Forum » Programiranje » C programiranje
C programiranje
Janac ::
#include <stdio.h> int main (void) { int stevec=1; while(stevec<=1000); { printf("%d", stevec); stevec=stevec+1; } return (0); }
Nevem zakaj ne dela though...
Janac ::
tako tudi ne:
#include <stdio.h> int main (void) { int stevec; stevec=1; while(stevec<=1000); { printf("%d", stevec); stevec=stevec+1; } return (0); }
Janac ::
#include <stdio.h> int main (void) { int stevec; stevec=1; while(stevec<=1000) { printf("%i", stevec); stevec=stevec+1; } return (0); }
Repaired :)
ampak pr do-while pa je pri while pogoju podpičje?
Zgodovina sprememb…
- spremenil: Janac ()
Janac ::
Janac ::
#include <stdio.h> int main (void) { double dVnos, dIzracun; int iOdlocitev, iNadaljevanje=1; while(iNadaljevanje==1) { printf("***Pretvornik iz metrov v milje***\n\n"); printf("Za preracun iz metrov v milje vnesite stevilo 1, za preracun iz milj v metre pa stevilo 2.______"); scanf("%i", &iOdlocitev); if(iOdlocitev==1) { printf("Vnesite dolzino v metrih. \n\n"); scanf("%lf", &dVnos); dIzracun = dVnos/1600; } else if (iOdlocitev==2) { printf("Vnesite dolzino v miljah:\n\n"); scanf("%lf", &dVnos); dIzracun = dVnos*1600; } else { printf("Prosim, da vnesete 1 ali 2.\n\n"); } printf("%lf\n\n\n\n", dIzracun); printf("Ali zelite ponoviti racunanje? Vnesite 1 za nadaljevanje ter katerikoli drug znak za zaustavitev programa.______"); scanf("%i", &iNadaljevanje); if (iNadaljevanje==1) { printf("Program se bo ponovno izvedel. \n\n"); } else { printf("Upam, da ste uzivali v uporabi mojega programa.\n\n"); } } return (0); }
Če vnesem neko črko, se pojavi neskončna zanka. Kako naj to rešim?
Zgodovina sprememb…
- spremenil: Janac ()
ragezor ::
ob hitrem pregledu mas napako pri dIzracun, ki ga printas brez vrednosti. kolikor se spomnim spremenljivke deklarirane znotraj funkcij nimajo 0 po defaultu ampak imajo neko garbage vrednost
mogoce je kaj s tem. tako da jo probaj inicializirat na 0.
mogoce je kaj s tem. tako da jo probaj inicializirat na 0.
johnnyyy ::
ob hitrem pregledu mas napako pri dIzracun, ki ga printas brez vrednosti. kolikor se spomnim spremenljivke deklarirane znotraj funkcij nimajo 0 po defaultu ampak imajo neko garbage vrednost
mogoce je kaj s tem. tako da jo probaj inicializirat na 0.
Lokalne spremenljivke gredo na stack. Zato dIzracun pri vnosu, ki ni 1 ali 2 vrne vrednost, ki je bila takrat v stacku. Stack je znotraj posameznega procesa omejen (odvisno od OSja), v primeru, da ga presežeš ti program vrne "segmentation fault".
Randomness je izjavil:
Tole ne bo vredu.
scanf("%i", &iNadaljevanje);
Imaš prav, pri vnosu vrednosti, ki ni število funkcija vrača 0. Zato je potrebno preveriti napake (errno).
napsy ::
Samo en majhen popravek .. stack od funkcije ni vezan na operacijski sistem ampak na implementacijo programskega jezika
"If you die, you die. But when you live you live. There is no time to waste."
johnnyyy ::
Samo en majhen popravek .. stack od funkcije ni vezan na operacijski sistem ampak na implementacijo programskega jezika
Sam sem imel nekajkrat s tem probleme, pri aplikacijah, ki so tekle na različnih GNU/Linux distribucijah. Pač na nekaterih se je program ustavil in javil seg. fault. No kasneje sem ugotovil, da imajo različne distribucije različno velik stack, ki ga lahko povečaš/zmanjšaš z ulimit ukazom.
Več se pa s tem nisem ukvarjal .
Twix ::
Zamenjaj printf in scanf z cout in cin
#include <iostream> using namespace std; int main() { cout << "Hello World" << endl; //izpis int s; cin >> s;//vnos cout << s;//izpis return 0; }
#include <iostream> #include <string> using namespace std; int main () { string name; cout << "Please, enter your full name: "; getline (cin,name); cout << "Hello, " << name << "!\n"; return 0; }
The world is a dangerous place, not because of those who do evil,
but because of those who look on and do nothing. Apple has a patent on patent-
ing things they didn't invent. arka putana! :D hašek :D HVALA EDWARD SNOWDEN!
but because of those who look on and do nothing. Apple has a patent on patent-
ing things they didn't invent. arka putana! :D hašek :D HVALA EDWARD SNOWDEN!
Zgodovina sprememb…
- spremenil: Twix ()
napsy ::
Samo en majhen popravek .. stack od funkcije ni vezan na operacijski sistem ampak na implementacijo programskega jezika
Sam sem imel nekajkrat s tem probleme, pri aplikacijah, ki so tekle na različnih GNU/Linux distribucijah. Pač na nekaterih se je program ustavil in javil seg. fault. No kasneje sem ugotovil, da imajo različne distribucije različno velik stack, ki ga lahko povečaš/zmanjšaš z ulimit ukazom.
Več se pa s tem nisem ukvarjal .
Tist stack size predvsem velja za programe, ki uporabljajo glibc. Kaksni drugi prevajalniki oz. programski jeziki pa lahko dolocajo poljubno velikost stacka za funkcije.
"If you die, you die. But when you live you live. There is no time to waste."
smoke ::
Twix ::
whoops pošast! me je zmedla!
The world is a dangerous place, not because of those who do evil,
but because of those who look on and do nothing. Apple has a patent on patent-
ing things they didn't invent. arka putana! :D hašek :D HVALA EDWARD SNOWDEN!
but because of those who look on and do nothing. Apple has a patent on patent-
ing things they didn't invent. arka putana! :D hašek :D HVALA EDWARD SNOWDEN!
Zgodovina sprememb…
- spremenil: Twix ()
Janac ::
Lahko kdo prosim pregleda tole kodo:
Debugger mi javi napako v drugem caseu....
#include <stdio.h> int main (void) { char cOdgovor; printf("*******************************\n"); printf("-RADI IMAMO PROGRAMSKI JEZIK C-\n"); printf("*******************************\n\n\n"); printf("Ali imate radi programski jezik C? *[D-da /N-ne/ M-mogoce]*\n\n"); scanf("%c", &cOdgovor); switch(cOdgovor) { case 'd'||'D' : { printf("***--Super--***!"); break; } case 'm' || 'M' : { printf("No, malo se premisli."); break; } case 'n' || 'N' : { printf("Malce sem razocaran.");b n break; } default : { printf("To ni odgovor na moje vprašanje!"); } } return(0); }
Debugger mi javi napako v drugem caseu....
amacar ::
Ne moreš imeti
spremeni v
case 'd'||'D' : { printf("***--Super--***!"); break; }
spremeni v
case 'd' : case 'D' : { printf("***--Super--***!"); break; }
Zgodovina sprememb…
- spremenil: amacar ()
ERGY ::
Ne moreš imeti
case 'd'||'D' :
{
printf("***--Super--***!");
break;
}
spremeni v
case 'd' :
case 'D' :
{
printf("***--Super--***!");
break;
}
Malo lažje...
#include <stdio.h> #include <ctype.h> ... switch(tolower(odg)) { ... case 'd': ... break; case 'm': ... break; case 'n': ... break; default: ... } return 0;
lebdim ::
v programskem jeziku pascal je lepše delati s stavkom case ... se ti ne zdi bolj pregledno drugače s case stavkom bolj kot z if?
Janac ::
lebdim ::
IF in CASE stavka uporabimo takrat, kadar želimo preveriti nek pogoj. če imaš za preveriti manjše število pogojev (npr. 4), boš uporabil stavek IF in potem za vsako možnost ELSE IF. če pa imaš za preveriti večje število pogojev, pa raje uporabi SWITCH-CASE, če se pogovarjamo o programskem jeziku C. vsaj tako jaz razumem razliko med stavkoma if in case, lahko pa se tudi motim.
minusnič ::
So optimizacije, ki delujejo le na switch stavkih, ne pa na enakovrednih if-else if-else strukturah.
Najprej pogledamo, če je switch takšne oblike:
To je poseben primer, ki bi ga bilo lepše izraziti z if stavkom:
1. Zamenjava večih pogojev, ki vodijo v en case block, s hitrejšimi operacijami:
( GCC vrstice ~128 - ~699)
Nakar pogledamo, če veliko pogojev vodi v en blok:
Ta stavek bi bilo lepše izraziti z:
Vendar je to le poseben primer, poglejmo kako je, ko imamo nesosledne pogoje:
To je enako:
Kar je enako:
Med 7 in 2 je 5 števil. Pet je manj kot širina registra. Zatorej naj bo:
Ali bitno zapisano: 101011. Končno dobimo:
2. Prevajanje inicializacije preko switch stavka v inicializacijo iz niza
( GCC vrstice ~701 - ~1093)
Zgodi se, da v switch stavku dajemo y-u določeno vrednost glede na vrednost x-a:
Če za katero vrednost x ne bi bilo break ukaza, bi bil ta blok izpuščen že med dead code removal (ker vsi bloki samo nastavijo y, in y je tako ali tako (ponovno) nastavljen v default, torej tisti blok nima posledic):
Nastavljalni switch stavek bi se dalo spremeniti v predprejšnjem primeru na nastavljenje y-a preko elementa x - 1 niza Y:
Za tako optimizacijo je default (ki se pretvori v else) nujen.
Ampak prejšen primer je spet le poseben primer s sosledjem case-ov.
Čisto vseeno je, če dva x-a vodita v isti y.
Seveda bi ob velikem razponu x-ov dobili velik niz s povečinoma default vrednostmi, zato je ta optimizacija narejena le, ko je razpon manjši ali enak x-ov 8 * število case-ov.
Če se v switch stavku inicializira več spremenljivk, se pač naredi več nizov.
3. Zamenjava padajočega preverjanja case-ov s hitrejšimi metodami
(Za to pa ne vem, kje je to implementirano v GCC, pa tudi ne zagotavljam, da se točno tako optimizira. Samo s tem testnim programom pokažem, da so sledeči primeri pravilni.)
Če je število case-ov manjše od 5 ali je razpon case-ov > 10 * število case-ov + 2 se uporabi binarno iskanje:
Najprej se case-e sortira po primerjanem številu, od najmanjšega do največjega. Ker so povsod break ukazi, to ne spremeni pomena.
Nato se to prevede na binarno iskanje:
Drugače se pa uporablja jump tables:
Verjetno se za (nekatere primere) tudi uporablja padajoče preverjanje
Najprej pogledamo, če je switch takšne oblike:
switch (a) { case b: // ... }
To je poseben primer, ki bi ga bilo lepše izraziti z if stavkom:
if (a == b) // ...
1. Zamenjava večih pogojev, ki vodijo v en case block, s hitrejšimi operacijami:
( GCC vrstice ~128 - ~699)
Nakar pogledamo, če veliko pogojev vodi v en blok:
switch (a) { case 1: case 2: case 3: // ... }
Ta stavek bi bilo lepše izraziti z:
if (a > 0 && a < 2) // ...
Vendar je to le poseben primer, poglejmo kako je, ko imamo nesosledne pogoje:
switch (a) { case 2: case 3: case 5: case 7: // ... }
To je enako:
if (x == 2 || x == 3 || x == 5 || x == 7) // ...
Kar je enako:
x_1 = x - 2; if (x == 0 || x == 1 || x == 3 || x == 5) // ...
Med 7 in 2 je 5 števil. Pet je manj kot širina registra. Zatorej naj bo:
u = (1 << 0) & (1 << 1) & (1 << 3) & (1 << 5);
Ali bitno zapisano: 101011. Končno dobimo:
x_1 = x - 2; u = b101011; if (x_1 >= 0 && x_1 < 4 && (1 << x_1) & u) // ...
2. Prevajanje inicializacije preko switch stavka v inicializacijo iz niza
( GCC vrstice ~701 - ~1093)
Zgodi se, da v switch stavku dajemo y-u določeno vrednost glede na vrednost x-a:
switch (x) { case 1: y = 2; break; case 2: y = 3; break; case 3: y = 5; break; default: y = -1; }
Če za katero vrednost x ne bi bilo break ukaza, bi bil ta blok izpuščen že med dead code removal (ker vsi bloki samo nastavijo y, in y je tako ali tako (ponovno) nastavljen v default, torej tisti blok nima posledic):
switch (x) { case 1: y = 2; break; case 2: y = 3; break; case 3: y = 5; break; default: y = -1; }
switch (x) { case 1: y = 2; break; case 3: y = 5; break; default: y = -1; }
Nastavljalni switch stavek bi se dalo spremeniti v predprejšnjem primeru na nastavljenje y-a preko elementa x - 1 niza Y:
const Y[] = {2, 3, 5}; . . . x_1 = x - 1; if (x_1 >= 0 && x_1 < 3) y = Y[x_1]; else y = -1;
Za tako optimizacijo je default (ki se pretvori v else) nujen.
Ampak prejšen primer je spet le poseben primer s sosledjem case-ov.
switch (x) { case 1: case 10: case 11: y = 1; break; case 2: case 12: y = 2; break; default: y = -1; }
Čisto vseeno je, če dva x-a vodita v isti y.
const Y[12] = {1, 2, -1, -1, -1, -1, -1, -1, -9, 1, 2}; x_1 = x - 1; if (x_1 >= 0 && x_1 < 12) y = Y[x_1]; else y = -1;
Seveda bi ob velikem razponu x-ov dobili velik niz s povečinoma default vrednostmi, zato je ta optimizacija narejena le, ko je razpon manjši ali enak x-ov 8 * število case-ov.
Če se v switch stavku inicializira več spremenljivk, se pač naredi več nizov.
3. Zamenjava padajočega preverjanja case-ov s hitrejšimi metodami
(Za to pa ne vem, kje je to implementirano v GCC, pa tudi ne zagotavljam, da se točno tako optimizira. Samo s tem testnim programom pokažem, da so sledeči primeri pravilni.)
Če je število case-ov manjše od 5 ali je razpon case-ov > 10 * število case-ov + 2 se uporabi binarno iskanje:
Najprej se case-e sortira po primerjanem številu, od najmanjšega do največjega. Ker so povsod break ukazi, to ne spremeni pomena.
Nato se to prevede na binarno iskanje:
switch (a) { case 1: f_1 (); break; case 2: f_2 (); break; case 3: f_3 (); case 4: f_4 (); break; default: g (); break; }
if (a == 2) f_2 (); else if (a > 2) goto vecje_od_2; if (a == 1) f_1 (); else goto __default; vecje_od_2: if (a == 3) f_3 (); else if (a == 4) f_4 (); __default: g ();
Drugače se pa uporablja jump tables:
switch (a) { case 1: f_1 (); break; case 2: f_2 (); break; case 3: f_3 (); break; case 4: f_4 (); break; case 5: f_5 (); break; }
const void *__tabela[] = {&&__case_1, &&__case_2, &&__case_3, &&__case_4, &&__case_5}; int a_1 = a - 1; if (a_1 >= 0 && a < 5) goto * __tabela [a_1]; else goto __konec_tabele; __case_1: f_1 (); goto __konec_tabele; __case_2: f_2 (); goto __konec_tabele; __case_3: f_3 (); goto __konec_tabele; __case_4: f_4 (); goto __konec_tabele; __case_5: f_5 (); __konec_tabele:
Verjetno se za (nekatere primere) tudi uporablja padajoče preverjanje
switch (x) { case 1: f_1 (); case 2: f_2 (); }
if (x == 1) f_1 (); else if (x == 2) f_2 ();
Janac ::
Ti pa si mojster za C :)
Lahko nekdo prosim pogleda tole:
Kar preskoči pogoja...
Lahko nekdo prosim pogleda tole:
#include <stdio.h> int main (void) { double dPoraba, dGorivo, dRazdalja, dMozno; printf("***My trip calculator***\n\n"); printf("--Program izracuna koliko km je mozno prevoziti s vsebino rezervoarja, opozori na premalo goriva.--\n\n"); printf("Vnesite povprecno porabo avtomobila v [l/100km]: "); scanf("%lf", &dPoraba); printf(" Koliko goriva imate v rezervoarju? v [l]"); scanf("%lf", &dGorivo); printf("Vnesite oddaljenost od cilja v [km]"); scanf("%lf", &dRazdalja); dMozno= dGorivo*100/dPoraba; if (dMozno<dRazdalja) { printf("Imate premalo goriva, zapeljite se na bencinsko črpalko."); } else if (dRazdalja>dMozno) { printf("Oddaljenost od cilja je: %lf", dRazdalja); printf("Z gorivom, ki je v rezervoarju je možno prevoziti: %lf", dMozno); } return (0); }
Kar preskoči pogoja...
amacar ::
Bravo, si sploh pogledal kaj si napisal? Dva enaka pogoja, zato ko preskoči prvega hkrati tudi drugega.
Sicer pa bi lahko komot zapisal tako
dMozno<dRazdalja == dRazdalja>dMozno
Sicer pa bi lahko komot zapisal tako
if (dMozno<dRazdalja) { printf("Imate premalo goriva, zapeljite se na bencinsko črpalko."); } else { printf("Oddaljenost od cilja je: %lf", dRazdalja); printf("Z gorivom, ki je v rezervoarju je možno prevoziti: %lf", dMozno); }
Zgodovina sprememb…
- spremenil: amacar ()
garamond ::
Na prvi pogled se mi zdi pravilen, sicer pa je potrebno vedno testirati program.
Se pač pelješ par stotin kilometrov, nekaj testnih relacij, itd. Treba je pokriti vse scenarije -- nujno je stestirati tudi pogoje, ko je premalo goriva.
Se pač pelješ par stotin kilometrov, nekaj testnih relacij, itd. Treba je pokriti vse scenarije -- nujno je stestirati tudi pogoje, ko je premalo goriva.
garamond ::
Opomba: jezik uporabniškega vmesnika je premalo natančen: “Imate premalo goriva, zapeljite se na bencinsko črpalko.” [konec navedka]
Nevešč uporabnik bi se zapeljal na bencinsko črpalko, ne naredil ničesar, odpeljal -- potem bi mu pa zmanjkalo goriva!
Nevešč uporabnik bi se zapeljal na bencinsko črpalko, ne naredil ničesar, odpeljal -- potem bi mu pa zmanjkalo goriva!
Janac ::
Eno vprašanje, kako bi v polju lahko določil da se soda števila shranijo na sode pozicije elementov, lihe pa na lihe pozicije elementov?
Janac ::
Jaz sem imel v mislih nekaj takega:
iStevec1 inicializiram na 1, iStevec2 pa na 2.
for(iStevec=0; iStevec<VELIKOST; iStevec++) { printf("Vnesite %i. stevilo:", iStevec+1); fflush(stdin); scanf("%lf", dVnos); dVnos=dVmesna; if(dVmesna%2==0) { dPolje_main[iStevec2]=dVnos; iStevec2=iStevec2+2; } else { dPolje_main[iStevec1]=dVnos; iStevec1=iStevec1+1; } }
iStevec1 inicializiram na 1, iStevec2 pa na 2.
Zgodovina sprememb…
- spremenil: Janac ()
ragezor ::
Mene pa zanima zakaj mi ne vrze errorja ampak samo warning
v cem je potem sploh fora const modifierja
void change_const(int* number) { *number = 100; } int main() { const int num = 34; change_const(&num); return 0; }
v cem je potem sploh fora const modifierja
Janac ::
Cela koda, lahko kdo prosim pogleda:
#include <stdio.h> #define VELIKOST 21 void Soda(double dPolje_soda[VELIKOST]); void Liha(double dPolje_liha[VELIKOST]); int main(void) { int iStevec1=1; int iStevec2=2; int iStevec=0; int iVnos=0; double dVmesna=0; double dPolje_main[VELIKOST]; printf("Program za izpis sodih in lihih števil.\n"); for(iStevec=0; iStevec<VELIKOST; iStevec++) { printf("Vnesite %i. stevilo:", iStevec+1); fflush(stdin); scanf("%i", &iVnos); if(iVnos % 2==0) { dPolje_main[iStevec2]=iVnos; iStevec2=iStevec2+2; } else { dPolje_main[iStevec1]=iVnos; iStevec1=iStevec1+1; } } Liha(dPolje_main); Soda(dPolje_main); return(0); } void Soda(double dPolje_soda[VELIKOST]) { int iStevec1=2; for(iStevec1=2; iStevec1<VELIKOST; iStevec1=iStevec1+2) { printf("%lf\n\n", dPolje_soda[iStevec1]); } } void Liha(double dPolje_liha[VELIKOST]) { int iStevec2=1; for(iStevec2=0; iStevec2<VELIKOST; iStevec2++) { printf("%lf\n", dPolje_liha[iStevec2]); } }
Excalibrus ::
Lahko samo na hitro razložiš, kaj je pravzaprav cilj programa? Sicer nisem popolnoma domač z sintakso v C-ju, tako da se lahko motim, ampak že sama zasnova programa mi na prvi pogled deluje daleč preveč nepotrebno zakomplicirano. Malo takih "lepotnih napak": v for zanki lahko komot deklariraš spremenljivko, ni ti je potrebno to zunaj zanke: primer -
for(int a=0; i<neka_vrednost; i+=2) {}
amacar ::
C89 and earlier versions only support declaration statements at the head of a block (IOW, the only thing that can appear between an opening { and a declaration is another declaration)
http://stackoverflow.com/questions/3588...
http://stackoverflow.com/questions/3588...
Vredno ogleda ...
Tema | Ogledi | Zadnje sporočilo | |
---|---|---|---|
Tema | Ogledi | Zadnje sporočilo | |
» | Java @OverrideOddelek: Programiranje | 777 (642) | kretze |
» | C in računanje kotovOddelek: Programiranje | 6495 (5548) | RatedR |
» | naloga ne funkcioniraOddelek: Programiranje | 1419 (1328) | FX6300B |
» | c napaka .c:4:1: error: expected identifier or '(' before '{' tokenOddelek: Programiranje | 1912 (1485) | MrStein |
» | [c] char zadevaOddelek: Programiranje | 2217 (2015) | TheCyborg |