Hirdetés

2024. május 1., szerda

Gyorskeresés

Hozzászólások

(#1451) grabber


grabber
addikt

Hali!

Valamiért nem akar ez működni és nem tudom miért.Annyira nem lenne érdekes,mert másik kóddal működik,de meg szeretnék tanulni programozni amihez értenem is kell.HA már VIK akkor csatlakozok,hogy a goto-ért exit jár :D

#inlude <stdio.h>
#include <stdlib.h>
#include <conio.h>

main ()
{
File*fp
char c;
fp=fopen("C:\prog\blabla.txt","r");
if(fp==NULL){printf("Hiba a fajl olvasasnal");exit(1);}
while(!feof(fp)){
c=fgetc(fp);
fputc(c,stdout);
}
fclose(fp);
exit(0);
}

Ez nem akar működni,VS8 fatal error C1021: invalid preprocessor command 'inlude'

Code blocks: progi\main.c|1|invalid preprocessing directive #inlude|
progi\main.c|6|warning: return type defaults to `int'|
progi\main.c||In function `main':|
progi\main.c|7|error: `File' undeclared (first use in this function)|
progi\main.c|7|error: (Each undeclared identifier is reported only once|
progi\main.c|7|error: for each function it appears in.)|
progi\main.c|8|error: `fp' undeclared (first use in this function)|
progi\main.c|8|error: syntax error before "char"|
progi\main.c|9|warning: implicit declaration of function `fopen'|
progi\main.c|9|warning: unknown escape sequence '\p'|
progi\main.c|9|warning: unknown escape sequence '\P'|
progi\main.c|10|warning: implicit declaration of function `printf'|
progi\main.c|11|warning: implicit declaration of function `feof'|
progi\main.c|12|error: `c' undeclared (first use in this function)|
progi\main.c|12|warning: implicit declaration of function `fgetc'|
progi\main.c|13|warning: implicit declaration of function `fputc'|
progi\main.c|13|error: `stdout' undeclared (first use in this function)|
progi\main.c|15|warning: implicit declaration of function `fclose'|
||=== Build finished: 8 errors, 9 warnings ===|

Helyette ez müxik,de még alakítani,kell hogy beolvassam dinamikus adatszerkezetbe.

#include <stdio.h>
void main()
{

int c;
FILE *fp;

if( (fp = fopen("C:\\prog\\blabla.txt","rt")) == NULL )
{
printf("\nHiba a blabla.blabl megnyitásánál !");
// Kilépés a programból
exit(0);
}
// Elôolvasás.
c = fgetc(fp);

// Amíg nincs file vége.
while( !feof(fp) )
{
printf("\nA beolvasott karakter : %c",c);
// Olvassa a következôt.
c = fgetc(fp);
}
// A file lezárása.
fclose(fp);
}

[ Szerkesztve ]

(#1452) Karma válasza grabber (#1451) üzenetére


Karma
félisten

Hát hasonlítsd össze a két kódot, elég jól látszik, a hibaüzenetek is beszédesek.

Pl.:
1) A File és a FILE két külön dolog (ez nem Pascal, a kis- és nagybetű számít!). Az utóbbi az érvényes, az előző meg a C számára ismeretlen fogalom, reklamál is miatta.
2) Ugyanebben a sorban kihagytál egy pontosvesszőt.
3) A legelső include-odat elírtad, "inlude" lett helyette, ez adja a többi hibaüzenet nagy részét.
4) A fájl elérési útvonalában nem jól írtad a \ jeleket. Mivel az escape karaktereket is az jelzi, a backslasheket kétszer kell beírni, mint a példádban.

Azt hiszem ennyi az össz hiba.

“All nothings are not equal.”

