„C (programozási nyelv)” változatai közötti eltérés

[ellenőrzött változat][nem ellenőrzött változat]
Tartalom törölve Tartalom hozzáadva
a Visszaállítottam a lap korábbi változatát: 195.199.181.234 (vita) szerkesztéséről Ruisza szerkesztésére
124. sor:
 
int main() // függvénydefiníció, egyúttal a program belépési pontja, ezúttal nincs paramétere
{ // [[#blokk|blokk]] kezdete pelyhe be szart nagyon büdös XD XD XD
int i; // deklaráció
 
181. sor:
* '''float''', '''double''', '''long double''' konstans pl.: <code>3.14</code>, <code>8.3e11</code>, <code>8.3d-11</code>. Float típusú konstans <code>3.14F</code>, long double <code>3.14L</code> alakban adható meg. Ha nincs típusjelzés, a konstans double típusú.
* '''void''': speciális adattípus, mellyel semmilyen művelet nem végezhető, még értékadás és konverzió sem. Mutatók és függvények esetén használatos.
A char, short, int, long és long long '''fixpontos''', a floatloat, double és long double '''lebegőpontos''' típus. Fixpontos adattípuson nincs túlcsordulás-ellenőrzés: az hibás működést eredményez.
 
A C-ben nincsen '''string típus''' (bár string konstans van, a [[#példa|példaprogramban]]: "Haho\n"). A stringet karakter[[#tömb|tömbben]] tartja, a string végét bináris nulla (<code>'\0'</code>) jelzi.
256. sor:
| align="center" | Programkód
|}
A tárolási osztály adja meg, hogy az adat a program melyik memóriaterületére kerül (lásd jobb oldali táblázat, középső oszlop).
 
A [[#blokk|blokkon]] (függvényen) kívül deklarált adat mindig statikus, a blokkon belüli – ha mást nem adunk meg – dinamikus. Blokkon belüli adat a <code>static</code> kulcsszóval tehető statikussá, és az <code>extern</code> jelzi, hogy másik forrásprogramban van deklarálva. Az <tt>extern</tt> kulcsszót blokkon kívül szokás használni, és mindig statikus adatra vonatkozik.
 
A statikus adatnak állandó helye (memóriacíme) van. A dinamikus adat a veremben tárolódik, a blokkba belépéskor foglalódik le a helye, kilépéskor felszabadul, kezdőértéke definiálatlan.
 
A <code>register</code> kulcsszóval javasolhatjuk a fordítóprogramnak, hogy a dinamikus adatot ne veremben, hanem a CPU regiszterében tartsa. Az ilyen változóknak nincs memóriacímük, így a <code>&</code> művelet nem használható rájuk. Kezdőértékük definiálatlan. Ha nincs elég regiszter, akkor a deklaráció ellenére verembe kerül az adat. A jelenlegi igen jól optimalizáló fordítók mellett a <tt>register</tt> használata idejétmúlt.
 
A programban kezdőértéket nem kapott statikus adatok 0 értéket kapnak, amikor az operációs rendszer a memóriába tölti a programot.
 
Konstans változót a <code>const</code> kulcsszóval lehet megadni, és kötelezően kezdőértéket kell kapjon, mely a program végrehajtása során nem változik, és a fordítóprogram ellenőrzi is, hogy ne szerepelhessen olyan utasításban, ahol értéket kaphatna. A konstans memóriaterületre kerülnek azok a konstansok is, melyeknek nincs nevük (<code>"Haho\n"</code> a [[#példa|mintapéldában]]).
 
==== A változó típusa ====
Háromféle lehet:
* egyszerű (lásd [[#Egyszerű típusok|fent]])
* összetett: <code>[[#struktúra|struct]]</code>, <code>[[#unió|union]]</code> vagy <code>[[#enum|enum]]</code>
* [[#tömb|tömb]] vagy [[#mutató|mutató]].
 
==== Kezdőérték ====
Kezdőérték a változónév utáni <code>=</code> jelet követő konstanssal adható meg. Kezdőérték adható dinamikus változónak is, de az érték beállításához a fordítóprogram kódot generál, és nem teszi a kezdőértékeket a konstansok memóriaterületére.<ref>A kezdőértéket kapott összetett adat fordítóprogramtól függően kivétel lehet: ilyenkor a konstans adatterületről másolja a verembe a kezdőértéket a kód.</ref>
 
Tömbök és összetett változók kezdőértékeit <code>{</code> és <code>}</code> közé kell tenni, a zárójelbeli értékeket vesszővel elválasztva. Nem hiba az utolsó érték után is kitenni a vesszőt.
 
Ha egy változónak nincs kezdőértéke, akkor az dinamikus változó esetén definiálatlan, statikus változó esetén 0 (lásd [[#Tárolási osztály|tárolási osztály]]).
 
==== Példák változódeklarációra ====
<syntaxhighlight lang="C">
int i;
int a, b=2;
static const unsigned short alfa = 88;
extern int globalis;
</syntaxhighlight>
 
=== {{anchor|struktúra}} Struktúra ===
A struktúra különböző típusú adatokból álló adat. A struktúra szerkezetét és a változókat lehet együtt vagy külön-külön deklarálni. Az alábbi két példa egyenértékű:
<table><tr><td>
<syntaxhighlight lang="C">
struct datstr {
short ev;
short ho;
short nap;
};
struct datstr ma, holnap;
</syntaxhighlight>
 
</td><td style="padding-left: 10pt; vertical-align: top">
<syntaxhighlight lang="C">
struct {
short ev;
short ho;
short nap;
} ma, holnap;
</syntaxhighlight>
 
</td></tr></table>
 
Az első példában az első utasítás az adatszerkezetet definiálja (melyet gyakran [[##include|header-fájlba]] teszünk, ha több forrásfáljból is használni akarjuk), a második deklarálja a változókat.
 
A második esetben a struktúrának nem kell kell neve legyen, bár ilyenkor nem használhatjuk a definiált adatszerkezetet később, más változó deklarálásához.
 
Kezdőértékadás a deklarációban:
<syntaxhighlight lang="C">
struct datstr ma = { 2015, 12, 4 };
</syntaxhighlight>
Értékadás aritmetikai utasítással:
<syntaxhighlight lang="C">
holnap = ma;
holnap.nap = 5;
</syntaxhighlight>
 
A struktúrák egymásba ágyazása:
<syntaxhighlight lang="C">
struct {
struct datstr dat;
short ora;
} pelda;
</syntaxhighlight>
Az évre <code>pelda.dat.ev</code> néven hivatkozhatunk, <code>pelda.ev</code> néven nem.
 
[[#struktmut|Mutatóval adott struktúra]] tagjaira a <code>-></code> művelettel lehet hivatkozni.
 
=== {{anchor|unió}} Unió ===
Az unió (<code>union</code>) formailag megegyezik a struktúrával, de a tagjai (melyek rendszerint struktúrák) azonos memóriaterületen helyezkednek el. Az unió mérete a legnagyobb tag mérete lesz. Arra szolgál, hogy ugyanazt a memóriaterületet a program különböző időpontokban különböző célokra használhassa. Rendszerprogramokban fordul elő, felhasználói programban ritka.
 
=== enum ===
Akkor használatos, ha egy egész változó csak néhány értéket vehet fel, és ezekre az értékekre (tipikusan kódokra) névvel akarunk hivatkozni a könnyebb megjegyezhetőség érdekében. Alakja a struktúrához hasonló, pl.:
<syntaxhighlight lang="C">
enum httpkod { VAN=200, TILTOTT=403, NINCS=404 } htkod;
</syntaxhighlight>
<tt>httpkod</tt> a struktúranév megfelelője, <tt>htkod</tt> a változó neve. A struktúrához hasonlóan külön is megadható a kettő. A kapcsos zárójelben nem kötelező értékeket megadni, ilyenkor a fordítóprogram 0-tól egyesével növekvő értékeket rendel a felsorolt nevekhez.
 
C-ben az enum – a [[C++]]-tól eltérően – nem definiál külön adattípust, egyszerűen hozzárendeli a felsorolt nevekhez az egész értékeket. A nevek ezután bármilyen [[#kifejezés|aritmetikai kifejezésben]] szerepelhetnek, mintha egész típusú konstansok lennének, de a program hordozhatósága érdekében ezt a tulajdonságot nem ajánlatos kihasználni.
 
=== {{anchor|tömb}} Tömbök ===
A programozásban tömbnek olyan változókat neveznek, melyek több azonos típusú adatból állnak. A deklaráció formája azonos a '''skalár''' (nem tömb) típusú változóval. Az elemek számát C-ben a változónév után szögletes zárójelben kell megadni (csak egész típusú érték lehet), a kezdőértékeket pedig a struktúráknál megismert módon. Pl:
<syntaxhighlight lang="C">
int egesztomb[4];
const int allando[3] = { 1, 2, 3 };
static struct datstr { int ev; int ho; int nap; } dat[2] = { { 1954, 10, 19 }, { 2015, 12, 06 } };
</syntaxhighlight>
 
A tömbök indexei 0-val kezdődnek. <tt>allando</tt> elemeire allando[0], allando[1], allando[2]-vel lehet hivatkozni. C-ben nincs tömbindex-ellenőrzés: allando[3]-ra hivatkozás hibás működést fog eredményezni. A tömbindex-túlcsordulás az egyik leggyakoribb programozási hiba C-ben.
 
Bármilyen típusú változó lehet tömbben, beleértve a tömböt is: C-ben a kétdimenziós tömb az egydimenziós tömb tömbje:
<syntaxhighlight lang="C">
double matrix[3][14];
</syntaxhighlight>
 
A többdimenziós tömbök elemei sorfolytonosan tárolódnak. Nem hiba egydimenziós tömbként hivatkozni rájuk, pl. <code>matrix[0][40]</code>.
 
A tömb elemszáma megadható fordítási időben kiértékelhető (konstans) kifejezéssel:
<syntaxhighlight lang="C">
int tomb[3+8*4];
381 ⟶ 270 sor:
A '''mutató''' memóriacímet tároló változó. Leggyakrabban függvények paramétereiben és tömbelem-hivatkozásokban fordul elő.
 
A mutató típus) Ezt könnyíti meg a <code>datmut->ev</code> alak. A kettő hatásában teljesen azonos.
A mutató típusa a memóriacímen tárolt adat típusát jelzi. A mutatót a változódeklarációban a név elé tett csillag jelzi:
<syntaxhighlight lang="C">
int *mut;
</syntaxhighlight>
Értéket a címképző operátorral adhatunk a mutatónak:
<syntaxhighlight lang="C">
int egesz = 3, *mut;
mut = &egesz;
</syntaxhighlight>
A mutatóval megadott adat értékére a <code>*</code> operátorral hivatkozunk. A fenti két sor után <code>egesz</code> és <code>*mut</code> értéke egyaránt 3.
 
A tömb neve a tömb memóriacímét jelenti; ilyenkor nem kell kitenni az <code>&</code>-et:
<syntaxhighlight lang="C">
int tomb[8], *mut;
mut = tomb;
</syntaxhighlight>
 
A mutatóhoz 1-et hozzáadva nem eggyel, hanem a fenti példában <code>sizeof(int)</code>-tel nő a mutató értéke, vagyis a következő egészre (a tömb következő elemére) mutat. Ez azt jelenti, hogy <code>*(mut+1)</code> és <code>tomb[1]</code> a fenti példában ugyanazt az értéket adja, és <code>*(mut+1)</code> is leírható <code>mut[1]</code> alakban.
 
Különbség csak két azonos típusú mutató között értelmezett, és a két cím különbsége elosztódik a típus hosszával. A fenti példában <code>mut-tomb</code> azt mondja meg, hogy <tt>mut</tt> <tt>tomb</tt> hányadik elemére mutat.
 
A mutató lehet <code>void</code> típusú; ilyenkor a fordítóprogram nem ellenőrzi a mutató típusát. Pl. a <tt>malloc</tt> nevű könyvtári függvény, mely memóriát kér a program számára, <code>void</code> mutatót ad vissza, melyet a program a kívánt típusú mutatóba tesz. A void típus miatt az értéket eltároló utasítás nem jelez típuskonverziós hibát.
 
A mutató típusa a memóriacímen tárolt adat típusa. Ebbe a <code>const</code> is beleértendő:
<syntaxhighlight lang="C">
int egy;
const int *mut;
mut = &egy; // helyes
*mut = 5; // hibas: konstansnak nem adhato ertek
</syntaxhighlight>
 
{{anchor|struktmut}}Struktúramutatók számára külön műveletet vezettek be. Pl.:
<syntaxhighlight lang="C">
struct { int ev; int ho; int nap; } dat, *datmut;
datmut = &dat;
</syntaxhighlight>
után <code>dat.ev</code>-re <code>(*datmut).ev</code> alakban kellene hivatkozni. (A zárójelre szükség van, mert a <code>.</code>-nak nagyobb a [[#prioritás|prioritása]], mint a <code>*</code>-nak.) Ezt könnyíti meg a <code>datmut->ev</code> alak. A kettő hatásában teljesen azonos.
 
A [[#Függvénymutató|függvénymutatók]] használatát lásd a [[#Függvények|függvényeknél]].
 
A mPELYHE BESZART !! NAGYON BÜDÖS NAGY A FASZOM PELYHE BÜDÖS xd xd xd xd XDXDXDXDXDXDXDXDXDXDXDDXDXDXXDXDDXDXDXDXDDXDXDXDXD ZSOZEATYA A KIRALY BÜDÖS KUTYÁK VAGYTOK AKIK OLVASSATOK
A mutatót visszaadó könyvtári függvények <code>NULL</code> értéket adnak vissza sikertelenség esetén (pl. a memóriafoglalás nem sikerült). A <tt>NULL</tt> az <tt>stdio.h</tt> [[##include|header-fájlban]] definiált konstans.
 
Mutató mutatóra is mutathat:
<syntaxhighlight lang="C">
int mut=3,*mut1,**mut2,***mut3;
 
mut1 = &mut;
mut2 = &mut1;
mut3 = &mut2;
</syntaxhighlight>
A fentiek után a <code>mut</code>, <code>*mut1</code>, <code>**mut2</code> vagy <code>***mut3</code> kifejezések mindegyikének 3 az értéke.
 
=== Típusdeklaráció ===