You are on page 1of 10

Forrs: http://www.doksi.

hu

Programozs C s C++ -ban

2. Tovbbi klnbsgek a C s C++ kztt


2.1 Igaz s hamis
A C++ programozsi nyelv a C-hez hasonlan definil nhny alap adattpust:
char
int
float
double
Ugyanakkor egy j adattpus is megjelent a C++ -ban az igaz s hamis rtkek
reprezentlsra: bool.
Emlkeztet: C nyelvben egy kifejezs rtke hamis ha nullval egyenl. Minden ms
esetben igaz a kifejezs rtke.
A C++ -ban az igaz rtk a true a hamis a false rtknek felel meg. Mivel
nagyon sok program mg mindig a C konvencit hasznlja, ezrt a fordt az integer
rtket bool tpusv konvertlja. Nzznk egy nagyon egyszer pldt:
#include <iostream>
using namespace std;
int main()
{
bool felt;
int a;
felt = false;
if(felt) // ez hamis lesz
a = 1;
else
a = 2; // ez a rsz hajtdik vgre
cout << a << endl;
return 0;
}

2.2 A typedef kulcssz


A typedef kulcssz C++ -ban is hasznlhat tpusok deklarlsra, de nem
szksges a struct, union s enum defincik esetn. Vegyk a kvetkez
defincit:

Forrs: http://www.doksi.hu

struct valami
{
int
a;
double d;
char
string[80];
};
Ezt a struktrt egyszeren hasznlhatjuk a C++ -ban:
valami what;
what.d = 3.1415;
Ennek a szintaktikai elemnek mg lesz jelentsge az objektum-orientlt programozs
sorn.

2.3 Mutatk, pointerek


Nzznk egy pldt, mely kinyomtatja tbb vltoz s egy fggvny cmt. (Ez azrt
lehetsges, mivel minden program rszlet a memriban van s gy van cme.)
#include <iostream>
using namespace std;
int dog, cat, bird, fish;
void f(int pet)
{
cout << "pet id number: " << pet << endl;
}
int main()
{
int i, j, k;
cout << "f(): " << (long)&f << endl;
cout << "dog: " << (long)&dog << endl;
cout << "cat: " << (long)&cat << endl;
cout << "bird: " << (long)&bird << endl;
cout << "fish: " << (long)&fish << endl;
cout << "i: " << (long)&i << endl;
cout << "j: " << (long)&j << endl;
cout << k: << (long)&k << endl;
return 0;
}
poiner1.cpp
A kiiratsnl a (long) kifejezs egy cast-ols, mely megmondja hogy a vltoznak ne
az eredeti tpust vegye figyelembe, hanem konvertlja long tpusv s csak utna
nyomtassa ki.
Az eredmny a kvetkez lesz:

Forrs: http://www.doksi.hu

f(): 4198875
dog: 4683580
cat: 4683576
bird: 4683588
fish: 4683592
i: 1245052
j: 1245048
k: 1245044
Lthat hogy az egy helyen deklarlt vltozk cme kzel kerl egymshoz.
Br C programozsi nyelvbl ismert, rdemes tismtelni, hogy a fggvnyek kztti
paramter tads rtk szerint trtnik. Ezt mutatja be a kvetkez plda, melynl
lthat, hogy az f fggvnyen belli vltozs nem tkrzdik a main fggvny
vltoziban, hiszen az f fggvny minden vltozja loklis s nem hivatkoznak kls
vltozkra.

#include <iostream>
using namespace std;
void f(int a)
{
cout << "a = " << a << endl;
a = 5;
cout << "a = " << a << endl;
}
int main()
{
int x = 47;
cout << "x = " << x << endl;
f(x);
cout << "x = " << x << endl;
return 0;
}
Ha lefuttatjuk a fenti pldt akkor az eredmny:
x
a
a
x

=
=
=
=

47
47
5
47

Ha azt szeretnnk, hogy az f fggvnyben trtn vltozsok hatssal legyenek a


