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 \texttt{-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ó az O3-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ó az o2-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.

Utolsó frissítés: 2020-10-20 10:36:58