Sie sind auf Seite 1von 13

Forrs: http://www.doksi.

hu

Utoljra frisstve: 2003-10-02 15:00 1.0s verzi.

Feladatok
1. Igazak-e a kvetkez lltsok?
a, Valamennyi feladat megoldsra a C++ nyelv a legalkalmasabb, mivel hatkony objektumorientlt kdot lehet gy kszteni. b, A C++ nyelv rgen szletett, ezrt mra nagyon kiforrott, gy szinte tkletes. c, A C++ nyelv hasznlata sorn knny hibzni a programrs sorn, ami a nyelv egyik htrnya. d, Ha hatkony objektum orientlt kdot kell rni, akkor a C++ (az egyik) legelnysebb vlaszts. Emiatt a rendszerprogramozs (egyik) leggyakoribb eszkze s valsznleg az is marad. e, A C++ egy szp programozsi nyelv, csak meg kell tanulni bnni vele, meg kell ismerni a trkkjeit s csapdit. gy C++-ban programozni j. Megolds

2. Mit r ki a kvetkez programrszlet?


int x = 3; int y = 2; printf("x/y=%f\n", (double)x/y); printf("x/y =%f\n", (double)(x/y)); printf("x/y=%f\n", x/y);

Megjegyzs: a cast opertor precedencija nagyobb, mint a / opertor. A pontos formzst nem kell megadni (a %f alaprtelmezsben 6 tizedesjegyig rja ki a szmot). Megolds

3. Vlaszoljon az albbi krdsekre!


a, Mi az m, n s o vltozk rtke az albbi kdrszlet vgrehajtsa utn?
int m=12, n, o; n=m++; o=++n;

Megolds b, Zrjelezze, hogy hogyan rtkeldnek ki az albbi opertorok s indokolja dntst:


szulev.datum.nap; // a . opertor a struktramez elrst jelenti szulev.datum->pnap; *p[10]; ++p[12]; p->s(); v=g=h;

Megolds

Forrs: http://www.doksi.hu

c, Az albbi pldban rtelmezze a 4-8. sorokat s adja meg e1, e2, e3, e4, e5 rtkt!
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];

Megolds

4. Rejtenek-e valamilyen veszlyt az albbi kifejezsek?


int j=10, k=10, m; m = osszead( k++, ++k); // az sszead fggvny visszatr a kt paramternek sszegvel ... if (k++> 2 || j--<4) { ... }

Megoldsok

5. Van-e hiba az albbi kdrszletben?


... char* p; char* s=abc; strcpy(p, s); // s msolsa p-be ... char buff[3]; strcpy(buff, s); // s msolsa buff-ba

Megolds

6. rjon tbb forrsfjlbl ll programot az albbi feladatnak megfelelen!

rjon egy olyan max nev fggvnyt, ami paramterknt egy integer tmbt s a tmb hosszt kapja meg. A fggvny a tmbben megkapott elemek kzl a legnagyobbal trjen vissza (felteheti, hogy valamennyi elem pozitv vagy nulla). A max fggvny az m1.cpp fjlban legyen definilva. rjon egy olyan count1 nev fggvnyt, ami azt szmolja, hogy hnyszor hvtk meg (ez legyen a visszatrsi rtke). A megoldshoz NE hasznljon globlis vltozt. A count1 fggvny az m1.cpp fjlban legyen definilva. rjon egy olyan inc nev fggvnyt, ami egy globlis gCount vltozt nvel egyel. Az inc fggvny az m1.cpp fjlban legyen definilva.

Forrs: http://www.doksi.hu

A main fggvny az m2.cpp fjlban legyen definilva. Ebben mutasson pldt a fenti fggvnyek s a gCount vltoz hasznlatra. Megolds

7. rjon olyan fggvnyt, ami egy paramterknt megkapott sztringben a & karaktereket %-ra cserli!
Megolds

8. rjon olyan fggvnyt, ami az els paramterknt megkapott sztringet a msodik paramterben megkapott helyre msol gy, hogy a && szekvencikat &-ra cserli!
Megolds

