Új hozzászólás Aktív témák
-
Karma
félisten
Nos, a ciklusmagot és a kiírást kijavítva nálam már jól működik.
iMac:Debug zsolt$ ./test
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97Azért nem lenne hátrány, ha azokat a while ciklusokat újragondolnád
[ Szerkesztve ]
“All nothings are not equal.”
-
Daneeka
senior tag
Köszi tényleg az volt a hiba, hogy kilógott a kettes. Pedig erre gondoltam, próbáltam is scrollozni felfele, ami miatt nem ment az az, hogy úgy néz ki nálam nem működik valamiért az egérgörgő parancssori progiknál. Aztán azt valószínűbbnek láttam, hogy nem bírok programozni mint azt, hogy nem bírok scrollozni, szóval beírtam ide.
(pár hete programozok még csak, a while nekem átláthatóbb, hogy látom függőlegesen a lépéseit, jobban hasonlít arra a folyamatra amit az agyamban elképzelek, később majd kiverik belőlünk esetleg )
[ Szerkesztve ]
-
Jester01
veterán
Pl. úgy, hogy nem intet használsz, hanem longot, ami mindig 32-bites.
Mindig? Na ne viccelj!kikiáltja C++ programozásnak, pedig ez csak egy C program, C++ fordítóval lefordítva,
Azért mert egy adott program ránézésre esetleg nem annyira objektum-orientált vagy ilyesmi, azért még meg lehet írni c++-ban. És persze semmi akadálya, hogy az implementáció során osztályokat használj pl. a "Program", "Terminal", "Executor" (ez egy absztrakt osztály lenne), "Simulator" (ez meg implementálja az Executor-t). Így ha teszem azt később ki akarod bővíteni azzal, hogy vezéreljen egy usb portra kötött 3D robotot akkor csak egy új osztály kell ami az Executor-t implementálja.cucka: Mivel a feladat specifikálta, hogy ezt a 3 byteot kell belegyömöszölni az int-be ezért feltételezhető, hogy az adott architektúrán legalább 24 bites az int. Ha meg több az tök mindegy. Egyszerű bit műveletekkel meg lehet oldani. Amúgy ha ettől a feladattól elvonatkoztatva valamikor adott bitszámú int-re van szükséged, akkor az stdint.h-ban laknak olyanok, hogy int32_t meg int_least32_t és társaik.
Jester
-
VaZso
senior tag
Köszönöm a választ.
Tehát ha jól értem, balról jobbra haladva értékeli ki a feltételek igazságtartalmát és ha valahol egyértelműsödik a helyzet, dönt a végrehajtásról...Ezesetben érdekes lehet még, hogy ha vagy kapcsolat van közöttük és az első feltétel teljesül, akkor pl. a második feltételben lévő x++ nem lépteti el a pointert...
...mondjuk ez alapján pedig már rég letesztelhettem volna hülyeségek kérdezése helyett...
-
Nunder
őstag
Windows Vista alól Virtual Boxon keresztül futtatok egy rendszeresen frissített Ubuntu 9.04-est. A file-okat egy direkt erre a fajta megjelenítésre specializált Makefile-al fordítom, azzal nem lehet a gond. Az a baj, hogy eddig gond nélkül futott még a warn-okkal együtt is, most elvileg hibátlan, és mégis dobálja a szegmens hibát.
“It's the job that's never started as takes longest to finish.” // blackbird3dworks.hu
-
cellpeti
veterán
igen!
Így néz ki a progi:
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
int getline(char s[],int lim){
int i,c;
for (i=0;i<lim && (c=getchar())!=EOF && c!='\n';++i)
s[i]=c;
s[i]='\0';
while (c!=EOF && c!='\n')
c=getchar();
return (i);
}
int lebege(char s[]){
int i=0, kezd;
while(isspace(s[i])) ++i;
if(s[i]=='+'||s[i]=='-') ++i;
kezd=i;
while(isdigit(s[i])) ++i;
if(s[i]=='.') ++i;
while(isdigit(s[i])) ++i;
if(i==kezd||kezd+1==i&&s[kezd]=='.') return 0;
if(toupper(s[i])=='E'){
++i;
if(s[i]=='+'||s[i]=='-')++i;
if(!isdigit(s[i])) return 0;
while(isdigit(s[i])) ++i;}
if(isspace(s[i])||!s[i]) return 1;
else return 0;
}
void main (void)
{
float r,T,K;
float pi=3.14;
char s[24];
int ok=1;
do
{
ok=1;
printf("Adja meg a kor sugarat!\n\n");
if(!getline (s,25))
{
printf("Üres sort adtal meg!\n\n");
ok=0;
}
else
{
if(!lebege(s))
{
printf("Nem lebegopontos a megadott szam!\n");
ok=0;
}
else
r=atof(s);
}
}while(ok==0);
K=2*r*pi;
T=r*r*pi;
printf("\nA kor kerulete: %.2f\n\nA kor terulete: %.2f\n\n",K,T);
getch();
}[ Szerkesztve ]
Tigris, tigris, csóvafény...
-
Sk8erPeter
nagyúr
Tényleg, ha már pointerek és tömbök hasonlóságáról van szó, kérdeznék: tanultuk, hogy hasonlóság van a kettő között, de van különbség memóriakezelésben. Milyen szempontból?
Ha pointerként hivatkozol (pl. int *p) az elvileg ugyanazt adja, mint a tömb első (nulladik) elemének címe. De akkor mi a jelentős különbség?Sk8erPeter
-
cellpeti
veterán
Na ezzel most nagyon jót kérdeztél.
[ Szerkesztve ]
Tigris, tigris, csóvafény...
-
shev7
veterán
ugy ertettem, hogy ha pointert mint tombot hasznalunk futasi idoben valtoztathato a "tombnek" a merete. Ha arra van szukseg fogod es nagyobbat foglalsz
''Gee, Brain, what do you want to do tonight?'' ''The same thing we do every night, Pinky: Try to take over the world!''
-
Sk8erPeter
nagyúr
"míg a pointer szabadon módosítható, a tömbváltozó nem, konstans értéke van."
Most ezt nem nagyon értem: a tömbváltozó is módosítható. Mármint a tömbben tárolt érték. Nyilván a pointer átállítható, hogy más elem címére mutasson.
Na de akkor mi a releváns különbség a memóriakezelésben?(#1383) shev7 : ezt sem értem, mert dinamikusan is, futásidőben is lehet memóriát foglalni tömbnek, attól függően, hogy mondjuk mekkora egy másik tömb, aminek az elemeit át szeretnénk másolni egy új tömbbe, attól függően módosítjuk a foglalt memóriaméretet.
_______________________________________________________
(#1380) cellpeti: nem értem, minek állítgattad át? Letöltöd, telepíted, működik. Tök felesleges állítgatni valamit, ha nem tudod, mi az...
[ Szerkesztve ]
Sk8erPeter
-
Sk8erPeter
nagyúr
A kolléga itt azt mondja, nem lehet futásidőben növelni a tömb méretét. De most akkor itt nem éppen az történik? Itt tulajdonképpen pointerrel és/vagy tömbbel játszik, de a kettő bizonyos szempontból hasonló, mégis más a kettő, és most már akkor kezdem azt sem érteni, amit azt hittem, eddig értettem Tehát itt a mutatott példában pl. egy új tömbnek már futásidőben foglal akkora memóriát, amekkora számára szükséges. A másikban meg még bővíti annyival, amennyi kell, mivel csak egyszer olvashatjuk be az állományt. Ugyanúgy kezeli, mint egy tömböt. De akkor most mi is az igazság?
Sk8erPeter
-
Sk8erPeter
nagyúr
Huhh. No, akkor valóban vannak homályos foltok.
Megpróbálom értelmezni akkor a lényegi kérdést, kérlek javíts, ha valamit rosszul gondolok:
A double *ujtomb; sorban tehát deklarálunk egy pointerváltozót ujtomb néven, aminek csak később foglaljuk le a szükséges memóriát, először még csak meghatározzuk, hogy "lesz ilyen". Amikor megtudtuk az eredeti tömb számunkra szükséges elemeit megszámolva, mekkora új tömbre van szükségünk, azután lefoglaltuk neki a számára szükséges memóriát. Ezután tömbként és egyben pointerként használtuk fel a későbbiekben, rakosgattunk bele elemeket, és itt ez most kicsit zavaros számomra, hogy akkor most melyik fogalmat is használjuk, ami helytálló. Mert tömbnek foglalunk helyet, de pointertömb...
A második feladatban már megint ez a fogalmi zavar a bajom. (pointer, tömb, pointertömb...)
Ráadásul - bocsi az értetlenkedésért, csak vannak ilyen homályos pontok - akkor a memóriafoglalással ezek szerint nem "méretezünk", hanem nem tudom, mit csinálunkÉs még egy pluszkérdés: a main()-ben free-vel felszabadítjuk a memóriát, de ekkor nem "szabadulunk meg" egyben az adatszerkezet már korábban eltárolt értékeitől is?
Bocs a sok kérdésért, és köszönöm az eddigi és további segítséget.
(#1411) shev7: pont most küldtem a hsz.-t. köszi, rögtön végiggondolom, hogy leülepedjen. És igen, jól látod, még nem jött át, kicsit zavar van most az agyamban. De már dereng valami!
[ Szerkesztve ]
Sk8erPeter
-
Sk8erPeter
nagyúr
Köszi a válaszokat, Karma és shev7, azt hiszem, már nagyjából értem.
"magát a pointert sikeresen definiáltuk, 4 byte-ot kapott a stacken (vagy globálisan), mint egy átlagos változó. De ezt most felejtsük el egy pillanatra, mert irreleváns." És hogy is van tovább?
"Dehogynem. Amire meghívod a free-t, az felszabadul, az értékei érvénytelenné és elérhetetlenné válnak."
Mondjuk jelen esetben a példaprogramnál ez nem volt világos, hogy minek foglaltunk akkor helyet az adatoknak, ha utána rögtön az eltárolás után meg is szabadultunk tőle. Igaz, erre lehetne azt mondani, hogy mivel nem volt része a feladatnak az, hogy tovább tárolgassuk, és még csináljunk vele valamit, csak a szavakra darabolás.(#1413) shev7: "Ott a kovetkezo egyenloseg igaz: p[5] = *(p+sizeof(int)*5)" Ettől egy kicsit megijedtem, mivel pont nem ezt tanultuk, hanem azt, hogy azzal egyenlő, hogy *(p+5). De látom később megbeszéltétek, hogy valóban az utóbbi a jó.
Itt viszont nem értettem az összefüggést: "ja es ezert indexeljuk 0-tol a tomboket C-ben" azzal, amit ezelőtt írtál.
Egyébként számomra az is újdonság volt, hogy lehet deklarálni úgy egy változót, hogy byte *p; . Ez mire jó ebben a formában? Még konkrét programban kevésszer láttam így deklarálva egy változót, de valamilyen szempontból nyilván hasznos lehet.Köszi nektek a türelmes válaszokat!
Sk8erPeter
-
Sk8erPeter
nagyúr
Értem, köszi!
(#1428) 3man: még C++-hoz nem konyítok, de csak érdeklődésképp kérdezem, hogy miért nem egyszerűbb a túlindexelés elkerülésére osztály létrehozása helyett mindig "kényszerűen" átadni a tömbméretet is mondjuk függvénynek, vagy végigszaladni a tömbelemeken a lezáró nulláig, hogy megtudjuk, hány eleme van, és utána ezzel dolgozzunk?
Sk8erPeter
-
Sk8erPeter
nagyúr
Abból indultam ki, hogy nekünk azt erőltették, hogy ha akár statikus tömbökkel is dolgozunk (persze, nem a pointertömbökre gondoltam ), és azokat adjuk át a függvényeknek, akkor lehetőleg adjuk át a méretét is, mert így könnyebb kezelni (pl. ha iterátorral rohangászol végig a tömbelemeken, akkor mittomén, for ciklusban a feltétel lehet az, hogy i<meret, stb. - persze úgy is lehetne, hogy tomb[i] != '\0' ), nem kell a függvényen belül is sizeof()-fal p×csölni, és így esetleg pl. main()-ben mondjuk elég egyszer sizeof-olni (talán ez gyorsaság szempontjából is érdekes lehet, fene tudja). Ez nem lehet elfogadható szempont? A 2-3. pont mondjuk teljesen igaz.
[ Szerkesztve ]
Sk8erPeter
-
3man
csendes tag
Termeszetesen debuggerekkel es tarsaikkal helyettesitheto a modszerem.
De amikor 10 netalan 100 kulso tesztelod van, akkor nem biztos, hogy ez kenyelmes modszer.
Mi a legegyszerubb megoldas?
Az AddVectoredExceptionHandler() -el elkapsz minden nem tervezett esemenyt, es logolsz minden fontos dolgot. A lefoglalt teruletek mutatolistaihoz rendelt nev alapjan barmilyen memoria hiba pontosan lokalizalhato akar ugy, hogy nem is debug modban fut a program. Egy callstack-hez hasonlo kovetes is beepitheto ebbe a logba.
Ugyan a debug mod azert van, hogy ezt elvegezze, de megeshet, hogy igy tul lassu a program. Ha a programot a vegleges formajaban kell tesztelni, akkor a debug mod mar kiesik, de a hiba megis egyszeruen detektalhato.[ Szerkesztve ]
-
Sk8erPeter
nagyúr
Nem, BME-n kifejezetten és erősen tiltják a goto utasítás használatát! Ezt a tanárok "halálfejes hibának" nevezik, ha ilyet teszel a ZH-dba, akkor rárajzolnak egy halálfejet (egyébként tényleg rárajzolják, ZH-megtekintésnél pár papíron láttam is ), és arra a feladatra - akármilyen szép is a többi része - eleve 0 pontot adnak. (olyan esetekben is kapsz ilyet, ha nem szabadítod fel a dinamikusan lefoglalt memóriát, amikor kellene, vagy inicializálatlan változóval dolgozol, stb.)
Elképzelhető, hogy régebben volt olyan tanár, akinek nem verték a fejébe, hogy goto-t nem használunk, de szerintem most már selejtezik az ilyeneket.
Pascalt nem is tudom, tanítanak-e még egyáltalán... Villamosmérnöki és Informatikai Karon biztos, hogy nem, ott C-vel kezdenek. De én úgy tudom, hogy még az építészek is alap C-t tanulnak. Pascalról mostanában egyáltalán nem hallottam, hogy valahol tanítanának még BME-n.A lényegre térve nem igazán értem, miért olyan nagyon hibás az elképzelés, hogy kívülről adjuk meg a függvénynek a méretet. Jahh, de az utolsó bekezdésben azt írod, hogy végül is van elfogadható érvelés erre is: akkor tehát mégis jó úgy?
Az "iterátor" szót lehet, hogy rosszul használtam, de arra az elemre gondoltam, amivel bejárod a tömböt.A goto utasításra visszatérve: tudom, hogy a használata egy undormány-hányadék hiba, és soha nem is tettem, mert direkt meg se néztem, hogy kell azt egyáltalán De érdekelne, konkrétan milyen szempontból oltári baromság a goto használata. Úgy emlékszem, hogy futásidejű összeomlásokat eredményezhet, meg hasonlókat, de a pontos érveket már elfelejtettem.
(#1442) 3man: értem, köszi. Tehát akkor érdemes mégis kézzel átadni (ha sima C-ben programozol) a tömbméretet, ugye?
(#1446) bama: most mi a kérdés? Egyébként ha ez egy prímtesztelő függvény, akkor szvsz elég furcsa, minek kell 4-gyel shiftelni a számot...
[ Szerkesztve ]
Sk8erPeter
-
Sk8erPeter
nagyúr
dabadab, Karma, kovsol: köszi a válaszokat!
Nálunk mondjuk a gyorsrendezés algoritmusánál sem használtak goto-t. Úgyhogy asszem maradok továbbra is annál, hogy NEM használok goto-t, amíg nem jön elő olyan helyzet, hogy mindenképp arra lesz szükségem - amit meg kétlek, hogy előállna.KISS filozófia, ez tetszik
A cikket pedig majd elolvasom, ha lesz időm, köszi.(#1451) grabber: miért használsz mindenhol exit(0)-t? Miért nem return 0; vagy return 1-et? Mi ez az exit-mánia?
Sk8erPeter
-
-
Karma
félisten
Áááháá! Megvan! Nem vagyok teljesen up-to-date, a C99 szabvány engedi a változó hosszúságú tömböt is stacken, ha a blokk elején ismert a hossz, tehát pl. egy függvény paramétere a tömb mérete.
float read_and_process(int sz)
{
float vals[sz]; // VLA, size determined at runtime
for (int i = 0; i < sz; i++)
vals[i] = read_value();
return process(vals, sz);
}#1460: Wikipédián találtam Elnézve a C99 újításait, gyanúsan C89-et "oktatott" anno Poppe prog1 órán.
[ Szerkesztve ]
“All nothings are not equal.”
-
dabadab
titán
"Egyébként nem úgy volt, hogy stacken tömböt csak fix méretben lehet létrehozni?"
Én nem tudok ilyenről és nekem ez teljesen jól működik:
#include <stdio.h>
void f(int size)
{
int x[size];
printf("%d\n",sizeof(x));
}
int main()
{
int c;
for ( c = 1 ; c < 10 ; c++ ) f(c);
return 0;
}./x
4
8
12
16
20
24
28
32
36szerk: látom, neked volt lelkierőd elolvasni a dokumentációt
[ Szerkesztve ]
DRM is theft
-
-
Jester01
veterán
C89 szabvány szerinti C nyelvben illetve C++ nyelvben csak fix méretű tömb van. C99-ben van dinamikus is. GCC meg szeret alapból nagyon laza lenni, házi feladat vagy hordozható kód esetén ajánlott a -ansi -pedantic -Wall. Ezen felül bizonyos warningok meg csak bekapcsolt optimalizáció mellett jelenkeznek.
MOD: haha a klónom gyorsabb volt Sőt tulajdonképpen mindenki. Na mindegy.
MOD #sok:
$ gcc -ansi -pedantic -Wall dab.c
dab.c: In function 'f':
dab.c:5: warning: ISO C90 forbids variable length array 'x'[ Szerkesztve ]
Jester
-
Sk8erPeter
nagyúr
"a függvényeknek csak egyetlen returnje legyen"
Na jó, de mondjuk egy prímtesztelő függvénynél pl. azt szeretnénk, hogy 1-gyel térjen vissza, ha egy szám prím, 0-val, ha nem az, hát ott kapásból a 0-nál vagy 1-nél 0-val kell, hogy visszatérjen, tehát ott már lesz egy return 0; , ha viszont az jött ki, hogy a szám prím, akkor ugye return 1;. És akkor már két return van a függvényben Vagy nem így értetted? Mert ez szerintem még bőven átlátható, és erre az átláthatóság nem jó érv szerintem...Ezek szerint annyira neked sem jöttek be az órái. Az mondjuk valóban nagy előny, ha előtte jól toltad legalább Pascalban, mert akkor csak át kell szokni a másik nyelv szintaktikájára. Hát nekem nem volt túl egyszerű a 0-ról megtanulni programozni, ilyen tanárokkal... Mondjuk most kifogtunk egy nagyon jó gyakvezt (Lengyel László, hátha ismered), aki végre úgy magyaráz, hogy az követhető, és egyáltalán nem unalmas, ráadásul bevon mindenkit a feladatmegoldásba, nem úgy ülsz ott órán, hogy mikor lesz már végre vége a gyaknak. Az nagy előny.
Sk8erPeter
-
Jester01
veterán
Más konvenciók meg pont azt mondják, hogy nyugodtan használj annyi returnt amennyit akarsz, az átláthatóság miatt Ugyanis adott esetben sok if/else ág lenne illetve segédváltozók és/vagy ciklus lefutás után a feltétel újratesztelése is szükséges lehet.
int find(int needle, int* haystack, int size)
{
int result = -1;
if (haystack == NULL)
{
fputs("haystack NULL", stderr);
} else {
for(int i = 0; i < size; i++)
{
if (haystack[i] == needle)
{
result = i;
break;
}
}
}
return result;
}-vagy-
int find(int needle, int* haystack, int size)
{
if (haystack == NULL)
{
fputs("haystack NULL", stderr);
return -1;
}
for(int i = 0; i < size; i++)
{
if (haystack[i] == needle)
{
return i;
}
}
return -1;
}Az első esetben hiába van 1 return a függvény végén, ahhoz, hogy megtudd mit ad vissza ígyis-úgyis végig kell nézni a függvényt, hogy hol lesz az a változó beállítva. Akkor meg pont ugyanolyan egyszerű a return utasításokat megkeresni. Ha pedig mondjuk két ciklus van egymásbaágyazva akkor még több macera kijutni belőlük (mivel ugye goto-t sem használunk )
[ Szerkesztve ]
Jester
-
Karma
félisten
Egy kicsit olvasgattam (szerencsére elég sűrű a C-ről szóló írások száma a neten ), úgy tűnik elég vegyes a dolog. Auto-pointereknél nem para a felszabadítás több return esetén, de pl. CleanupStacknél sokkal bonyolultabb a memóriát karban tartani.
“All nothings are not equal.”
-
Sk8erPeter
nagyúr
Dehát ez már kapásból nem jó, ha 0-t vagy 1-et adsz be a függvénynek, hiszen ezekre is azt fogja mondani a függvény, hogy prím, és nem tételezheted fel, hogy nem fog a felhasználó beadni 0-t vagy 1-et... És ugye a 0 vagy az 1 nagyon nem prímszám...
Pontosan ezen csodálkoztam a Prog honlapján fenn lévő MINTAmegoldásoknál, hogy rossz a prímtesztelő függvény... ---> [link]
Itt így csinálták meg a függvényt:
int prime(int a){
int i,max=(int)(sqrt(a)+1);
for(i=2;i<a;i++)if(a%i==0)return 0;
return 1;
}
És ez is rohadtul mindig 1-et fog visszaadni eredményül, ha 0 vagy 1 a számunk... Ja, és még egyet igencsak elbaszarintottak benne: létrehozták a max változót, de sehol sem használják fel...
Tőlünk ugye elvárják a hibátlan megoldásokat, de ők a MINTAként feltett ZH-ban két ilyen üvöltő hibát elkövethetnek. Kicsit gáz.[ Szerkesztve ]
Sk8erPeter
-
addikt
Én tisztáznám magam,de azzal is belemártózok.Ezt a programot se én írtam,de mivel nem tanultam ilyesmit egyik havernak meg volt ilyen,így elkértem.
Azt is tudjátok most tanulok,így előbb megcsinálom később megértem alapon megy,mert fordítva már nehéz lesz ekkora anyagnál.Köszi,hogy szóltok ilyenért,mert ebből is tanulok.
-
Sk8erPeter
nagyúr
Gondolkoztam még ezen, hogy miért lesz átláthatóbb a függvény, ha egyetlen return van, de nem látom be, miért is lenne ez jó. Szerintem azonnal áttekinthetővé válik a dolog, hogy ha valami feltétel, amire várunk, már az elején teljesül, akkor ne is folytassa tovább a vizsgálgatást, ez gondolom akár gyorsaság szempontjából sem lehet elhanyagolható. Jester01-gyel értek egyet, sokkal kevésbé lesz átlátható a függvény a sok if-else elágazás miatt. A tanított anyagokban is mindenhol akár több return utasítás is van bizonyos feltételek teljesülése esetén.
De most tényleg, miért lenne baj, ha több return van?
___________________
"Auto-pointereknél nem para a felszabadítás több return esetén, de pl. CleanupStacknél sokkal bonyolultabb a memóriát karban tartani."
Ebből sokat nem értettem, ezt röviden el tudod magyarázni?Sk8erPeter
Új hozzászólás Aktív témák
● olvasd el a téma összefoglalót!
● ha kódot szúrsz be, használd a PROGRAMKÓD formázási funkciót!