(#1453) grabber válasza Karma (#1452) üzenetére


grabber
addikt

Köszi,csak már lassan 24 órája progot tanulok.Tanulj meg 24 óra alatt programozni :D De reménytelen és már egyre többet hibázok.Lásd előbb.

(#1454) Sk8erPeter válasza Karma (#1450) üzenetére


Sk8erPeter
nagyúr

dabadab, Karma, kovsol: köszi a válaszokat! :R
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 :DDD
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? :F Mi ez az exit-mánia? :D

Sk8erPeter

(#1455) dabadab válasza Sk8erPeter (#1454) üzenetére


dabadab
titán

"miért használsz mindenhol exit(0)-t?"

Mert kezdő :) (Mondjuk a voidra definiált main()-re azért sikoltoznia kellene a fordítónak.)
Az exit() használata tulajdonképpen ugyanannyira problémás, mint a goto, ugyanazon okok miatt.

[ Szerkesztve ]

DRM is theft

(#1456) Karma válasza dabadab (#1455) üzenetére


Karma
félisten

Szerintem csak -Wall mellett. Ma futottam össze egy kóddal, ott még azért se kiabált, a fordító, hogy:

int i, tomb[i];

Részemről nem tudom megemészteni.

“All nothings are not equal.”

(#1457) dabadab válasza Karma (#1456) üzenetére


dabadab
titán

GCC minden egyéb kapcsoló nélkül rítt, hogy warning: return type of ‘main’ is not ‘int’.

A te példád meg igazából teljesen rendben van, az inicializálatlan változók használatának kiszűrése meg nem tartozik a klasszikus warning okok kozé.

DRM is theft

(#1458) Karma válasza dabadab (#1457) üzenetére


Karma
félisten

Az RVCT nekem mindig rinyál.

Egyébként nem úgy volt, hogy stacken tömböt csak fix méretben lehet létrehozni? Még én is ezt állítottam nemrég, de ez a sor (bár felrobbant, ha futtatja az ember) elbizonytalanított egy kicsit a hitemben. Vagy az csak a Pascalban volt így, és valamiért összekeverem? Égő :B

[ Szerkesztve ]

“All nothings are not equal.”

(#1459) Karma válasza Karma (#1458) üzenetére


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 :P Elnézve a C99 újításait, gyanúsan C89-et "oktatott" anno Poppe prog1 órán.

[ Szerkesztve ]

“All nothings are not equal.”

(#1460) dabadab válasza Karma (#1458) üzenetére


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
36

szerk: látom, neked volt lelkierőd elolvasni a dokumentációt :D

[ Szerkesztve ]

DRM is theft

(#1461) sghc_toma válasza Karma (#1458) üzenetére


sghc_toma
senior tag

C89-ben es C++-ban nem lehet, C99-ben lehet.. mondjuk snow leo gcc-je -std=c89-cel sem sirt miatta.. es generalt egy kilometer kodot belole, amit most nem fogok atbogaraszni, majd holnap reggel :)

// ehh, jol elkestem..

[ Szerkesztve ]

in asm we trust

(#1462) Jester01 válasza Karma (#1458) üzenetére


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 :DD 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

(#1463) Darth_Revan


Darth_Revan
veterán

Hali

Adott az alábbi C program:

#include <stdio.h>
#include <stdlib.h>

int main (int argc, char **argv)
{

if (argc <2)
{
printf ("Kevés paraméter");
exit (2);
}

int szam;
sscanf (argv[1], "%d", &szam);
printf ("szam: %d, szam);

}

Beírom, hogy " ./script neve ami lefordítja szám " és akármilyen számot adok meg nem azt adja vissza, hanem a tízszeresét..miért?

(#1464) Gyuri16 válasza Darth_Revan (#1463) üzenetére


Gyuri16
senior tag

nalam jol mukodik. gcc 4.3.2
(utolso printf-bol hianyzik egy ", illetve egy return 0 a vegere )

Nem vagyok egoista, csak uborkagyalu!

(#1465) doc válasza Darth_Revan (#1463) üzenetére


doc
nagyúr

nekem (OSX, gcc) jol mukodik

MOD: ugy tunik a te keszulekedben van a hiba... milyen fordito?

[ Szerkesztve ]

(#1466) Darth_Revan válasza doc (#1465) üzenetére


Darth_Revan
veterán

Érdekes, már nálam is jól működik :B

(#1467) Darth_Revan


Darth_Revan
veterán

azt hogy lehet megoldani, hogy char tmb[szam] tömbbe (szam-ot a fenti módszerrel adom meg) eltárolók scanf-el billentyűzetről beolvasott decimális számokat, majd kiírom őket? Megpróbáltam volna kiíratni for ciklussal a &tmb-t de vagy semmit se ír ki (üres) vagy csak random karaktereket :(

(#1468) Karma válasza Darth_Revan (#1467) üzenetére


Karma
félisten

Hát az biztos, hogy nem az & operátorral, ami visszaadja az adott változó címét, jelen esetben a tömböd első elemére mutató konstans pointer címét :)

Helyette, amikor kiírsz, csináld ezt például:

for (int i = 0; i < szam; i++)
{
putchar(tomb[i]);
}

“All nothings are not equal.”

(#1469) Darth_Revan válasza Karma (#1468) üzenetére


Darth_Revan
veterán

Igen, kitöröltem a &-t és már így jó :) Csak char tömb miatt 128-ig kezeli jól a számokat és ezt kellene még valahogy megoldani, hogy az ennél nagyobb számokat is tudja jól kezelni. (muszáj char típusnak lennie a tömbnek)

(#1470) Karma válasza Darth_Revan (#1469) üzenetére


Karma
félisten

unsigned char?

“All nothings are not equal.”

(#1471) Darth_Revan válasza Karma (#1470) üzenetére


Darth_Revan
veterán

Azzal pedig 255-ig kezeli jól a számokat. Char tömbbe kellene tárolni egész, decimális int számokat és kiírni őket. (Majd kiírni őke bit-ként)

[ Szerkesztve ]

(#1472) Karma válasza Darth_Revan (#1471) üzenetére


Karma
félisten

Na, ha ezt mondtad volna először, mindjárt lenne a helyzet.

Akkor meg tárold el a simán a karaktereket, és majd később sscanf-fel konvertáld őket számmá, ha számolni is kell velük. Nem jó így? Mi is lesz belőle a végén?

“All nothings are not equal.”

(#1473) cucka válasza Karma (#1472) üzenetére


cucka
addikt

Gondolom az a feladat lényege, hogy számjegyenként kell eltárolni a bekért számokat és így kell velük műveleteket végezni.
(A fenti csak tipp, de az ilyen típusú feladatokat mindenhol el szokták játszani programozás órán :) )

[ Szerkesztve ]

(#1474) Darth_Revan válasza Karma (#1472) üzenetére


Darth_Revan
veterán

Azt nem igazán tudom hogyan kell...atoi-vel kellene valahogy.

(#1475) bpx válasza Darth_Revan (#1474) üzenetére


bpx
őstag

eleve karaktertömbbe olvasol be a billentyűzetről, és ha kell valamit számolni, elég akkor pl. int-té konvertálni (pl. sscanf-el, ahogy a korábbi kódodban csináltad, vagy akár atoi)

(feltéve, hogy nem "hülye-biztos" programot kell írni, mert akkor marad a karakterenkénti ellenőrzött adatbevitel)

[ Szerkesztve ]

(#1476) Sk8erPeter válasza dabadab (#1455) üzenetére


Sk8erPeter
nagyúr

"Mert kezdő :)"
Mondjuk így se igazán értem, mert nálunk kezdetektől fogva azt verték a fejünkbe, hogy return. Sőt, azért is szóltak, hogy külön függvény se lépjen ki hasonló módon, idézek:
"Függvény ne hívjon kilépéssel, hasonlókkal kapcsolatos dolgokat, mert a felsőbb szintű kódot ez meglepetéssel fogja érinteni (fájlok lezárása, takarítás elmarad). Ha szükséges, akkor legyen a programnak valami fatal_error() függvénye, azt hívjuk."
(Forrás: http://infoc.eet.bme.hu/gyakorlatok/)

"Az exit() használata tulajdonképpen ugyanannyira problémás, mint a goto, ugyanazon okok miatt."
Akkor ezt most megjegyeztem, hogy az exit() függvényt se fogom sosem használni. :D

(#1459) Karma: titeket is Poppe tanított? Első alkalommal (tavaly) minket is, de nekem annyira megtetszett a tantárgy, hogy felvettem idén is. :DDD Ugyebár nincs kereszt progból... és Poppe órái szvsz olyan szinten unalmasak voltak, hogy egyáltalán nem keltette fel az érdeklődésem a programozás iránt (előtte középsuliban persze egyáltalán nem volt programozás), és ezzel még kb. az évfolyam fele így volt. :D Aztán amikor nyáron elkezdtem a PHP-vel foglalkozni, akkor rájöttem, hogy a programozás jó dolog. És most már ráfeküdtem a C-re is, aláírás megvan, már csak a vizsgára kell gyakorolni, mint egy elmebeteg. :)

[ Szerkesztve ]

Sk8erPeter

(#1477) Karma válasza Sk8erPeter (#1476) üzenetére


Karma
félisten

Az exit tényleg durva. De ha már ott tartunk, számomra bevált az a gyakorlat, és egyébként is rengeteg konvenció azt is mondja, hogy a függvényeknek csak egyetlen returnje legyen, pont az átláthatóság miatt.

Egyszerűbb, ha az ember felelősségekkel tervez. Egy számot ellenörző függvénynek köze sincs a teljes program futásához (jó esetben, retardált feladatokat leszámítva), így oda értelemszerűen nem kerülhet exit. Igazából az alkalmazáslogikának 99%-ának semmi köze hozzá.

Ő "tanított", de nem programozni, hanem csak ledarálta a C nyelv alapjait. Szerencsémre az elv már korábban megvolt, Pascalban elég sokat versenyeztem, így a C nem volt nagy falat. Elővizsgával simán lenyomtam elsőre, meg általában a többi programozási tárgyat is.

[ Szerkesztve ]

“All nothings are not equal.”

(#1478) Sk8erPeter válasza Karma (#1477) üzenetére


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 :D Vagy nem így értetted? Mert ez szerintem még bőven átlátható, és erre az átláthatóság nem jó érv szerintem... :F

Ezek szerint annyira neked sem jöttek be az órái. :D 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... :U 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. :K

Sk8erPeter

(#1479) Karma válasza Sk8erPeter (#1478) üzenetére


Karma
félisten

Egy prímtesztelőnél vannak bonyolultabb függvények is :)
De ezt is meg lehet oldani egy returnnel.

Itt egy nagyon naív példa:

int isPrime(int aNumber)
{
int result = 1; // T.F.H. igaz
int i;
int max = aNumber / 2;

for (i = 2; i <= max && result; i++) // kilépünk a ciklusból, ha a feltevés sérül
{
result = aNumber % i;
}

return result;
}

[ Szerkesztve ]

“All nothings are not equal.”

(#1480) Jester01 válasza Karma (#1477) üzenetére


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 :DDD 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 :N )

[ Szerkesztve ]

Jester

(#1481) Karma válasza Jester01 (#1480) üzenetére


Karma
félisten

Mondjuk mindkettőnk példája eléggé erőszakolt, azt a NULL ellenőrzést én nem tenném bele a függvénybe, inkább odaírnám a doksiba, hogy nem lehet NULL, és nem hívnám meg ha nincs értelme :)

“All nothings are not equal.”

(#1482) Karma válasza Karma (#1481) üzenetére


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.”

(#1483) PazsitZ


PazsitZ
addikt

Lehet amatőr kérdés, de a long int-et hogyan kell jelölni? Ugyan is ezt a warning-ot kapom:
feladat.c:53: warning: format ‘%u’ expects type ‘unsigned int *’, but argument 3 has type ‘long int *’

, s bár lefordul, de szabványosan, mi lenne a long int jelölése?
google-ban nem tudom, erre pl hogyan kellene keresnem
printf("%u %u %u",a,b,c);

- http://pazsitz.hu -

(#1484) Karma válasza PazsitZ (#1483) üzenetére


Karma
félisten

Unsigned longé %lu, signedé %ld.
Ha kell, a long long inté meg %lld és %llu, vagy windowson %I64u és %I64d.

[ Szerkesztve ]

“All nothings are not equal.”

(#1485) PazsitZ válasza Karma (#1484) üzenetére


PazsitZ
addikt

Köszönöm a segítséget!

- http://pazsitz.hu -

(#1486) Sk8erPeter válasza Karma (#1479) üzenetére


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... :Y :U
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

(#1487) Karma válasza Sk8erPeter (#1486) üzenetére


Karma
félisten

Eh, mondtam, hogy naív megoldás, azt nem, hogy jó is :DDD
Meg egyébként is csak firkáltam.

[ Szerkesztve ]

“All nothings are not equal.”

(#1488) sghc_toma válasza Jester01 (#1480) üzenetére


sghc_toma
senior tag

nem igazan vagyok otthon compiler-irasban, de mintha valami olyasmit olvastam volna valamikor valahol, hogy van egy rakas optimalizalo algo, ami arra (is) epit, hogy egy fuggvenybe egy helyen bemegyunk, egy masikon meg ki.. errol valaki valamit?

in asm we trust

(#1489) grabber válasza Karma (#1477) üzenetére


grabber
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.

(#1490) Sk8erPeter válasza Karma (#1477) üzenetére


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? :DDD
___________________
"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? :B

Sk8erPeter

(#1491) Karma válasza Sk8erPeter (#1490) üzenetére


Karma
félisten

Pedig ha azok a fogalmak megvannak, az első kérdésre is könnyebb válaszolni. Persze mindkettő C++ minta (sőt, a második csak és kizárólag Symbian C++-ban van), ezért C-nél még nem kavar be.

Auto pointer: egy olyan objektum, ami ha megsemmisül a stacken, magával ránt egy hozzárendelt heapen lévő objektumot is, így amikor az auto_ptr scope-on kívülre kerül, a másik objektum biztosan megsemmisül. Ez egy egyszerűsítés, így biztosan nem maradhat meg a heapen lévő objektum pl. azért, mert valahova berakott az ember még egy returnt, és elfelejtette felszabadítani ott is a memóriát :U

Valahogy így néz ki:

int valami()
{
int *valami_int = new int; // heapen hoztam letre, mint a malloc C-ben
auto_ptr<int> valami_ptr(valami_int); // az auto pointerre bizom a felszabaditast
...
// ugy hasznalom, mint egy pointert
*valami_ptr = 5; // a valtozo erteket valtoztatom itt
...
return 0; // valami_ptr megsemmisul -> valami_int is torlodik
...
return 1; // valahol mashol ugyanez lezajlik
}

Ha nem lenne ez az auto_ptr, akkor mindkét return elé oda kéne írni explicite a következő sort (ez a free C++-os megfelelője), amit könnyen kifelejthet az ember, ha utólag hackelget bele a függvénybe, memory leaket okozva.

delete valami_int;

Cleanup Stack: Amikor a Symbiant írták, még nagyon fejletlenek voltak a C++ fordítók, kivételdobáskor a stacken lévő objektumokra nem hívódott meg a destruktor, ami mindenféle vicces hibához vezethetett, többek között "csak" memory leakhez. Ezért a nagyokosok kitalálták, hogy "csináljunk saját kivételkezelést!", megalkották a Leave-eket és a Cleanup Stacket.

Minden heapen lefoglalt objektumot, ami nem tagváltozó, fel kell kézzel rakni a CleanupStackre, és persze le is kell venni onnan, ha olyan műveletek jönnek, amik kivételt (konkrétan leave-et) dobhatnak. Tehát mindig figyelni kell a programozónak arra, hogy mikor mi van rajta, mikor melyik objektum kinek a felelősségébe tartozik, és ennek megfelelően variálni.

Na itt jön be, hogy ha több return utasítás van, akkor kitörhet a káosz, a függvény különböző részein más lehet a CleanupStack állapota, minden returnnél megfelelően adminisztrálni kell, és ha bármit változtatni kell, mindenhol át kell írni...

Példakód:
TInt CSomething::DoSomethingL()
{
TInt result = 0;

CSomethingBig *big = CSomethingBig::NewL();
CleanupStack::PushL(big);

RSomethingResource res;
CleanupClosePushL(res);

result = res->DoSomethingDangerousL(big); // ha ez dob egy leave-et, res bezarodik, big megsemmisul

CleanupStack::PopAndDestroy(2, big); // mindket elemet megsemmisiti
return result;
}

Ezt a kódot nem magyaráznám túl, ha nem baj, hiszen csak random firkáltam. A lényeg az, hogy a PopAndDestroy hívást minden return előtt meg kell hívni, pontosan.

[ Szerkesztve ]

“All nothings are not equal.”

(#1492) VaZso


VaZso
senior tag

Sziasztok!

Kicsit megkavarodtam... Feladatom, hogy egy config fileból beolvassak különféle változókat.

Kicsit elveszettnek érzem magam abban, hogy milyen változótípus milyen tartományokban működik és akkor még fel sem merült, hogy esetleg más architektúrán mi a különbség...

Tehát:

short: 2 byte-on tárol --> 2^16-1, ill. ha az első bit az előjelbit, akkor -32768 - 32767-ig terjed.

int: 4 byte-os --> 2^32-1 ...

long: 8 byte-os --> 2^64-1 ...

float?

double?

Hogy kezeljem? Mik a határai?
Nem igazán találtam értelmes adatot.

Sima C-vel próbálkozom.

(#1493) gygabor88 válasza VaZso (#1492) üzenetére


gygabor88
tag

[climits] és hasonlóan cfloat tartalmazza a float és double típus határait.

[ Szerkesztve ]

(#1494) 3man válasza VaZso (#1492) üzenetére


3man
csendes tag

"Config" filet sokkal celszerubb valamilyen szabvanyos szoveges formaban letrehozni, es nem binarisan. Semmikepp nem binarisan. Az egyik legoptimalisabb az xml formatum.
Ekkor a problemad egybol eltunik, mivel nem kell azzal foglalkozni, hogy az adott gepen hogyan nez ki a float fizikailag. Ezt az xml kezelo elintezi.

[ Szerkesztve ]

(#1495) Karma válasza 3man (#1494) üzenetére


Karma
félisten

Nem minden esetben előnyös ezért egy teljes XML parsert berántani szerintem.

“All nothings are not equal.”

(#1496) 3man válasza VaZso (#1492) üzenetére


3man
csendes tag

Az xml-re ra lehet epiteni egy olyan config-rendszert, ahol mar azzal sem kell foglalkozni, hogy az adott valtozo int, float vagy eppen string tipusu. Sot az xml definialhatja a valtozokat, a programban a valtozonak nem is kell jelen lenniuk alapbol.

Gondolom elso hallasra furcsan hangzik, de megoldhato egyszeruen.
Eloszor letre kell hozni egy altalanos "valtozo" osztaly. /bocs, megint c++, de itt merult fel a tema./
Az xml-ben egy definicio valahogy igy nez ki : valami="100.2".

class altalanos_valtozo {
public:
char *nev;
int tipus;
char *ertek;
};

A valtozo neve lesz a "valami", az erteke pedig a "100.2". A tipus egyszeruen meghatarozhato, ha csak szamokat es elojelet tartalmaz, akkor int, ha pontot is ,akkor float, a tobbi esetben string. De lehet egyenileg kialakitani tobb tipust is.
Meg nehany konvertalo operatort kell az osztalyhoz adni, es mar kesz is egy kenyelmesen hasznalhato altalanos valtozo, ami egy xml kezelovel kiegeszitve egy tokeletes config kezelest biztosit.
Konnyen bovitheto, mivel az xml-be letrehozva egy ilyen bejegyzest, az automatikusan a programban is azonnal "el".
Mas kerdes, hogy ezt valamire hasznalni is kell, amit "sajnos" bele kell irni a programba.

(#1497) 3man válasza Karma (#1495) üzenetére


3man
csendes tag

Igazad van. Van egy bonyolultsagi szint, ahol mar erdemes, sot, szuksegszeru.

De nehany ertek miatt felesleges. Ettol fuggetlenul a szoveges mod mindenkepp ajanlott. Mar csak amiatt is, mert kezzel editalhato.

(#1498) VaZso válasza 3man (#1494) üzenetére


VaZso
senior tag

A "config" file-om szabványos formátumban van...
..."plain text" ... :)

kulcs = érték módon kap tartalmat a változó, a lekérdezést végezhetik különféle függvények (string, int, long, stb. visszatérési értékkel).

(#1499) 3man válasza VaZso (#1498) üzenetére


3man
csendes tag

Oke, de akkor nem ertem, minek kell az, hogy mekkora szam fer el egy floatba?

(#1500) VaZso válasza gygabor88 (#1493) üzenetére


VaZso
senior tag

Upsz... még mindig nem vagyok "képben"...

Itt kicsit más értékek vannak, mint amit a gépemen tapasztaltam.
Vélhetően azért, mert ez x64-es rendszer.

Mégjobban elbizonytalanodtam, hogy az egyes változóknál milyen tartományt kéne figyelnem, hogy ne csorduljon túl...

Eszerint 32-bites rendszeren a short és az int is 2 byte-os és a long 4 byte-os?

Float működése ill. határai még mindig nem tiszta...

Copyright © 2000-2024 PROHARDVER Informatikai Kft.