9. Jellemezze az albbi tpusokat! Hogyan nznek ki a memriban s mi trtnik a tmb ill. pointer mveletek vgrehajtsakor?
a,
int* p;

Megolds b,
int t[3];

Megolds c,
int* p; int t[3]; p=t; *p=1; *(p+2)=2; p++;

Megolds d,
int* p[5]; p[0]=(int*)malloc(sizeof(int)); p[1]=(int*)malloc(3*sizeof(int)); *p[0]=1; *p[1]=2; p[1][1]=3; *(*(p+1)+2)=3; free(p[0]); free(p[1]);

Forrs: http://www.doksi.hu

Megolds 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;

Megolds

10. sszetett tpusdeklarci. Adja meg egy-egy mondatban, hogy mit definilnak az albbi kifejezsek!
a, void (*(*p)[10])(int*); b, void (*t[10])(int*); c, double (*(*p)(int))(char); Megolds

11.

rjon C vagy C++ programot a kvetkezkre:

Definiljon egy olyan struktrt, ami knyvek listjnak kezelst teszi lehetv. Minden knyvrl trolni szeretnnk a cmt (max. 100 karakter) s egy szerzjnek nevt (max. 50 karakter). rjon meg egy olyan fggvnyt, aminek kt bemen paramtere egy knyv cme s szerzje, s ami hozzadja egy globlisan trolt lncolt listhoz a knyvet (termszetesen miutn dinamikusan helyet foglalt egy struktrnak s felparamterezte azt). A megolds sorn felhasznlhatja az strcpy sztringmsol fggvnyt, aminek deklarcija: char* strcpy(char* dest, char* src); , s ami a dest paramter ltal mutatott helyre tmsolja az src stringet, a terminl \0-t is belertve. Megolds

Megoldsok

Forrs: http://www.doksi.hu

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 kirtkels sorrendje a kvetkez: Az x konvertlsa double-ra, majd a / opertor vgrehajtsa eltt y-t double-ra konvertlja a rendszer (mivel a / opertor egyik argumentuma double, a msik int, gy az int paramter a bvebb tpusra konvertldik, ami double). Ezutn meghvdik a / opertor a kt double argumentummal s double eredmnyt ad vissza. A msodik printf x/y=1.000000-t r ki, mivel a kirtkels sorrendje a kvetkez: Meghvdik a / opertor a kt int argumentummal s egszek kztti maradkos osztst vgrehajtva int-tel tr vissza, aminek rtke 1. Ezutn ezt az 1-et castolja double-l a rendszer. A harmadik printf hibs! Meghvdik a / opertor a kt int argumentummal s egszek kztti maradkos osztst vgrehajtva int-tel tr vissza, aminek rtke 1. A problmt az okozza, hogy a printf fggvnynek gy egy int tpus rtk addik t (ami ltalban ngy bjtos), a formatl sztringben viszont %f-et adtunk meg, amivel az mondjuk a fordtnak, hogy az eredmnyt 8 bjtos double-knt rtelmezze. Emiatt a fggvnyhvs sorn a stack elkutyuldik, a program nem definilt mdon hibsan fog mkdni. A plda jl demonstrlja, mirt is veszlyes a printf s a hasonl vltoz argumentum fggvnyek hasznlata. Vissza

3. Feladat
a, Mind a hrom vltoz rtke 13. Vissza b,
- azonos precedencia, balrl jobbra kirtkelssel (szulev.datum).nap; (szulev.datum)->pnap; - azonos precedencia szint, balrl jobbra kirtkelssel *(p[10]); - a [] opertor magasabb precedencia szinten van, mint a * opertor ++(p[12]); - a []opertor magasabb precedencia szinten van, mint a prefix opertor (p->)s(); - a -> s a () opertor egy precedencia szinten vannak, balrl jobbra kirtkelssel v=(g=h); - az = opertor jobbrl balra rtkeldik ki

Vissza

Forrs: http://www.doksi.hu

