#include <stdio.h>
#include <malloc.h>
#include <string.h>
int main(int argc, char **argv) {
char *msg = _alloca(256); // malloc(256);
char *p;
int i, l = 0;
memset(msg, 0, 256);
if(argc == 1) {
strncat(msg, "y", 1);
} else {
for(i = 1; i < argc; i++) {
l += strlen(argv[i]) + 1;
if(l >= 256) {
break;
}
strncat(msg, argv[i], strlen(argv[i]));
strncat(msg, " ", 1);
}
l = strlen(msg) -1;
p = msg + l;
if(*p == ' ') {
*p = '\0';
}
}
while(1) {
printf("%s\n", msg);
}
}
Ez volt az első implementáció. Hátránya, hogy korlátos, nem tud 256 byte-nál nagyobb sztringet kezelni.
Azután gondolkodtam, és megszületett a yes2:
#include <stdio.h>
int main(int argc, char **argv) {
int i;
if(argc == 1) {
while(1) {
printf("y\n");
}
} else {
while(1) {
for(i = 1; i < argc; i++) {
if(i > 1) {
printf(" ");
}
printf("%s", argv[i]);
}
printf("\n");
}
}
}
Kicsi (majdnem negyede az első verziónak a lefordított bináris), gyors. Ha még gyorsabbá akarnám tenni, akkor be lehetne tenni egy else ágat az argc == 2 esetre (ekkor ugyanis csak egy paramétert kell végtelen ciklusba kiíratni, kiesne a for ciklus).
- hrgy84 blogja
- A hozzászóláshoz be kell jelentkezni
Hozzászólások
a malloc/_alloca + memset parost miert nem calloc helyettesiti? Gyorsabb igy?
- A hozzászóláshoz be kell jelentkezni
Az _alloca azert lett, mert a yes by definition csak ctrl+c -re all le. Viszont, mivel igy eselyem sincs a free() hivasara, muszaj explicite a stacken helyet foglalni. A calloc ugy tudom, nem a stacken foglal memoriat. A memset-et meg mar megszoktam masutt.
Ja, es ugye linuxon nem _alloca hanem alloca, csak mar a #ifdef/#define parossal hajnal egykor nem volt kedvem szorakozni.
--
()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.
- A hozzászóláshoz be kell jelentkezni
"csak ctrl+c -re all le. Viszont, mivel igy eselyem sincs a free() hivasara"
jujj, most ugy teszek, mintha ezt nem olvastam volna ;)
--
NetBSD - Simplicity is prerequisite for reliability
- A hozzászóláshoz be kell jelentkezni
Persze, lehet atexittel, meg signal handlerekkel szorakozni, de most komolyan: egy ekkora programnal megeri?
--
()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.
- A hozzászóláshoz be kell jelentkezni
Most megnéztem Macen a BSD félét, az a tiéddel ellentétben csak az első argumentumot írja ki, amennyiben egynél több is van. Érdekes, eszerint a for ciklussal ott nem bajlódtak.
- A hozzászóláshoz be kell jelentkezni
Igen, vegulis ez az, ami megkulonbozteti a ket implementaciot egymastol. A for ciklustol ugyanis a masodik lassabb lesz, hiszen mindig be kell jarnia az argv tombot, az elso viszont memoriat igenyel a stacken - ami valtozo, hogy mennyi van.
--
()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.
- A hozzászóláshoz be kell jelentkezni
http://nxr.netbsd.org/xref/src/usr.bin/yes/yes.c
ez miert nem jo?
--
NetBSD - Simplicity is prerequisite for reliability
- A hozzászóláshoz be kell jelentkezni
1) nem neztem a NetBSD-set, mert tobbszor szaladtam mar ra, hogy nem lehetett 1:1 hasznalni az ottani forrasokat, annyira meg nem ismerem a NetBSD forrasfat, hogy meg mertem volna lepni a portolast.
2) ld. fentebb. Ez foleg akkor erdekes, ha folyamatosan olyanokat kell valaszoljon, hogy "Igen, tudom mit csinalok". Ezt a ti verziotok csak idezojelekkel tudja, az en masodik verziom viszont folyamatosan az argv tombot cseszteti. Persze, cserebe a ciklus overheadjevel lassabb a kiiras.
--
()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.
- A hozzászóláshoz be kell jelentkezni
meg a sok strlen() hivas is lassít.
A ternaris operatorral meg lehetne egyszerusiteni a masodik kododat is.
elso eseteben nem ertem az alloca hasznalatat. minek?
es nem vizsgalod a visszateresi erteket sem.
- A hozzászóláshoz be kell jelentkezni
Van egy kis kulonbseg. Az elso esetben csak az inicializalas lassu, maga a kiiras mar a printf konstans idejevel megy. A masodik esetben azonban a tombbejaro for ciklus minden kulso ciklus eseteben terhel.
Az alloca-t azert hasznaltam, mert ez volt a legegyszerubb modja annak, hogy ne kelljen belemerulnom abba, hogy Windows alatt a Ctrl+C hogyan allitja le valojaban a programokat (ejjel egykor nem volt kedvem pocsolni vele), igy a stacken foglalok helyet, aminel kevesbe erdekes, ha nem szabaditom fel (mert ugye a megszakitas kezelesenek ignoralasaval ez tortenik).
A visszateresi erteket ket okbol nem vizsgalom
- Ha nincs 256 byte a stacken, akkor valami baromi nagy gaz lehet a rendszerben, a legkissebb dolog egy null-ponter dereference
- Nem bolondbiztos programot akartam irni, hanem elso korben egy mukodot. Ha eljutunk eddig, utana mar lehet finomkodni vele, nekem akkor ott volt szuksegem egy yes-re.
--
()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.
- A hozzászóláshoz be kell jelentkezni
Tudom, ez rossz megközelítés, de az miért baj, ha a heap-en foglalsz memóriát? A gyakorlatban az operációs rendszer úgyis felszabadítja, amikor megszakad a program futása, nem?
- A hozzászóláshoz be kell jelentkezni
Ha nem, akkor meg szar van, 256 byte memoria oda.
--
()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.
- A hozzászóláshoz be kell jelentkezni
És mikor nem?
- A hozzászóláshoz be kell jelentkezni
Mit tudom en, nekem eleg a lehetoseg is, hogy aggodjak.
--
()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.
- A hozzászóláshoz be kell jelentkezni
http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/cmd/yes/y…
--
NetBSD - Simplicity is prerequisite for reliability
- A hozzászóláshoz be kell jelentkezni
:) A
for (;;)
rém elegáns a
while(1)
-el szemben.
Amúgy érdekes összevetni az implementációkat, mert ez egy olyan kis program, ami első nekifutásra belátható összetettségű, és mégis többféle az a bizonyos nekifutás...
- A hozzászóláshoz be kell jelentkezni
Én a
#define ever ;;
for(ever){
}
verziót szeretem...
--
Soli Deo Gloria
- A hozzászóláshoz be kell jelentkezni
Az fputs tenyleg jo otlet, erre igy nem is gondoltam. A putchar-t viszont valahogy nem szeretem... Ez ilyen megmagyarazhatatlan ellenszenv, nincs konkret oka.
Megnezegettem. Erdekes a true es a false implementacioja. Szerintem a return gyorsabb mint az exit() es kisebb kodot ad.
--
()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.
- A hozzászóláshoz be kell jelentkezni
Az argc mikor lesz kisebb, mint 1? :D
- A hozzászóláshoz be kell jelentkezni