kls vltozkra, akkor nem rtk, hanem referencia szerinti paramter tadst kell
hasznlni, vagyis mutatkat (pointereket) kell hasznlni. Erre is nzznk egy pldt:

Forrs: http://www.doksi.hu

#include <iostream>
using namespace std;
void f(int *a)
{
cout << "a = " << *a << endl;
*a = 5;
cout << "a = " << *a << endl;
}
int main()
{
int x = 47;
cout << "x = " << x << endl;
f(&x);
cout << "x = " << x << endl;
return 0;
}
Ha lefuttatjuk a fenti pldt akkor az eredmny:
x
a
a
x

=
=
=
=

47
47
5
5

2.4 C++ referencik


A mutatk nagyjbl ugyangy mkdnek C++ alatt is ahogy ezt az elz
bekezdsben lthattuk. Ugyanakkor a C++ bevezette a referencik fogalmt. Br
elvileg referencik nlkl is lehetne dolgozni C++ -ban, de nhny helyen fontos lesz.
A referencik esetben a szintaxis tisztbb lesz, s csak a hvott fggvnynl jelenik
meg, hogy referencia szerinti rtktads trtnik!
#include <iostream>
using namespace std;
void f(int &a)
{
cout << "a = " << a << endl;
// itt kzvetlenl a vltozba runk, nem a cmre !!!
a = 5;
cout << "a = " << a << endl;
}
int main()
{
int x = 47;
cout << "x = " << x << endl;
f(x);

Forrs: http://www.doksi.hu

cout << "x = " << x << endl;


return 0;
}
reference1.cpp
A pldban lthat, hogy ahelyett hogy az f fggvny argumentumt mutatnak
deklarlnnk (int *), referenciaknt deklarljuk (int &). Itt van egy msik fontos
klnbsg is hiszen az f fggvnyen bell az a vltozra hivatkozunk. Ha az a
vltoz egy mutat, akkor a rtke egy memria cm lesz s a fenti rtkads
rvnytelen hiszen ki tudja mi van az 5-s memria cmen melyre az a vltoznak
hivatkoznia kell. Ezzel szemben a fenti pldban az a vltoz manipulcija sorn
egy olyan vltozrol van sz, amelyre az a vltozra referl.
Ezek utn az eredmny:
x
a
a
x

=
=
=
=

47
47
5
5

2.5 A << jelek tbb rtelme


Az albbi plda azt fogja mutatni, hogy a << s >> jeleknek tbb rtelme is van a C++
programozsi nyelvben. (Magyarzattal egy picit ksbb szolglunk.)
#include <iostream>
using namespace std;
void PrintBinary(const unsigned char val)
{
for(int i = 7; i >= 0; i--)
{
if(val & (1 << i))
cout << "1";
else
cout << "0";
}
}
int main()
{
int a;
unsigned char b;
cout << "Adj meg egy 0 es 255 kozotti szamot";
cin >> a;
b = a;
PrintBinary(b);
cout << endl;

Forrs: http://www.doksi.hu

return 0;
}

2.6 C-ben rt fggvnyek hasznlata


Arra is lehetsg van hogy olyan fggvnyeket hasznljunk, melyet valaki a C
programozsi nyelvben rt meg, s egy C fordtval s linkerrel egy knyvtrr
szerkesztett.

2.6.1 A cplusplus makr


Elszr is minden C++ fordt mely kveti az ANSI/ISO szabvnyt definilja a
__cplusplus
szimblumot. Ez lnyegben azt jelenti, mintha minden forrs file legtetejn az albbi
makr definci llna:
#define __cplusplus

2.6.2 A fggvnyek deklarlsa


A C programozsi nyelvben rt fggvnyek esetn (melyet C++ -ban is szeretnnk
hasznlni) deklarlni kell hogy C fggvnyrl van sz, pldul:
extern "C" void *xmalloc(unsigned size);
A deklarci teljesen azonos a C nyelvben megszokott defincival, de el kell rni az
extern "C" kifejezst.
Ha tbb deklarcit szeretnnk egybe fogni, a kvetkez hasznlhat:
extern "C"
{
#include <valami.h>
int *fvg(int a);
}
Br ez a kt mdszer hasznlhat, de van egy ennl elterjedtebb mdszer.