c,
int e1, e2, e3, e4, e5; int t[]={10, 20, 30, 40, 50}; int*p = t; e1 = *p++; // e1=10, p++-t kirtkeli, ami p eredeti meg nem nvelt rtke (postfix ++ miatt), s az ezen a cmen lev rekesz tartalmt rja e1-be e2 = ++*p; // e2=21, a p ltal mutatott rtket nveli s azt rja be e2-be (p-t az elz sorban nveltk!) e3 = (*p)++; // e3=21, p ltal mutatott rtket nveli, de a postfix ++ miatt az eredeti rtk rdik e3-ba e4 = *++p; // e4=30, p-t lpteti egyel, s ahov ezutn mutat, annak tartalmt rja e4-be e5 = ++p[1]; // e5=41, ekvivalens ++*(p+1)-el, gy a p+1 ltal mutatott rekesz tartalmt egyel nveli s berjja e5-be

Vissza

4. Feladat
Kt rejtett veszlyforrs lapul a sorokban: Az m = osszead( k++, ++k); esetben a fggvny paramtereinek kirtkelsi sorrendje nem definilt, gy fordttl fgg az, hogy osszead(10, 11) vagy osszead(11, 11) ami tnylegesen lefut. Az if (k++> 2 || j--<4) esetben a felttel csak addig rtkeldik ki, amg biztosan el nem dl. gy ha k>2, akkor a j-t nem cskkenti. Vissza

5. Feladat
Kt hiba is van. Az strcpy(p, s); esetben az a gond, hogy az strcpy a p ltal mutatott terletre msol, a p pedig nincs egy lefoglalt terletre belltva. gy a msols egy nem definilt, vletlenszer helyre (arra a cmre, ami p rtke) trtnik, gy vletlenszeren fellrdik valami a memriban (vagy kapunk egy memria vdelmi hibt: Access Violation at ....). Az strcpy(buff, s); mr majdnem j, mert it lefoglaltunk 3 karakternek helyet. Itt az a problma, hogy 4 karakternek kellett volna helyet foglalni a sztringet lezr \0 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;

Forrs: http://www.doksi.hu

} return maxval; } int count1() { static int cnt = 0; return ++cnt; } // definiljuk a gCount globlis vltozt (helyet is foglal) int gCount = 0; void inc() { ++gCount; }

m2.cpp:
#include <stdio.h> // deklarlni kell a globlis vltozt az adott forrsfjlban hasznlat eltt // itt helyfoglals nem trtnik, az m1.cpp-ben definilt vltozt jelenti extern int gCount = 0; // deklarlni kell a fggvnyeket az adott forrsfjlban hasznlat eltt int max(int* p, int count); int count1(); void inc(); main() { count1(); inc(); printf("A szmllk rtke: %d, %d", count1(), gCount); }

Vissza

7. Feladat
void strreplace(char* s) { while(*s!='\0') { if (*s == '&') { *s='%'; } s++; } } // plda a hasznlatra

Forrs: http://www.doksi.hu

main() { char teststr[]="abc&d&f"; printf("teststr=%s\n", teststr); strreplace(teststr); printf("teststr=%s\n", teststr); }

Megjegyzsek: A void strreplace(char* s)" helyett rhattunk volna "void strreplace(char[] s)"-t, ami teljesen ugyanazt jelenti. Az strreplace fggvny meghvsakor nem addik t a tmb, csak az els elem (vagyis a tmb) cme. Ez egy 4 bjl tadst jelenti a stack-en (ltalban 32 bites OS alatt). Egy msik megolds, ami tmbindexelst hasznl:
void strreplace(char* s) { int i=0; while(s[i]!='\0') { if (s[i] == '&') { s[i]='%'; } i++; } }

Vissza

8. Feladat
HF. Vissza

9. Feladat
A lnyeg, hogy emlkezznk az alapszablyokra: pointer definci pl.: int* p; , ami egy pointernek foglal helyet tmb definci pl.: int t[10]; , ami 10 int-nek foglal helyet a tmb neve (mint szimblum) az els elem cmt jelenti, de a cmnek nem foglaldik kln hely brmibl lehet tomb, pl. tmbbl is, pl.: int t[5][10];, ami olyan 5 elem tmb, aminek elemei 10 elem tmbk tmb esetben a t[i] ekvivalens *(t+i)-vel, de ugyanez igaz a p pointerre is p++, p+i, t+i, stb.. a pointert ill. a tmbt mindig tpusnyival lpteti (tmbnl ami az elem tpusa, pointernl amire mutat) ha tmbt adunk t fggvnynek mindig csak a tmb (vagyis az els elem) cme addik t, sohasem a teljes tmb Mindig kpzeljk el, hogy az adott vltoz hogy nz ki a memriban. Memria rekeszekben gondolkodjunk, ami rekeszeknek cme van valahol a memriban. a tbbi kiderl a pldkbl

