Info 2, 1. heti előadás: bevezetés

Utolsó módosítás: 2009. február 12.

Nézet: lényeg vagy minden

A C programozási nyelv, áttekintés

Kezdjük az egyik leghíresebb C nyelvű programmal (kissé megváltoztatva).

#include <stdio.h>

int
main(void) {
	printf("hello, world\n");
	return 0;
}

Ez a program semmi hasznosat nem csinál, csak kiír egy üzenetet.

Ezt a programot éppen a K&R könyv első kiadása tette híressé.

Hogyan használjuk ezt a programot? A fenti C nyelvű forráskódot egyszerűen írjuk be egy .c kiterjesztésű fájlba egy szövegszerkesztő programmal (vagy ebben az esetben csak töltsük le). Legyen ez mondjuk a hello.c.

Most a C fordítót fogjuk meghívni, hogy a forrásból futtatható (bináris) fájlt hozzunk létre. Tegyük föl, hogy a parancssorban a cd paranccsal már kurrenssé tettük azt a könyvtárat, amiben a forrásfájl van. Most írjuk be ezt a parancsot.

gcc -Wall -O -o hello hello.c

A fordító parancssorából a gcc a fordítóprogram neve (Gnu compiler collection), a -o hello azt adja meg, hogy a kimenet fájl neve hello legyen, a -Wall -O pedig megkéri a fordítót, hogy bizonyos (nem végzetes) hibákra felhívja a figyelmünket.

Ha a fordítás sikeres, akkor a hello nevű futtatható program létrejön az aktuális könyvtárban, ezt (akár többször is) futtathatjuk a ./hello paranccsal. Ha ezt megtesszük, kimenetként a következő üzenetet kapjuk.

hello, world

Most vizsgáljuk meg újra a programot!

A programban a következő szerkezetet látjuk.

int
main(void) {
        ...
}

Itt jegyzem meg, hogy a C forrásban az üres karaktereknek (szóközök, újsor jelek, tabulátor jel) többnyire nincsen sok jelentése, ezekkel szabadon lehet tagolni – olvashatóbbá tenni – a forrást. Természetesen szó közepén nem szabad üres helyet hagyni, és két szomszédos szót (mint pl int main) legalább egy szóközzel el kell választani, ha nincs köztük semmilyen írásjel. Ritkán előfordul, hogy két szomszédos jel közé is kell szóköz; továbbá van egy olyan eleme a szintaxisnak (preprocesszor direktívák), ahol az újsornak és szóközöknek a szokásosnál egy kicsit több jelentése van.

Ez létrehozza (definiálja) a main nevű függvényt. Egy C program nagyrészt függvény-definíciókra tagolódik, általában sok rövid függvényre.

Egy függvény valamilyen tevékenységet ír le, amit akár többször is végre lehet hajtani. A függvényre a nevével lehet hivatkozni, így a programban több helyről is meghívhatjuk. Így aztán a függvények az absztrakció eszközei, mivel egy bonyolultabb tevékenységet egy rövidebb névvel jelölhetünk vele. (Ne keverjük össze a C függvényeket a matematikai függvényekkel!)

A main nevű függvénynek különleges jelentése van, mivel a program futtatásakor a C környezet ezt hívja meg, és ez hívhat meg aztán más függvényeket.

A C függvények definiálásával részletesebben csak később fogunk foglalkozni, így ezen az előadáson csak olyan rövid programokat nézünk, amik egyetlen main függvényből állnak.

Most nézzük a függvény törzsét. Ez a kapcsos zárójelek közti rész, és ez hajtódik végre, amikor a függvényt meghívjuk.

	printf("hello, world\n");

A printf egy függvény neve. Ez a függvény a szabványos C könyvtár része, vagyis minden C környezetnek része.

A C nyelvben a függvényhívások úgy néznek ki, hogy a függvény neve után zárójelben a függvény argumentumait soroljuk fel vesszővel elválasztva. A függvény ekkor megkapja az argumentumok értékét, és úgy használja őket, ahogy akarja.

A törzsben van még egy ilyen utasítás is.

	return 0;

A return utasítás befejezi a függvény futását, és meghatározza a függvény visszatérési értékét. A visszatérési értéket a függvényt meghívó másik függvény felhasználhatja. (Mi a printf hívásánál nem használjuk fel annak visszatérési értékét.) A C környezet a main függvény visszatérési értékét a program exit kódjának használja.

Nem szóltunk még erről a sorról.

#include <stdio.h>

A C típusos nyelv, ami azt jelenti, hogy a változóknak és függvényeknek típusuk van, ami megadja, hogy kell őket felhasználni. A könyvtári függvények típusát fejlécállományok adják meg, egy ilyen fejlécet a #include direktívával lehet hozzácsapni a forrásunkhoz. A printf könyvtári függvény (és még több másik függvény) deklarációja az stdio.h fejállományban szerepel, így ezt kell betöltenünk, hogy a printf-et használhassuk.

Nézzünk most egy kicsit hosszabb programot is.

#include <stdio.h>

int
main(void) {
	int n;
	n = 19;
	while (1 < n) {
		printf("%d\n", n);
		if (0 == n % 2)
			n = n / 2;	
		else
			n = 3 * n + 1;
	}
	return 0;
}

Ebben már megfigyelhetjük, hogy a függvény törzse deklarációkbók és utasításokból áll. Az egyszerű utasítás egy kifejezésből és egy lezáró pontosvesszőből áll. Az összetett utasítások, mint az if vagy while vagy a kapcsoszárójeles blokk, másik utasításokat tartalmazhatnak.

A kifejezések (egyszerűen szólva) változókból, konstansokból, és az őket összekötő operátorokból és függvényhívásokból áll.