Tartalmi kivonat
Utoljára frissítve: 2003-10-02 15:00 1.0–s verzió Feladatok 1. Igazak-e a következő állítások? a, Valamennyi feladat megoldására a C++ nyelv a legalkalmasabb, mivel hatékony objektumorientált kódot lehet így készíteni. b, A C++ nyelv régen született, ezért mára nagyon kiforrott, így szinte tökéletes. c, A C++ nyelv használata során könnyű hibázni a programírás során, ami a nyelv egyik hátránya. d, Ha hatékony objektum orientált kódot kell írni, akkor a C++ (az egyik) legelőnyösebb választás. Emiatt a rendszerprogramozás (egyik) leggyakoribb eszköze és valószínűleg az is marad. e, A C++ egy „szép” programozási nyelv, csak meg kell tanulni bánni vele, meg kell ismerni a trükkjeit és csapdáit. Így C++-ban programozni jó Megoldás 2. Mit ír ki a következő programrészlet? int x = 3; int y = 2; printf("x/y=%f ", (double)x/y); printf("x/y =%f ", (double)(x/y)); printf("x/y=%f ", x/y);
Megjegyzés: a cast operátor precedenciája nagyobb, mint a / operátoré. A pontos formázást nem kell megadni (a %f alapértelmezésben 6 tizedesjegyig írja ki a számot). Megoldás 3. Válaszoljon az alábbi kérdésekre! a, Mi az m, n és o változók értéke az alábbi kódrészlet végrehajtása után? int m=12, n, o; n=m++; o=++n; Megoldás b, Zárójelezze, hogy hogyan értékelődnek ki az alábbi operátorok és indokolja döntését: szulev.datumnap; // a operátor a struktúramező elérését jelenti szulev.datum->pnap; *p[10]; ++p[12]; p->s(); v=g=h; Megoldás c, Az alábbi példában értelmezze a 4-8. sorokat és adja meg e1, e2, e3, e4, e5 értékét! int e1, e2, e3, e4, e5; int t[]={10, 20, 30, 40, 50}; int*p = t; e1 = *p++; e2 = ++*p; e3 = (*p)++; e4 = *++p; e5 = ++p[1]; Megoldás 4. Rejtenek-e valamilyen veszélyt az alábbi kifejezések? int j=10, k=10, m; m = osszead( k++, ++k); // az összead függvény visszatér a két paraméterének
összegével . if (k++> 2 || j--<4) { . } Megoldások 5. Van-e hiba az alábbi kódrészletben? . char* p; char* s=”abc”; strcpy(p, s); // s másolása p-be . char buff[3]; strcpy(buff, s); // s másolása buff-ba Megoldás 6. Írjon több forrásfájlból álló programot az alábbi feladatnak megfelelően! Írjon egy olyan max nevű függvényt, ami paraméterként egy integer tömböt és a tömb hosszát kapja meg. A függvény a tömbben megkapott elemek közül a legnagyobbal térjen vissza (felteheti, hogy valamennyi elem pozitív vagy nulla). A max függvény az m1cpp fájlban legyen definiálva Írjon egy olyan count1 nevű függvényt, ami azt számolja, hogy hányszor hívták meg (ez legyen a visszatérési értéke). A megoldáshoz NE használjon globális változót A count1 függvény az m1.cpp fájlban legyen definiálva Írjon egy olyan inc nevű függvényt, ami egy globális gCount változót növel egyel. Az inc függvény az m1.cpp fájlban legyen
definiálva A main függvény az m2.cpp fájlban legyen definiálva Ebben mutasson példát a fenti függvények és a gCount változó használatára. Megoldás 7. Írjon olyan függvényt, ami egy paraméterként megkapott sztringben a ’&’ karaktereket ‘%’-ra cseréli! Megoldás 8. Írjon olyan függvényt, ami az első paraméterként megkapott sztringet a második paraméterben megkapott helyre másol úgy, hogy a ”&&” szekvenciákat ‘&’-ra cseréli! Megoldás 9. Jellemezze az alábbi típusokat! Hogyan néznek ki a memóriában és mi történik a tömb ill. pointer műveletek végrehajtásakor? a, int* p; Megoldás b, int t[3]; Megoldás c, int* p; int t[3]; p=t; *p=1; *(p+2)=2; p++; Megoldás d, int* p[5]; p[0]=(int*)malloc(sizeof(int)); p[1]=(int*)malloc(3sizeof(int)); *p[0]=1; *p[1]=2; p[1][1]=3; *((p+1)+2)=3; free(p[0]); free(p[1]); Megoldás e, int t[3][2]; int (*p)[2]; p = t; *t[0]=1; t[0][0]=2; t[1][1]=3; *(t[1]+1)=4;
*((t+1)+1)=5; *p[0]=10; p[0][0]=11; p[1][1]=12; *(p[1]+1)=13; *((p+1)+1)=14; Megoldás 10. Összetett típusdeklaráció Adja meg egy-egy mondatban, hogy mit definiálnak az alábbi kifejezések! a, void (*(p)[10])(int); b, void (*t[10])(int); c, double (*(p)(int))(char); Megoldás 11. Írjon C vagy C++ programot a következőkre: Definiáljon egy olyan struktúrát, ami könyvek listájának kezelését teszi lehetővé. Minden könyvről tárolni szeretnénk a címét (max. 100 karakter) és egy szerzőjének nevét (max 50 karakter) Írjon meg egy olyan függvényt, aminek két bemenő paramétere egy könyv címe és szerzője, és ami hozzáadja egy globálisan tárolt láncolt listához a „könyvet” (természetesen miután dinamikusan helyet foglalt egy struktúrának és felparaméterezte azt). A megoldás során felhasználhatja az strcpy sztringmásoló függvényt, aminek deklarációja: char* strcpy(char dest, char src); , és ami a dest paraméter által mutatott
helyre átmásolja az src stringet, a termináló ‘ ’-t is beleértve. Megoldás Megoldások 1. Feladat a, nem b, nem c, igaz d, igaz e, igaz Vissza 2. Feladat Az első printf „x/y=1.500000”-öt ír ki, mivel a kiértékelés sorrendje a következő: Az x konvertálása double-ra, majd a / operátor végrehajtása előtt y-t double-ra konvertálja a rendszer (mivel a / operátor egyik argumentuma double, a másik int, így az int paraméter a bővebb típusra konvertálódik, ami double). Ezután meghívódik a / operátor a két double argumentummal és double eredményt ad vissza. A második printf „x/y=1.000000”-t ír ki, mivel a kiértékelés sorrendje a következő: Meghívódik a / operátor a két int argumentummal és egészek közötti maradékos osztást végrehajtva int-tel tér vissza, aminek értéke 1. Ezután ezt az 1-et castolja double-lá a rendszer A harmadik printf hibás! Meghívódik a / operátor a két int argumentummal és egészek közötti
maradékos osztást végrehajtva int-tel tér vissza, aminek értéke 1. A problémát az okozza, hogy a printf függvénynek így egy int típusú érték adódik át (ami általában négy bájtos), a formatáló sztringben viszont %f-et adtunk meg, amivel az mondjuk a fordítónak, hogy az eredményt 8 bájtos double-ként értelmezze. Emiatt a függvényhívás során a stack elkutyulódik, a program nem definiált módon hibásan fog működni. A példa jól demonstrálja, miért is veszélyes a printf és a hasonló változó argumentumú függvények használata. Vissza 3. Feladat a, Mind a három változó értéke 13. Vissza b, - azonos precedencia, balról jobbra kiértékeléssel (szulev.datum)nap; (szulev.datum)->pnap; - azonos precedencia szint, balról jobbra kiértékeléssel *(p[10]); - a [] operátor magasabb precedencia szinten van, mint a * operátor ++(p[12]); - a []operátor magasabb precedencia szinten van, mint a prefix operátor (p->)s(); - a -> és a
() operátor egy precedencia szinten vannak, balról jobbra kiértékeléssel v=(g=h); - az = operátor jobbról balra értékelődik ki Vissza c, int e1, e2, e3, e4, e5; int t[]={10, 20, 30, 40, 50}; int*p = t; e1 = *p++; // e1=10, p++-t kiértékeli, ami p eredeti meg nem növelt értéke (postfix ++ miatt), és az ezen a címen levő rekesz tartalmát írja e1-be e2 = ++*p; // e2=21, a p által mutatott értéket növeli és azt írja be e2-be (p-t az előző sorban növeltük!) e3 = (*p)++; // e3=21, p által mutatott értéket növeli, de a postfix ++ miatt az eredeti érték íródik e3-ba e4 = *++p; // e4=30, p-t lépteti egyel, és ahová ezután mutat, annak tartalmát írja e4-be e5 = ++p[1]; // e5=41, ekvivalens ++*(p+1)-el, így a p+1 által mutatott rekesz tartalmát egyel növeli és beírjja e5-be Vissza 4. Feladat Két rejtett veszélyforrás lapul a sorokban: Az m = osszead( k++, ++k); esetében a függvény paramétereinek kiértékelési sorrendje nem
definiált, így fordítótól függ az, hogy osszead(10, 11) vagy osszead(11, 11) ami ténylegesen lefut. Az if (k++> 2 || j--<4) esetében a feltétel csak addig értékelődik ki, amíg biztosan el nem dől. Így ha k>2, akkor a j-t nem csökkenti Vissza 5. Feladat Két hiba is van. Az strcpy(p, s); esetében az a gond, hogy az strcpy a p által mutatott területre másol, a p pedig nincs egy lefoglalt területre beállítva. Így a másolás egy nem definiált, véletlenszerű helyre (arra a címre, ami p értéke) történik, így véletlenszerűen felülíródik valami a memóriában (vagy kapunk egy memória védelmi hibát: „Access Violation at .”) Az strcpy(buff, s); már majdnem jó, mert it lefoglaltunk 3 karakternek helyet. Itt az a probléma, hogy 4 karakternek kellett volna helyet foglalni a sztringet lezáró ‘ ’ miatt. Vissza 6. Feladat m1.cpp: int max(int* p, int count) { int maxval = -1; int i; for (i=0; i<count; ++i, ++p) { if ( *p>maxval )
maxval = *p; } return maxval; } int count1() { static int cnt = 0; return ++cnt; } // definiáljuk a gCount globális változót (helyet is foglal) int gCount = 0; void inc() { ++gCount; } m2.cpp: #include <stdio.h> // deklarálni kell a globális változót az adott forrásfájlban használat előtt // itt helyfoglalás nem történik, az m1.cpp-ben definiált változót jelenti extern int gCount = 0; // deklarálni kell a függvényeket az adott forrásfájlban használat előtt int max(int* p, int count); int count1(); void inc(); main() { count1(); inc(); printf("A számlálók értéke: %d, %d", count1(), gCount); } Vissza 7. Feladat void strreplace(char* s) { while(*s!='