Beruflich Dokumente
Kultur Dokumente
hu
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
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
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
Megoldsok
Megolds
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.
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
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;
Forrs: http://www.doksi.hu
int
int
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.
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
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
t ezt a tmbt jelenti (els elem cme) int int int int int int
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.
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)