Forrs: http://www.doksi.hu

a,
int* p;

p egy pointer int-re vagy egy int tmb els elemre. 4 bjtot foglal el a memriban (32 bites OS alatt), ami egy cmet trol. Ez a pointer nincs semmi rvnyes terletre belltva, gy nem definilt, hogy hova mutat (vletlenszer a tartalma).
p ennek a rekesznek a tartalmt jelenti, ami mutat valahov

Megjegyzs: minden pointer mrete (char*, int*, stb.) megegyezik, vagyis ugyanannyi helyet foglal a memriban. A mutatott rtk tpust csak azrt kell megadni, hogy ha nveljk/cskkentjk a pointer rtkt, akkor tudja a fordt, hogy hny bjttal kell pontosan nvelni az rtkt. Pl. ha int*rl van sz, akkor a p++ 4-el nveli a pointer rtkt, hiszen az int mrete ngy bjt (ltalban). gy fog a pointer egy elemnyivel nni. Vissza b,
int t[3];

t egy 3 elem tmb, melynek elemei int-ek. 3* sizeof (int)-et foglal el a memriban (jellemzen 3*4 bjtot). A t szimblum ugyanakkor az els elem cmt is jelli, gy t felfoghat egy konstans int* pointernek is. Vigyzat, ugyan t az els elem cmt jelli ugyan (t==&t[0]), de kln hely ennek a pointernek nem foglaldik, csak jellsrl van sz. gy t-t nem is lehet megvltoztatni (pl. a t++ hibs), hiszen ha a pointernek nincs kln memriarekesz, akkor mit is nvelnnk? Mindezek jl megrthetk, ha a memriabeli kpt t-nek lerajzoljuk:
t az els elem cmt jelenti, de ennek a cmnek nincs kln memria rekesz, csak az elemeknek foglaldik hely int int int cmek t[0] v. *t t[1] v. *(t+1) t[2] v. *(t+2)

Az brn az is jl lthat, hogy a t+i a t cmrl nem i bjtnyit, hanem i elemnyit lp a memriban. Vissza c,
int* p; int t[3]; p=t;

Ez tulajdonkppen az elz plda, csak a p pointert belltottuk a tmb cmre.

Forrs: http://www.doksi.hu

int t ennek a cme

int

int

Ezek utn a kvetkezket nzzk:


*p=1; *(p+2)=2; p++;

3. A p++ ennek a rekesznek a tartalmt egy tpusnyival (int* esetn sizeof(int)el) nveli, vagyis p ezutn ide mutat.

int

int

int 2. A *(p+2) ill. a p[2] ennek a rekesznek a tartalmt jelenti, gy a *(p+2)=2 ebbe a rekeszbe 2-t r.

1. A *p ennek a rekesznek a tartalmt jelenti, gy a *p=1 ebbe a rekeszbe 1-et r.

Vissza d,
int* p[5];

p egy olyan 5 elem tmb, melynek elemei pointerek integerekre. Plda a hasznlatra:
int* p[5]; p[0]=(int*)malloc(sizeof(int)); p[1]=(int*)malloc(3*sizeof(int)); *p[0]=1; *p[1]=2; p[1][1]=3; *(*(p+1)+2)=3; free(p[0]); free(p[1]);

Forrs: http://www.doksi.hu

p ezt a tmbt jelenti (els elem cme) int* int* int* int* int*