2.6.3 C s C++ include file-ok


Ha a __cplusplus makrt s az extern "C" kifejezst egytt hasznljuk olyan
include, header file-okat hozhatunk ltre melyek hasznlhatk a C s a C++
programozsi nyelvben is. Egy ilyen include file szerkezete a kvetkez szokott lenni:

Forrs: http://www.doksi.hu

#ifdef __cplusplus
extern "C"
{
#endif
// a fggvnyek s vltozk ide jnnek, pldul:
void *xmalloc(unsigned size);
#ifdef __cplusplus
}
#endif
Figyeljk meg, hogy a feltteles fordtsi direktvk segtsgvel hogyan ellenrizzk
hogy C vagy C++ tpus fordtsra van-e szksg. A szabvnyos include file-ok,
pldul az stdio.h is ilyen mdon van megszerkesztve s ezrt hasznlhat mind a
kt nyelvben!

2.7 Fggvny definils C++ -ban


Az emberi kommunikciban egy sznak gyakran tbb jelentse van. Ugyanakkor a
programozsi nyelvekben egy fggvnynek vagy tevkenysgnek nevet kell adni, s
csak egy neve lehet. Ez sajnos problmhoz vezethet. Pldul ha hrom klnbz
tpus vltoznk van s ezeket ki akarjuk nyomtatni ltalunk definilt fggvnyekkel,
akkor hrom klnbz fggvnyt kell deklarlni a C nyelvben, pldul:
print_int, print_char, print_double. Ugyanakkor mind a hrom
fggvny ugyanazt csinlja ezrt szeretnnk elkerlni, hogy hrom fggvny nevet
kelljen megjegyezni s azt szeretnnk, hogy csak egy fggvny nevet kelljen
megjegyezni.
Ennek a problmnak a megoldsra vezettk be a function overloading, fggvny
overloading lehetsgt a C++ -ban. (A kifejezst szoktk fggvny tlterhelsnek is
fordtani, de szerintem ez nem teljesen fedi a jelentst. Ezrt inkbb az overloading
angol szt fogom hasznlni, mint magyar kifejezst.) Az overloading ltalnosan azt
jelenti, hogy az adatokon valamilyen operci vgrehajtst vgz szimblumhoz
(pldul fggvnyazonosthoz, opertorhoz) tbb, klnbz tpusra vonatkoz
klnbz jelentst rendelnk. (Ezt a mondatot olvassuk el tbbszr is s prbljuk
meg megrteni!) Hogy egy adott adathoz egy mvelet milyen rtelmezse tartozik, az
az adott adat tpustl, vagy pontosabban a fogalmazva az adott fggvny paramter
szignatrjtl fgg. A paramter szignatra itt azt jelenti, hogy egy fggvnynek
mennyi s milyen tpus paramtere van, illetve a paramterek milyen sorrendben
kvetik egymst. Teht attl fggen, hogy egy fggvnyt milyen tpus
paramterekkel aktivizlunk, mindig az
aktulis paramterekkel megegyez
szignatrj fggvnyvltozat hvsnak megfelel kdot generl a C++ fordt.
Ebbl is taln lthat, hogy az overloading nem tdefinilst jelent, hiszen amikor az
overloading ltal egy szimblumhoz egy jabb jelentst rendelnk az eredeti
jelentsek nem vesznek el.

Forrs: http://www.doksi.hu

Nzzk a fenti problmt C++ -ban:


