Professional Documents
Culture Documents
„Egy új programozási nyelv elsajátításának egyetlen útja, hogy az adott nyelven programokat írjunk.”
Tartalomjegyzék
1. Alapismeretek.......................................................................................................................................4
1.1. Változók, adattípusok és méretek.................................................................................................4
1.1.1. Regiszterváltozók..................................................................................................................4
1.2. Állandók.......................................................................................................................................5
1.2.1. Szimbolikus állandók............................................................................................................5
1.2.2. Felsorolt állandók..................................................................................................................5
1.3. Tömbök.........................................................................................................................................5
1.4. A változók érvényességi tartománya és a külső változók............................................................5
1.4.1. Az érvényességi tartomány szabályai...................................................................................5
1.4.2. Statikus változók...................................................................................................................6
1.5. Típuskonverziók...........................................................................................................................6
1.6. Inkrementáló és dekrementáló operátorok...................................................................................6
1.7. Bitenkénti logikai operátorok.......................................................................................................7
1.7.1. Igazságtáblázatok..................................................................................................................7
1.8. Értékadó operátorok és kifejezések..............................................................................................7
1.9. Feltételes kifejezések....................................................................................................................8
1.10. A precedencia és a kifejezés kiértékelési sorrendje....................................................................8
1.11. A switch utasítás.........................................................................................................................9
1.12. Feladatok..................................................................................................................................10
1.12.1. Betű számolása..................................................................................................................10
1.12.2. Szavak számlálása.............................................................................................................10
1.12.3. Szökőév.............................................................................................................................10
1.12.4. Számjegyek összege..........................................................................................................10
1.12.5. Legkisebb közös többszörös.............................................................................................10
1.12.6. Konvertálás kettes számrendszerbe..................................................................................10
1.12.7. Konvertálás 16-os számrendszerbe...................................................................................10
1.12.8. Átlagszámítás....................................................................................................................10
2. Függvények........................................................................................................................................11
2.1. A függvényekkel kapcsolatos alapfogalmak..............................................................................11
2.2. A header állományok..................................................................................................................11
2.3. Rekurzió......................................................................................................................................11
2.4. A C előfeldolgozó rendszer........................................................................................................12
2.4.1. Állományok beépítése.........................................................................................................12
2.4.2. Makróhelyettesítés..............................................................................................................12
2.4.3. Feltételes fordítás................................................................................................................13
2.5. Feladatok....................................................................................................................................13
2.5.1. Faktoriális...........................................................................................................................13
2.5.2. Legkisebb közös többszörös...............................................................................................13
2.5.3. Vektor rendezése.................................................................................................................14
2.5.4. Bitműveletek.......................................................................................................................14
3. Mutatók és tömbök.............................................................................................................................15
3.1. Mutatók és címek........................................................................................................................15
2
3.2. Mutatók és függvényargumentumok..........................................................................................16
3.3. Mutatótömbök és mutatókat megcímző mutatók.......................................................................16
3.4. Függvényeket megcímző mutatók..............................................................................................16
3.5. Feladatok....................................................................................................................................16
3.5.1. Lowercase...........................................................................................................................16
3.5.2. N karakter másolása............................................................................................................16
3.5.3. Szöveg keresése szövegben................................................................................................17
3.5.4. Szám konvertálása szövegé.................................................................................................17
3.5.5. Szöveg konvertálása számmá.............................................................................................17
3.5.6. Vektorok rendezés..............................................................................................................17
3.5.7. strpbrk.................................................................................................................................17
3.5.8. strtok...................................................................................................................................17
4. Struktúrák...........................................................................................................................................18
4.1. Alapfogalmak.............................................................................................................................18
4.2. Struktúrák és függvények...........................................................................................................19
4.3. Önhivatkozó struktúrák..............................................................................................................19
4.4. A typedef utasítás.......................................................................................................................19
4.5. Unionok......................................................................................................................................20
4.6. Bitmezők.....................................................................................................................................20
4.7. Feladatok....................................................................................................................................20
4.7.1. Adatkezelés.........................................................................................................................20
4.7.2. Menükezelés erőforrás alapján...........................................................................................20
3
1. Alapismeretek
Adattípusok, és mérteik:
char karakter, egy byte-on ábrázolva, értelmezési tartománya: -128 .. 127
unsigned char előjel nélküli karakter típus, értelmezési tartománya: 0 .. 255
short rövid egész típusú szám, értelmezési tartománya: -32768 .. 32767
unsigned short előjel nélküli rövid egész típusú szám, értelmezési tartománya: 0 .. 65535
int egész típusú szám, értelmezési tartománya: -2147483648 .. 2147483647
unsigned int előjel nélküli egész típus, értelmezési tartománya: 0 .. 4294967295
long hosszú egész típus, értelmezési tartománya: -2147483648 .. 2147483647
unsigned int előjel nélküli hosszú egész típus, értelmezési tartománya: 0 .. 4294967295
float egyszeres pontosságú lebegőpontos (valós) szám
double kétszeres pontosságú lebegőpontos (valós) szám
Az int és a float típusú változók pontossága és lehetséges nagysága a használt számítógéptől függ.
A változók deklaráció során kezdeti értéket is kaphatnak. Ha a változó nem automatikus, akkor a
kezdeti értékadás csak egyszer a program végrehajtásának a kezdetén történik meg, és a kezdő értéket
megadó kifejezésnek állandó értéknek kell lenni. Az automatikus változók kezdeti értéke határozatlan,
hacsak explicit módon nem kapnak értéket.
Bármely változó deklarációjában alkalmazható a const minősítő, ami azt jelzi, hogy a változó
értékét nem fogjuk megváltoztatni, pl.:
const char uzenet[] = „Hello world!”;
1.1.1. Regiszterváltozók
A register deklaráció azt tudatja a fordítóprogrammal, hogy az így deklarált változót nagyon
gyakran fogjuk használni. A register deklarálású változót a számítógép regiszterébe helyezzük, ami
kisebb méretű és gyorsabb programot eredményez. A fordítóprogramnak lehetősége van figyelmen
kívül hagyni a deklarációt.
pl.: register int i;
Csak bizonyos típusú változók lehetnek regiszter változók, és csak néhány változó lehet az. A
felesleges register deklarációk nem okoznak problémát, mivel a felesleges számú, vagy nem
megengedett típusú változók deklarálásából a register szó törlődik. További megszorítás, hogy nem
hivatkozhatunk a regiszterváltozó címére.
4
1.2. Állandók
1.3. Tömbök
Az
int ndigit[10];
deklaráció a 10 egész számot tartalmazó ndigit tömböt deklarálja. A tömb méretének már fordításkor
ismertnek kell lennie, mert a fordító csak így képes meghatározni a tömb tárolásához szükséges
memóriaterület nagyságát.
A C nyelvben a tömök indexe mindig nulláról indul. Az index tetszőleges egész típus lehet.
5
paramétereire is, mivel ezek valójában helyi változók.
A külső változók vagy függvények érvényességi tartománya a deklaráció helyén kezdődik, és az
éppen fordított forrásállomány végéig tart. Ha egy külső változóra a definiálása előtt hivatkozunk,
vagy más forrásállományban definiáltuk, mint ahol használjuk, akkor kötelező az extern deklaráció.
Fontos, hogy megkülönböztessük a külső változók deklarálását és definiálását. A deklaráció a
változó tulajdonságait (elsősorban a típusát) írja le, a definíció viszont ezenkívül még tárterületet is
rendel hozzá.
A külső változókat csak a forrásállományok egyikében kell definiálni, a többi állományban csak
extern deklaráció van, amelyen keresztül ezek a változók elérhetők.
A külső változók inicializálása csak a definícióval együtt történhet.
1.5. Típuskonverziók
Ha egy operátor operandusai különböző típusúak, akkor a művelet végrehajtása előtt azokat egy
közös típusra kell hozni. Az automatikus konverzió csak akkor jön létre, ha egy kevesebb operandust
egy szélesebb operandussá kell alakítani, mivel így biztosan nem vész el információ. Ha egy hosszabb
egész típust egy rövidebbhez, vagy egy lebegőpontos típust egy egészhez rendelünk, akkor információ
veszhet el, ezért figyelmeztető jelzést kapunk, de maga a művelet nem tilos.
Az értékadás is típuskonverzióval jár: a jobb oldal értéke a bal oldal típusának megfelelő típusává
alakul, és ez lesz az eredmény típusa is.
Tetszőleges kifejezésben kikényszeríthetjük az explicit típuskonverziót a rögzítő (cast) unáris
típusmódosító operátorral. Az így kialakított szerkezet:
(típusnév)kifejezés
alakú, és hatására a kifejezés típusnévvel megadott típusúvá konvertálódik.
1.7.1. Igazságtáblázatok
7
alakkal. A tömörebb forma előnye, hogy a gép a k1 kifejezést csak egyszer számolja ki. Összetett
kifejezések esetén ügyeljünk a zárójelezésre. Például az
x *= y + 1;
alak az
x = x * (y + 1);
kifejezésnek felel meg, és nem az
x = x * y + 1;
kifejezésnek.
A tömörségen túl az értékadó operátorok alkalmazásának további előnye, hogy jobban megfelel az
emberi gondolkodásnak, és a fordító programot is segítik a hatékony kód előállításában.
8
Operátor Asszociativitás
() [] → balról jobbra
! ~ ++ -- + - * & (típus) sizeof jobbról balra
* / % balról jobbra
+ - balról jobbra
<< >> balról jobbra
< <= > >= balról jobbra
= = != balról jobbra
& balról jobbra
^ balról jobbra
| balról jobbra
&& balról jobbra
|| balról jobbra
?: jobbról balra
= += -= *= /= %= &= ^= |= <<= >>= jobbról balra
9
1.12. Feladatok
1.12.3. Szökőév
Írjunk programot, amely eldönti egy megadott évszámról, hogy szökőév-e. Szökőév meghatározása:
minden néggyel osztható év, kivéve a százzal is oszthatókat. Szökőévek viszont a 400-zal osztható
évek. Vagyis a százasra végződő évek közül csak azok szökőévek, amelyek 400-zal is oszthatók.
1.12.8. Átlagszámítás
Írjunk programot, mely beolvassa egy tanuló jegyeit, majd kiszámítja az átlagot. A jegyeket
tömbben tárolja. A beolvasásnál csak a jó osztályzatokat fogadja el. A tantárgyak száma 10. Az átlag
kiszámítása után adjuk meg azt is, hogy az egyes osztályzatok hányszor fordultak elő!
10
2. Függvények
A függvényekkel a nagyobb számítási feladatok kisebb egységekre oszthatók, így a programozó
felhasználhatja a már meglévő egységeket, és nem kell minden alkalommal elölről kezdeni a munkát.
2.3. Rekurzió
A C nyelv függvényei rekurzívan használhatók: egy függvény közvetlenül vagy közvetetten
hívhatja saját magát. Amikor egy függvény rekurzívan hívja magát, minden híváskor az automatikus
változók új készletével kezdi a munkát. Ez az új változókészlet teljesen független a korábbi
hívásokkor keletkező készletektől.
Egy egyszerű példa:
11
long nfakt(long n)
{
if( n > 1 )
return n*nfakt(n-1);
return 1;
}
2.4.2. Makróhelyettesítés
Egy definició általánosan
#define név helyettesítő szöveg
alakú, és hatására a makróhelyettesítés egyik legegyszerűbb formája indul el: a névvel megadott
kulcsszó minden előfordulási helyére beíródik a helyettesítő szöveg. A #define utasításban szereplő
névre ugyanazok a szabályok érvényesek, mint a változók neveire, a helyettesítő szöveg pedig
tetszőleges lehet. A hosszú definíciók több sorban is folytathatók, ha az egyes sorok végére a \ jelet
írjuk. A #define utasítással definiált név érvényességi tartománya a definíció helyétől az éppen
fordított állomány végéig terjed. Egy definícióban felhasználhatunk korábbi definíciókat is.
Lehetőség van argumentumot tartalmazó makrók definiálására is, így a helyettesítő szöveg a
különböző makróhívásoknál más és más lesz. Példaként definiáljuk a max nevű makrót a következő
módon:
#define max(A, B) ((A) > (B) ? (A) : (B))
Ez a sor hasonlít egy függvényhíváshoz, de nem az, hanem a max makrósoron belüli kifejezése,
amelyben a formális paraméter a megfelelő aktuális argumentummal lesz helyettesítve. Így az a
programsor, hogy
12
x = max(p+q, r + s);
azzal a sorral helyettesítődik, hogy
x = ((p+q) > (r+s) ? (p+q) : (r+s);
Mindaddig, amíg az argumentumokat következetesen kezeljük, a makró bármilyen adattípus esetén
helyes eredményt fog adni.
Ha jól megfigyeljük a max makró kifejezést, akkor észrevehetünk benne egy csapdát. A kifejezést
kétszer értékeli ki, ami inkrementáló – dekrementáló operátorok, vagy adatbevitel és adatkivitel esetén
hibát (mellékhatást) okoz. Például a
x = max(i++, j++); //hibás!!
sorban a kifejezés hatására a nagyobbik argumentum kétszer inkrementálódik. Ügyelnünk kell a
zárójelek használatára is, mert megváltozhat a végrehajtási sorrend. Nézzük meg mi történik, amikor a
#define square(x) x * x //hibás!!
makrót square(z + 1) alakban hívjuk! A kifejezés után a kifejezésben az x helyére z + 1 kerül, így a
kifejezés z + 1 * z + 1 lesz, ami nyilvánvalóan hibás.
A nevek korábbi definíciója megszüntethető az #undef paranccsal.
2.5. Feladatok
2.5.1. Faktoriális
Írjuk meg a faktoriális számláló függvényt rekurzió nélkül.
13
2.5.3. Vektor rendezése
Írjunk programot, mely feltölt egy 100 elemű vektort 1 és 1000 közé eső egész számokkal, majd a
következő feladatokat látja el (minden egyes feladatot külön függvényben írjunk meg, a 100 elemű
vektor lehet globális):
• kiszámítja az elemek összegét, átlagát
• kiválasztja a legnagyobbat és a legkisebbet
• kiírja az elemeket eredeti sorrendben, majd rendezi és úgy is megjeleníti azokat
2.5.4. Bitműveletek
– Írjunk függvényt, amely a paraméterként megadott egész szám x-edik bit-jéről eldönt, hogy 0
vagy 1.
– Írjunk függvényt, amely a paraméterként megadott egész szám x-edik bit-jét 1 – re állítja.
– Írjunk függvényt, amely a paraméterként megadott egész szám x-edik bit-jét 0 – ra állítja.
– Írjunk függvényt, amely a paraméterként megadott egész szám x-edik bit-jét billegteti.
– Írjunk függvényt, amely a paraméterként megadott n-től m bit-ig lemaszkolja a számot, és
visszatér a maszkolás eredményével.
14
3. Mutatók és tömbök
A mutató vagy pointer olyan változó, amely egy másik változó címét tartalmazza. A C nyelvű
programokban gyakran használják a mutatókat, egyrészt mert bizonyos feladatokat csak velük lehet
megoldani, másrészt mert alkalmazásukkal sokkal tömörebb és hatékonyabb program hozható létre.
p: c:
15
(*ip)++;
Az utolsó esetben a zárójelre szükség van, mert hiányában az ip inkrementálódna az ip által kijelölt
adat helyett, mivel a *-hoz és ++-hoz hasonló unáris operátorok jobbról balra hajtódnak végre.
int a = 2, b = 4;
swap(&a, &b); //swap függvény hívása
3.5. Feladatok
3.5.1. Lowercase
Írjunk függvényt amely a paramétereként kapott szöveg összes betűjét kisbetűvé alakítja.
16
3.5.3. Szöveg keresése szövegben
Írjuk meg a C könyvtárban szereplő strstr függvényt.
3.5.7. strpbrk
Írjuk meg a C alapkönyvtárban megtalálható strpbrk függvényt.
3.5.8. strtok
Írjuk meg egy külön file-ba a C alapkönyvtárban megtalálható strtok függvényt, majd segítségével
írjuk át az 1.12.2-es feladatot.
17
4. Struktúrák
A struktúra egy vagy több, esetleg különböző típusú változó együttese, amelyet a kényelmes
kezelhetőség céljából önálló névvel látunk el. Néhány nyelvben az így értelmezett struktúrát
rekordnak nevezik. A struktúra bevezetése segíti az összetett adathalmazok szervezését, ami
különösen nagy programok esetén előnyös, mivel lehetővé teszi, hogy az egymással kapcsolatban lévő
változók egy csoportját egyetlen egységként kezeljük.
A struktúrák átmásolhatók egymásba, értékül adhatók más struktúráknak, átadhatók függvénynek,
és a függvények visszatérési értékei is lehetnek.
4.1. Alapfogalmak
struct pont {
int x;
int y;
};
A struktúra deklarációját a struct kulcsszó vezeti be, amelyek kapcsos zárójelek között a
deklarációk listája követ. A struct kulcsszót opcionálisan egy név, az ún. struktúracímke követheti. Ez
a címke vagy név azonosítja a struktúrát, és a későbbiekben egy rövidítésként használható a kapcsos
zárójelek közötti deklarációs lista helyett.
A struktúrában felsorolt változóneveket a struktúra tagjainak nevezzük. Egy struktúra címkéje, ill.
egy tagjának a neve és egy közönséges változó neve lehet azonos.
Egy strukt deklaráció egy típust is definiál. A jobb oldali, záró kapcsos zárójel után következhet a
változók listája, hasonlóan az alapadattípusok megadásához.
Zaz olyan struktúra deklaráció, amely nem követ a változók listája, nem foglal helyet a tárolóban,
csak a struktúra alakját írja le. Ha a struktúra címkézett volt, akkor a címke a későbbi definíciókban a
struktúra konkrét előfordulása helyett használható. Például felhasználva a pont korábbi deklarációját a
struct pont pt;
definíció egy pt változót definiál, ami a struct pont-nak megfelelő típusú struktúra.
Egy struktúra úgy inicializálható, hogy a definíciót az egyes tagok kezdeti értékének listája követi.
A kezdeti értékeknek állandó kifejezéseknek kell lenni, például:
struct pont maxpt = {1024, 768};
Egy kifejezésben, az adott struktúra egy tagjára úgy hivatkozhatunk, hogy
struktúra-név.tag
A pont struktúratag operátor összekapcsolja a struktúra és a tag nevét. A pt pont koordinátái pl. úgy
írhatjuk ki, hogy:
printf(„%d, %d”, pt.x, pt.y);
A struktúrák egymásba ágyazhatók, például:
struct tegla {
struct pont pt1;
struct pont pt2;
};
Ennek alapján a tegla struktúra két pont struktúrából áll.
18
4.2. Struktúrák és függvények
A struktúrák esetén megengedett művelet a struktúra másolása vagy értékadása, ill. a struktúra
címéhez való hozzáférés az & operátorral, és a struktúra tagjaihoz való hozzáférés. Ezek a műveletek
a struktúrát egy egységként kezelik, és a másolás, vagy értékadás magában foglalja a struktúrák
függvényargumentumkénti átadását, ill. a struktúra típusú függvényvisszatérés lehetőségét is. A
struktúrák egy egységként nem hasonlíthatók össze.
Ha nagy struktúrát kell átadnunk egy függvénynek, akkor sokkal hatékonyabb, ha a struktúra
mutatóját adjuk át, és nem pedig a teljes struktúrát másoljuk át. A struktúra mutatójának deklarációja:
struct pont *pp;
Ez egy struct pont típusú struktúrát kijelölő mutatót hoz létre. Ha pp egy pont struktúrát címez, akkor
pp maga a struktúra, és (*pp).x, ill. (*pp).y pedig a struktúra tagjai. A zárójelre szükség van, mert a .
struktúratag operátor precedenciája nagyobb, mint a * operátoré.
A struktúrák mutatóit gyakran használjuk egy rövidített jelölési formában. Ha p egy struktúra
mutatója, akkor a
p->struktúratag
kifejezés közvetlenül a struktúra megadott tagját címzi.
4.4. Unionok
Az union egy olyan változó, amely különböző időpontokban különböző típusú és méretű
objektumokat tartalmazhat, úgy, hogy a fordítóprogram ügyel az objektumok méretére, és tárbeli
elhelyezésére vonatkozó előírások betartására. A union-ok alkalmazásával lehetővé válik, hogy
azonos tárterületen különböző fajta adatokkal dolgozzunk, anélkül, hogy a programba géptől függő
információkat kellene beépíteni.
4.5. Bitmezők
4.6. Feladatok
4.6.1. Adatkezelés
Írjunk programot, mely egy dinamikus listába emberek adatait viszi föl. Azonosító, név, születési
év, lakcím. Majd valósítsuk meg menüből a következő funkciókat:
• egy adat felvitele a listába
• egy adat törlése a listából
• keresés név alapján (egyedi jellemző)
• keresés születési év alapján (több egyforma is lehet, mindet adja meg)
• teljes lista
20