p[0] v. *p az p[1] v. *(p+1) az ebben a ebben a rekeszben lev rekeszben lev pointert jelenti pointert jelenti int int A malloc-al lefoglaltuk s a p[0] pointert belltjuk ennek a rekesznek a cmre. A *p[0]=1 ide 1-et r. A p[1][1] v. *(p[1]+1) v. *(*(p+1)+1) ezt a rekeszt jelenti. A *p[1] v. p[1][0] v. *(*(p+1)) ezt a rekeszt jelenti, pl. a *p[1]=2 ide 2-t r. A malloc-al lefoglaltuk s a p[1] pointert belltjuk ennek a rekesznek a cmre. int int

A p[1][2] v. *(p[1]+2) v. *(*(p+1)+2) ezt a reke

Vissza e,
int (*p)[2];

p egy pointer egy 2 elem tmbre, melynek elemei int-ek. p nvelse 2 int-nyit ugrik a memriban. Ugyanis ehhez megnzi, hogy p milyen tpusra mutat, s a tpus mretvel nvel. Itt a tpus mrete egy 2-es int tmb, aminek mrete 2*4 bjt. Plda a hasznlatra loklisan (stack-en) vagy globlisan (adatszegmensben) foglalt memrival:
int t[3][2]; int (*p)[2]; helyre mutat p = t; lltjuk *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; // ez lefoglal 3*2 int-nyi helyet // egy pointernek foglal helyet, ami nem definilt // p kompatbilis t-vel, a pointert a tmb elejre

Forrs: http://www.doksi.hu

p ennek a rekesznek a tartalmt jelenti

t ezt a tmbt jelenti (els elem cme) int int int int int int

t[0] v. *t ez a tmb (ebben az els elem cme)

t[1] v. *(t+1) ez a tmb (ebben az els elem cme) A *t[0] v. t[0][0] v. **t ezt a rekeszt jelenti, pl. a *t[0]=2 ide 2-t r.

t[2] v. *(t+2) ez a tmb (ebben az els elem cme) A t[1][1] v. *(t[1]+1) v. *(*(t+1)+1) ezt a rekeszt jelenti.

t helybe mindenhol lehet p-t is rni, ugyanazt jelenti

Az plda a hasznlatra dinamikus memria hasznlattal (az elz pldhoz kpest csak az a klnbsg, hogy a hely lefoglalsa dinamikusan trtnik s nem a tmb ltal, gy az brn a t-helybe mindenhol p-t kell rni):
int (*p)[2]; p = (int(*)[2])malloc(2*3*sizeof(int)); // ez nem volt eladson, nem kell *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; free(p);

tudni

Vissza

10.

Feladat

a, void (*(*p)[10])(int*) - p egy pointer egy olyan 10 elem tmbre, melynek elemei pointerek olyan fggvnyekre, melyek egy int* paramtert vrnak s void-dal trnek vissza. A definci sorn egy pointernek (4 bjt ltalban) foglaldik hely. b, void (*t[10])(int*) - t egy 10 elem tmb, melynek elemei olyan fggvnyekre mutat pointerek, melyek egy int* paramtert vrnak s void-dal trnek vissza. A definci sorn 10 pointernek (10*4 bjt ltalban) foglaldik hely.

Forrs: http://www.doksi.hu

c, double (*(*p)(int))(char) - p egy pointer egy olyan fggvnyre, amelyik egy int paramtert vr s visszatr egy pointerrel egy olyan fggvnyre, amelyik char paramtert vr s double-lal tr vissza. Vissza

11.

Feladat

struct konyv { char cim[100]; char szerzo[50]; struct konyv* kov; }; struct konyv* first_konyv = NULL;

void uj_konyv( char* cim, char* szerzo ) { struct konyv* ujk = (struct konyv*)malloc(sizeof(struct konyv)); strcpy(ujk->cim, cim); strcpy(ujk->szerzo, szerzo); // beszuras a lista elejere ujk->kov = first_konyv; first_konyv = ujk; }

Vissza

A segdletet ksztette: Benedek Zoltn, BME Automatizlsi s Alkalmazott Informatikai Tanszk 2003 A feladatokkal kapcsolatos szrevtelekkel, bugokkal Benedek Zoltnt keresstek (benedek.zoltan@aut.bme.hu)

Das könnte Ihnen auch gefallen