zdravim vas teraz len zacinam v C programovat. Mam knizku ucim sa s nej a tam mam jeden program na pocitanie znakov ale nieje tam napisane ako ma vyzerat vystup. U mna po zadani znakov a stlaceni enter vyhodi len prazdny riadok a nepocita znaky. Chcem sa spytat ci tam nieje niekde chyba odpisal som to presne podla knizky.
#include <stdio.h>
main()
{
double pz;
for(pz = 0; getchar() != EOF; ++pz)
;
printf("%.0f\n", pz);
}.
Neviem co presne ma robit program alebo co chces aby robil, ale napriklad tento:
#include <stdio.h>
int main()
{
double pz;
for (pz=0; getchar() != EOF; ++pz)
{
printf("%.0f\n", pz);
}
return 0;
}
ktory je skoro ten isty ako tvoj, vypisuje po zadani znakov a enteru toto:
abc
1
2
3
defgh
4
5
6
7
8
9
#include <stdio.h>
int
main()
{
int c;
int pocet = 0;
while ((c = getchar()) != '\n') pocet++;
printf("Pocet zadanych znakov je %d\n", pocet);
return 0;
}
Ano, vravme cloveku, ktory sa uci elementarne veci, ze si za koniec vstupu moze zvolit hocico, najlepsie, nech si kazdy zvoli iny operacny system a ine standardy alebo iny jazyk, inu abecedu a uz sa vobec nedohovorime...
Toto naozaj nie je spravne miesto miesto na obohacovanie si nejakeho ega...
EOF nie je znakom ASCII. To byva aj castou chybou zacinajucich programatorov. EOF je v C definovane ako konstanta (ako je nizsie napisane) a je zauzivana hodnota -1 (vid zdrojove kody glibc).
Predstav si, ze mas premennu c typu char. Makra/funkcie getchar(), fgetc(), getc(),... vracaju navratovu hodnotu int (a je to z dovodu prave EOF). Ked sa nad tym zamyslis, tak explicitna typova konverzia sposobi, ze c bude nadobudat hodnoty 255 pri EOF (a 255 je platnym znakom - aj ked nie tabulky ASCII ale hociktorej rozsirujucej narodnej).
Je dobre, ze zaciatocnik zacina s C (je to najlepsia volba podla mna ako sa zacat ucit programovat). A tato vec je elementarna i ked na nu zacinajuci programatori casto zabudaju.
Ja som o signaloch nic nevravel, zaoberame sa vyssie uvedenym zdrojovym kodom a obohacovat ego si tu rozhodne nechodim (to kludne prenecham inym).
Spomenuta skratka nic neemuluje, len na stdin vlozi riadiaci znak (004), o to sa stara emulator terminalu. Shell do toho uz vobec nezasahuje, ten bezi na pozadi pricom vstup sa smeruje na proces na popredi - nas program. O interpretaciu riadiacich znakov v stdin sa stara kernel, oi. zabezpecuje aj echo znakov na terminal, moznost editovat riadok atd.. Beziaci program ma moznost si vybrat z viacerych moznosti "predspracovania" stdin vratane moznosti ho uplne vypnut v pripade zmu nevyhovuju.
Ma tam startovaci prikaz pz=0. Podmienku ukoncenia (znak != EOF) a inkrementacnu podmienku.
To, ze to neni for stylu od i:=1 to 10, neznemena, ze to je zly for.
Prave stylom ako si to napisal ty je to 100krat neprehladnejsie (zvlast pre zaciatocnika).
Takze laskavo netrep a chod si honit ego inde s tvojim standardnym ko(ko)d(t)om.
Dalej programujem iba zopar rokov a uprimne neviem, aky ma zmysel pouzivat na pocet typ premennej double. Ani som to este nikde nevidel. Klasicky sa dava int... A hold, bez ujmy na vseobecnosti, pricitanie celeho cisla k double nevrati nam vzdy hodnotu, aku by sme ocakavali...
V C velmi neprogramujem, radsej mam C++, Python, Javu, Haskel atd... Taky for cyklus som este v zivote nevidel. Ano, Ceckari maju z mne nepochitelnych dovodov vo zvyku pisat for(;;)... ale mne sa vazne vidi jasnejsie while(true)...
Dalej, knihu, ktoru mas sa velmi neodporuca na zaciatok. Predsa, je pisana stylom, akym sa programovalo z pred par rokov. Je milovana biblia ludi, ktori programuju stale ako v tej dobe, ale predsa, uz zijeme trochu v inej dobe.
Ten kod, ktory si napisal, je velmi cudny. Pre double, tym padom aj printf, main nema definovanu navratovu hodnotu ani nic nevracia... Ja tomu vravim spraseny kod.
pre zaujemcov odporucam keyword programing practices. Kniha od Herouta je podla mna ovela vhodnejsia pre zaciatocnika. Sice som uz jedneho guru pocul, ze ten clovek C velmi nerozumie. Neviem, mozno je to pravda, ale niesom guru v C a kazdy iny tu ucebnicu chvali.
mne skoro pripomina vec typu for (set<int>::iterator it = x.begin(); it != x.end(); ++it), co tiez nie je for na pocet opakovani. alebo iny priklad for (int i = 0; buf[i]; i++) na prejdenie celeho stringu (po posledny nulovy znak).
btw vacsi problem ako v tom, ze tam nema navratovu hodnotu pre main vidim v tom, ze vypisuje double cez %f, ked spravne je %lf (nie som si teraz isty, ci to potom vypise uplnu hovadinu vzdy, alebo len obcas).
set<int>::iterator it = x.begin();
while (it != x.end()) {
strasne;
dlhy;
blok;
s;
kodom;
az;
do;
aleluja;
++it;
}
ide o tom co je viac citatelnejsie, hlavne ak na projekte robi viac ludi. navyse ak nie medzi while a for ziadny rozdiel v performance, pretoze kazdy poriadny kompilator si to zoptimalizuje podla seba a ako uzna za vhode. takze "while" vs. "for" povazujem za flame, ktory je onicom.
Este sme si nepovedali o aky standard ide. C99 definuje implicitnu navratovu hodnotu funkcie main() a to (prekvapivo???) int. C89 nic take nedefinuje (pokial viem)
Chybou vsakje neuvedenie navratovej hodnoty, ktoru pouziva OS. V takomto pripade je tato hodnota nedefinovana.
To kedy sa problem s %f a %lf prejavi je celkom zaujimave. Staci sa pozriet ako su reprezentovane cisla s plavajucou desatinnou ciarkou v pamati a dlzku v bitoch float a double (tu vsak pozor)
Proste ked potrebujem raz prejst string a na zakladne toho vyplnit zopar inych hodnot, tak tento for je uplne super.
Ale ked mas nejake super riesenie, tak sem s tym.
Samozrejme ten for je spravne, ked ho pouzijes ako hovoris. V C je "true" akakolvek nenulova hodnota.