#include <stdio.h>
void show(int val)
{
printf("Integer: %d\n", val);
}
void show(double val)
{
printf("Double: %lf\n", val);
}
void show(char *val)
{
printf("String: %s\n", val);
}
int main()
{
show(12);
show(3.1415);
show("Hello World\n!");
}
A fenit kdrszletben hrom darab show fggvny van melyek csak a
paramtereikben vagy argumentumaikban klnbznek. Fontos megjegyezni, hogy
br a forrskdban azonos nevek szerepelnek, de amikor a C++ fordt dolgozik
ezekkel a fggvnyekkel, akkor teljesen ms neveket kapnak a fordts s linkels
idejre. Azt a folyamatot amely a forrs file-ban szerepl nevet belsleg hasznlatos
nvv konvertlja name mangling-nek szoktuk nevezni. Pldul a C++ fordt a
fenti pldban a void show(int) fggvnynek a @@showI nevet adja, mg a
void show(char *) fggvnynek a @@showCP nevet. (A klnbz C++
fordtk klnbz name mangling eljrst alkalmaznak, de mindegyik valamilyen
mdon belekdolja a nvbe a paramter lista tipusait.) Ezek a bels nevek nem
klnsebben fontosak a programoz szempontjbl, de azrt fontosak lehetnek
pldul ha egy C++ -os fggvny knyvtr tartalmt listzzuk ki.

2.7.1 Megjegyzsek

Ne hasznljuk a fggvny tdefinilst abban az esetben ha kt fggvny teljesen


klnbz dolgokat csinl. A fenti pldban a klnbz show fggvnyek
nagyon hasonlak voltak.
A C++ azt nem engedi meg hogy kt fggvny csak a visszatrsi rtk tpusban
klnbzzn! Ennek az oka a kvetkez, pldul:
printf(Hello World\n);

Forrs: http://www.doksi.hu

A fenti kdrszlet semmilyen informcit nem ad a visszatrsi rtkrl, hiszen a


programoznak nem ktelez figyelembe vennie a visszatrsi rtket. gy ha kt
printf fggvny ltezik, melyek csak a visszatrsi rtkkben klnbznek, a
fordt nem tudn eldnteni hogy melyiket kell hasznlni.
A fggvny overloading nha meglephet bennnket. Pldul a fenti plda esetn
ha az albbi fggvny hvst hasznljuk
show(0);
akkor melyik fggvny hvdik? A nulla lehet egsz szm, vals szm s a NULL
pointernek is megfelel. Ebben az esetben az egsz szmot nyomtat fggvnyt
hvja meg a C++, de lehet hogy nem ezt vrtuk, vagy nem ezt akartuk.

2.8 Alap fggvny argumentumok


A C++ nyelvben a fggvny overloading-on kvl van mg egy lehetsg mellyel
azonos nev, de klnbz argumentum szm fggvnyt lehet hasznlni. Ez a
lehetsg az, hogy a fggvnyeknek lehet alap argumentuma. Az alap
argumentumot gy lehet megadni, hogy az argumentum alaprtkt a
fggvnydeklarciban megadjuk.
Pldul:
#include <stdio.h>
void showstring(char *str = "Hello World!\n");
int main()
{
showstring("Ez egy explicit argumentum.\n");
showstring();

// valjban ez:
// showstring("Hello World!\n");

}
Ez a lehetsg, hogy bizonyos argumentumokat nem kell megadni a C++ fordt egy
knyelmi szolgltatsa, ettl a kd nem lesz rvidebb s nem lesz hatkonyabb.
Termszetesen egy fggvnynek tbb alap argumentuma is lehet:
void two_ints(int a = 1, int b = 4);
int main()
{
two_ints();
two_ints(20);
two_ints(20, 5);
}

// argumentumok: 1, 4
// argumentumok: 20, 4
// argumentumok: 20, 5

Forrs: http://www.doksi.hu

Amikor a two_ints fggvnyt hasznljuk, akkor a fordt nulla, egy vagy kt


argumentumot ad meg, attl fggen hnyat nem adott meg a programoz. Fontos
viszont, hogy a
two_ints(,6)
kifejezs hibs, argumentumot elhagyni csak a jobb oldalrl lehet!
Az alap argumentumokrl a C++ fordtnak tudnia kell, ezrt ltalban a fggvny
deklarcinl szoktuk megadni ket. Pldul az include file tartalma:
// az include file
extern void two_ints(int a = 1, int b = 4);
s a hozztartoz implementci:
void two_ints(int a, int b)
{
...
}

You might also like