You are on page 1of 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

int

int

t ennek a cme

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

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]);

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.

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

int

int

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


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.

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

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

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.

int

int

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

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

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

tudni

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

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)

You might also like