A C fordító
A C fordító¶
A C fordító tehát tulajdonképpen már egy preprocesszált fájlt kap, ami tisztán C nyelvi elemekből áll, és tartalmaz minden deklarációt ahhoz, hogy önmagában le lehessen fordítani.
A fordítás gcc
esetében nem közvetlenül gépi kódra, hanem assembly nyelvre történik.
Optimalizálás¶
A C fordító nem csak "szó szerint" tudja lefordítani a C programot, hanem különféle optimalizálások elvégzésére is képes. Azaz ugyanabból a forrásállományból különböző binárisok keletkezhetnek, attól függően, hogy mik a szándékaink azzal. A lefordított, de különböző módon optimalizált programok viselkedésben megegyeznek, de egyéb tulajdonságaikban eltérnek.
Egy beágyazott rendszerben, ahol az erőforrások korlátozottak, nyilván egy olyan bináris előállítása lehet célszerű, amely kevesebb tárterületet foglal. Ugyanakkor egy sok számítást végző program esetében talán a futásidő a lényegesebb jellemző, amely idő alatt a program a kívánt eredményt meghatározza.
A gcc
fordítónak a -O
kapcsolóval tudjuk megmondani, hogy milyen optimalizálásokat alkalmazzon.
-O0
- nincs optimalizálás: A C forrás minden egyes művelete le lesz fordítva assemblyre, még akkor is, ha az nyilvánvalóan felesleges. Ez általában nagyon nagy és lassú gépi kódot eredményez, viszont hibakeresésnél igen hasznos, hiszen minden egyes gépi kódú utasításról egyértelműen megmondható, hogy az eredetileg melyik C-beli művelethez tartozott.-O1
- alapvető optimalizálás: A C fordító elvégzi azokat az optimalizálásokat amik mind a méretet, mind a futási időt csökkentik, de a fordítási időt nem növelik meg jelentős mértékben.-O2
- optimalizálás méretre és futásidőre: A C fordító elvégzi azokat az optimalizálásokat amik sem a méretre, sem a futásidőre nincsenek jelentős negatív hatással.-O3
- optimalizálás futásidőre: A C fordító elvégzi azokat a futásidőre optimalizáló algoritmusokat is, amik jelentősen növelhetik a kód méretét.-Ofast
- aggresszív optimalizás sebességre: A C fordító azO3
-as optimalizálásokon felül a standardoknak nem megfelelő átalakításokat is elvégez.-Os
- méretre optimalizálás: A C fordító azo2
-es optimalizálások közül kihagyja azokat amelyek tipikusan méretet növelnek, de elvégez olyan plusz átalakításokat amik csökkentik a kód méretét, tekintet nélkül a futási időre gyakorolt hatásuktól.-Og
- optimalizálás debuggolásra: A C fordító azokat az átalakításokat végzi csak el, amikkel a program még szépen debuggolható marad.
A C kulcsszavai¶
Egy adott nyelv kulcsszavai azok, amik segítenek abban, hogy a program szemantikáját kialakítsuk, így ismétlésképp nézzük meg, milyen kulcsszavakat ismertünk meg a C esetében, illetve ezek a kulcsszavak mit eredményeznek.
Típusok¶
Kulcsszó | Leírás |
---|---|
char |
Karakter típus, 1 bájt = 8 bit. |
int |
Egész típus, 4 bájt = 32 bit (32 és valószínűleg 64 bites rendszereken is). |
float |
Valós típus, 4 bájt = 32 bit. |
double |
Valós típus, 8 bájt = 64 bit. |
Típusmódosítók¶
Kulcsszó | Leírás |
---|---|
long |
"hosszú" - a típus értéktartományának bővítése: long int , long long int , long double |
short |
"rövid" - a típus értéktartományának szűkítése: short int |
signed |
"előjeles" - negatív és pozitív értékek tárolása: signed char , signed ... int |
unsigned |
"előjeltelen" - csak nemnegatív értékek tárolására: unsigned char , unsigned ... int |
Típusképzések¶
Kulcsszó | Leírás |
---|---|
enum |
Felsorolás típus: a típus értékhalmazát a programozó adja meg. A fordító a típust végső soron int -ként, az értékhalmaz elemeit konstans azonosítóként kezeli, de a program olvashatóságát jelentősen javíthatja a használata. |
struct |
Szorzat rekord típus: több akár különböző típusú érték egységben kezelése. A típus egyes mezői egyszerre tárolnak értékeket. |
union |
Egyesített rekord típus: több akár különböző típusú érték egységben kezelése. A típus egyes mezői közül egyidejűleg csak egy tárolhat értéket. |
Típusokkal kapcsolatos kulcsszavak¶
Kulcsszó | Leírás |
---|---|
typedef |
Típusképzés kulcsszava: a deklarációban megadott azonosító nem egy adott típusú változót, hanem magát a típust fogja azonosítani. |
void |
"Üres" típus: értékkel vissza nem térő függvények (eljárások) és típustalan pointerek megvalósításához. |
sizeof |
Típus méretének lekérdezésére: az adott típus egy értéke hány bájton tárolódik. |
Tárolási osztályok – hely¶
Kulcsszó | Leírás |
---|---|
auto |
"Automatikus": A globálisan deklarált változóknak hely foglalódik a program teljes futási idejére, a blokkokban lokálisan deklarált változóknak pedig az adott blokk végrehajtásának idejére. A gobális változók valamelyik adatszegmensben, a lokális változókat a veremben lesznek tárolva. |
static |
"Állandó": Az ilyen lokálisan deklarált változónak mindenképpen "statikus", vagyis állandó helyet foglalunk a program teljes futási idejére. A változó az adatszegmensben lesz elhelyezve. Meg lehet jelölni globális programelemeket (változókat, függvényeket) is a static kulcsszóval, ezek az adott fordítási egységre nézve lokálisak lesznek, más egységből nem lesznek elérhetők még a szerkesztési lépésben (linker) sem. |
register |
"Regiszter": A fordító megpróbálja mindenképpen regiszterben tartani a változót (ez nem biztos, hogy sikerül). Ez gyorsabb elérést biztosít, cserében a változónak nem lesz memóriacíme. (Akkor sem, ha a fordító nem tudja megoldani a végig regiszterben tárolást, és az értéket idonként elmenti a memóriába.) |
extern |
"Külső": Ezzel jelezzük a fordítónak, hogy a változó létezik, használni fogjuk, de ne foglaljon neki helyet, mert azt valahol máshol tesszük meg. A változóhivatkozások feloldása majd a linker feladata lesz. Ez akkor hasznos, ha egy változót más fordítási egységben is el szeretnénk érni. Érdekesség, hogy ha egy globális változót egy blokkban új deklarációval elfedünk, akkor egy ennek alárendelt blokkban extern-ként ismét újradeklarálva hozzáférhetünk a globális változóhoz. |
Tárolási osztályok – mód¶
Kulcsszó | Leírás |
---|---|
const |
"Konstans" változó: A változó (beleértve a függvény paraméter) értékét a programban nem változtathatjuk meg. A fordítóprogram nem engedi, hogy (az inicializáláson kívül, ami konstans változónál kötelező, függvényparaméternél pedig automatikus) értéket adjunk a változónak, de a változó értéke továbbra is a memóriában tárolódik, így kerülővel, pointerek segítségével azért módosítható. |
volatile |
"Illékony" változó: Ez a kulcsszó azt jelzi a fordítónak, hogy a változó értékét más is módosíthatja. Tehát a fordító nem számíthat a korábban regiszterbe töltött értékre (még ha maga a program nem is változtatott rajta). Ezért a fordító minden egyes műveletnél használni fogja a változóhoz rendelt memóriaterületet, azaz erre a változóra nem végez optimalizálást. |
Vezérlés - szelekció¶
Kulcsszó | Leírás |
---|---|
if |
Az egyszerű szelekciós vezérlés kulcsszava. |
else |
A szelekciós vezérlés egyébként ágának kulcsszava. |
switch |
Az esetkiválasztásos szelekciós vezérlés kulcsszava. |
case |
z esetkiválasztásos szelekciós vezérlés blokkjában egy belépési pont kulcsszava. |
default |
Az esetkiválasztásos szelekciós vezérlés blokkjában az egyébként fel nem sorolt esetek belépési pontja. |
Vezérlés - ismétlés
Kulcsszó | Leírás |
---|---|
for |
A ciklusszervezés egyik kulcsszava, általában számlálásos ismétlésekhez. |
while |
A ciklusszervezés másik kulcsszava, általában kezdő- vagy végfeltételes ismétlésekhez. |
do |
A végfeltételes ciklus kezdetét jelző kulcsszó. |
Vezérlés - ugrások¶
Kulcsszó | Leírás |
---|---|
break |
Kiugrás az adott ciklusból vagy switch utasításból, az azt követő első utasításra. |
continue |
A ciklusmag aktuális végrehajtásának befejezése, ugrás az inkrementálásra vagy a feltétel-kiértékelésre. |
goto |
A feltétel nélküli vezérlésátadás megvalósításának kulcsszava. (Ne használjuk!) |
return |
Visszatérés a függvényből a hívás helyére, és a visszatérési érték megadása. |