KURZUS: Programozás alapjai
MODUL: II. modul
4. lecke: Típusok és konstansok
Ebben a leckében pontosítjuk a típusokkal és konstansokkal kapcsolatosan eddig megszerzett ismereteket. Részletesen megnézzük, formálisan is definiáljuk a már ismert típusok, és az ilyen típusú konstansok szabályait, valamint eddig nem ismert típusokkal is foglalkozunk, mint pl. felsorolt típusok. Nagyon röviden szó esik végül a typedef kulcsszó használatáról is. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A lecke végére a hallgatónak tisztában kell lennie | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A lecke kulcsfogalmai: szimbólum, elválasztó jel, azonosító, függvény, típusmódosító, minősítő, alap- és származtatott típusok, felsorolás típus, enum specifikátor, enumerátor, névterület, egész típus, aritmetikai típus, definíciós deklaráció, referencia deklaráció, deklarációs pont. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Szimbólumok | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A fordító a forráskódot szintaktikai egységekre, vagy más elnevezéssel szimbólumokra (token), és fehér karakterekre tördeli. A több egymást követő fehér karakterből csak egyet tart meg. Ebből következőleg: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Pontosan hat szimbólum (int i ; float f ;) lesz a következőkből: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
int | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
vagy | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
int i; float f; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A karakter, vagy karakterlánc konstansokban előforduló, akárhány fehér karaktert változatlanul hagyja azonban a fordító. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Említettük már, hogy a programnyelv szimbólumokból áll. Most ismertetjük a szimbólum definícióját módosított Backus-Naur, metanyelvi leírással: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
szimbólum: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Az értelmezés nagyon egyszerű: a felsorolt hat fogalom mindegyike szimbólum. Az operátorokról már esett szó, de a részletekre később még visszatérünk. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A kulcsszavak: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Vannak ezeken kívül még nem szabványos kulcsszavak és más védett azonosítók, de ezek mindig megtudhatók a programfejlesztő rendszer segítségéből! Ilyenekre kell gondolni, mint a cdecl, a pascal, az stdcall, vagy egy-két aláhúzás karakterrel kezdődőkre, mint például az __STDC__ stb. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Elválasztójel | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A szintaktikai egységeket (a szimbólumokat) egymástól legalább egy fehér karakterrel el kell választani. Nincs szükség azonban az elválasztó fehér karakterre, ha a két nyelvi egység közé a szintaktikai szabályok szerint egyébként is valamilyen elválasztójelet kell írni. Az operátorok is elválasztójelnek minősülnek kifejezésekben. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
elválasztójel: (a következők egyike!) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
[ ] ( ) { } * , : = ; ... # | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Nézzük meg néhány elválasztójel funkcióját! | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Az utasítást záró pontosvessző minden példában benne van. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A kerek zárójeleknek csoportosító funkciója van kifejezésekben. Van, amikor a szintaktika része. Függvényhívásnál az aktuális paramétereket, függvénydeklarációban és definícióban a formális paramétereket ebbe kell tenni. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
d = c*(a+b); | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A szögletes zárójelek tömbök deklarációjában és indexelő operátorként használatosak. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
char kar, lanc[] = "Sztan és Pan."; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A kapcsos zárójelekbe tett több utasítás szintaktikailag egyetlen utasításnak minősül. A dolgot összetett utasításnak, blokknak nevezzük. Az összetett utasítás (blokk) záró kapcsos zárójele után tilos pontosvesszőt tenni! (Pontosabban, a pontosvessző egy további, hatástalan üres utasítást generál, de a program mérete ettől még növekedhet.) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if(a<b){ /* Illegális pontosvessző használat. */ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A csillag elválasztó-jelnek többféle szerepe van a nyelvben. Eddig csak a szorzás operátor funkcióját ismerjük. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
a = 3.14*b; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Az egyenlőség jel hozzárendelés operátor, és deklarációs utasításban elválasztja a változót az inicializátortól, vagy inicializátorlistától. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
char tomb[5] = {0, 1, 2, 3, 4}; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A kettős kereszt előfeldolgozó (preprocessor) direktíva kezdete. A sorbeli első nem fehér karakternek kell annak lennie. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#include <stdio.h> | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Azonosító | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
azonosító: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
nem-számjegy: (a következők egyike!) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
számjegy: (a következők egyike!) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Az azonosító változóknak, függvényeknek, felhasználó definiálta adattípusoknak stb. adott, a következő pontokban pontosított név: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Típusok és konstansok a nyelvben | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A nyelvben összesen négy típuskategória van: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A mutatókkal, a struktúrákkal és az uniókkal később foglalkozunk. A típusokat úgy is csoportosíthatnánk, hogy vannak | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Az alaptípusok a void, a char, az int, a float és a double. A származtatás pedig a short, a long, a signed és az unsigned ún. típusmódosítókkal történhet. A short és a long, valamint a signed és az unsigned egymást kizáró módosító párok, de a két pár egyazon alaptípusra egyszerre is alkalmazható, azaz létezik | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A signed és az unsigned módosító azonban csak egész típusokra (char és int) alkalmazható, lebegőpontos valós és a void alaptípusra nem. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A származtatott típusokba mindig beleértendők az ilyen típusú értékkel visszatérő függvények, az ilyen típust paraméterként fogadó függvények, a tömbök stb. Ha programunkban valamilyen azonosítót használni kívánunk, akkor előbb deklarálni (definiálni) kell. A deklaráció teremti meg a kapcsolatot az azonosító és az objektum között, és rögzíti legalább az objektum adattípusát. A származtatott típust is szokás egyszerűen típusnak nevezni. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"Készpénzre váltva" az előző bekezdésben mondottakat: ha a típus valamilyen nem void adattípus, akkor a deklarációk következőképp szemléltethetők: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
típus t, t1, t2; /* Három típus típusú objektum. */ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Feltétlenül említést kell tennünk még két, definícióban használható módosítóról, melyek alaposan megváltoztatják a deklarált objektum tulajdonságait. E kulcsszavakat minősítők megnevezéssel is illetik. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A const nem módosítható objektumot definiál, azaz meggátolja a hozzárendelést az objektumhoz, és az olyan mellékhatásokat, mint az inkrementálás, dekrementálás stb. Magyarán: nem engedi meg az azonosító elérését balértékként. A const a deklaráció elején bármilyen alaptípussal, aggregátum típussal stb. állhat, de tilos többtételes deklaráció első vesszője után kiírni: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
float f = 4.5, const cf = 5.6; /* HIBÁS! */ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A const típusú objektum értékkel való ellátásának egyetlen módja az inicializálás. Tehát az ilyen objektum definíciójában kötelező neki kezdőértéket adni, mert ez később már nem tehető meg. Például: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const float pi = 3.1415926; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Az elő nem írt alaptípus miatt a deklaráció specifikátorként egyedül álló const tulajdonképpen const int, s ezért a max2int is az. E deklarációk után "botor dolgok" a következő utasítások: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pi = 3.; /* Szintaktikai hiba. */ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A volatile szó jelentése elpárolgó, illékony, állhatatlan. Módosítóként azt jelzi, hogy az illető változó értéke program végrehajtáson kívüli okból (megszakítás, B/K port, konkurensen futó végrehajtási szál stb.) is megváltozhat. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A volatile kulcsszó deklaráción belüli elhelyezésének szabályai egyeznek a const-éival. A fordító az ilyen változót nem helyezheti el regiszterben, ill. az ilyen objektumot is tartalmazó kifejezés kiértékelése során nem indulhat ki abból, hogy az érték közben nem változik meg. Szóval az ilyen változó minden hivatkozásához elérési kódot kell generálnia akkor is, ha az látszólag hatástalannak tűnik. Például: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
volatile ticks; /* volatile int a típus. */ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A while-beli feltétel kiértékelésekor a ciklus minden ütemében tölteni kell ticks értékét. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Egy objektum egyszerre lehet const és volatile, amikor is az őt birtokló program nem módosíthatja, de megváltoztathatja az értékét bármely aszinkron program vagy végrehajtási szál. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A konstansok definíciója a következő: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
konstans: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Tudjuk, hogy az objektum is lehet konstans, de itt most nem ilyen állandóról van szó. Az "igazi" konstans nem azonosítható memória területet takar, mely fix, a program futása alatt meg nem változtatható értéket tartalmaz. A konstansnak nincs szoftveresen is használható címe, de van adattípusa, mely meghatározza az állandónak | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Egész típusok és konstansok | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Már említettük, hogy az egész típusok a char és az int alaptípusból a signed - unsigned, valamint a short - long módosító párok alkalmazásával állíthatók elő, azaz a deklaráció írásszabálya eltekintve a tárolási osztálytól és az inicializálástól: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<típusmódosítók> <alaptípus> azonosítólista; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A típusmódosítók alaptípus párost azonban a továbbiakban is típusnak fogjuk nevezni. A szabályok a következők: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A nyelv szerint nincs sem egész túlcsordulás, sem alulcsordulás. Az egész konstansnál láthatunk erre is egy rövid példát! | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
egész-konstans: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A metanyelvben a < ... > az elhagyhatóságot jelöli! | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
egész-konstans: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
decimális-konstans: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
oktális-konstans: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
hexadecimális-konstans: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
nemzérus-számjegy: (a következők egyike!) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
oktális-számjegy: (a következők egyike!) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
hexadecimális-számjegy: (a következők egyike!) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
egész-utótag: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
unsigned-utótag: (a következők egyike!) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
long-utótag: (a következők egyike!) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A definíció szerint: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Lássunk néhány példát a decimális, az oktális és a hexadecimális egész konstansokra! | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
int i = 10; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Explicit egész utótagot a konstans utána írva megváltoztathatjuk az alapértelmezett belsőábrázolást. Az inicializátor konstansok típusegyeztetésével elkerülhető a szükségtelen közbenső konverzió. Például: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
unsigned ui=2u; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Az egész konstans 0 és 4294967295 értékhatárok közt megengedett. Ez azonban a programozó felelőssége, mert a 4294967295-nél nagyobb érték egyszerűen csonkul. Legfeljebb egy "halk" figyelmeztető üzenet jöhet a fordítótól. Például a | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#include <stdio.h> | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
hatására 5032704 jelenik meg, ami egy híján 4300000000 - 4294967295. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Felsorolás (enum) típus és konstans | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Az enum (enumerate) adattípus mnemonikussá tesz egy sorozat egész értékre való hivatkozást. Például az | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
enum napok{ vasar, hetfo, kedd, szerda, csut, pentek, szomb } nap; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
deklaráció létrehoz egy egyedi enum napok egész típust. Helyet foglal egy ilyen típusú, nap azonosítójú változónak, és definiál hét, konstans egész értéket reprezentáló enumerátort: az enumerátor készletet. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Felsorolás típusú változóban a típushoz definiált enumerátor készlet egyik értékét tarthatjuk. Az enumerátort enum konstansnak is nevezik. Felsorolás típusú változókat használhatunk index kifejezésben, minden aritmetikai és relációs operátor operandusaként stb. Tulajdonképpen az enum a #define direktíva alternatívájának is tekinthető. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ANSI C-ben az enumerátor értékét definiáló kifejezés csak egészértékű konstans kifejezés lehet, és típusa mindig int. Az enum változó tárolásához használt memória is annyi, mint az int típushoz használt. enum típusú konstans vagy érték a C-ben ott használható, ahol egész kifejezés is. Lássuk a szintaktikát! | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
enum-specifikátor: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
enumerátorlista: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
enumerátor: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
enum-konstans: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Az enum-specifikátor definíciójában az enumerátorlistával definiált enum típus opcionális azonosítóját enum címkének (tag) nevezzük. Ha ezt elhagyjuk a definícióból, névtelen enum típust kapunk. Ennek az az ódiuma, hogy később nincs lehetőségünk ilyen felsorolás típusú változók definíciójára, hisz nem tudunk a névtelen enum-ra hivatkozni. Névtelen enum típusú változók tehát csak a névtelen enum deklarációjában definiálhatók, máshol nem. Az | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
enum {jan, feb, marc, apr, maj, jun, jul, aug, szep, okt, nov, dec}; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
így teljesen használhatatlan, hisz képtelenség ilyen típusú változót deklarálni. A probléma az azonosítólista megadásával elkerülhető: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
enum {jan, feb, marc, apr, maj, jun, jul, aug, szep, okt, nov, dec} ho=jan, honap; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Foglaljuk össze az enum deklarációval kapcsolatos tapasztalatainkat: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
enum <enum címke> <{enumerátorlista}> <azonosítólista>; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ahol a < > most is az elhagyhatóságot jelöli. Az enum címke megadása tehát azt biztosítja, hogy az "enum enum címke" után azonosítólistát írva később ilyen felsorolás típusú változókat definiálhatunk. A fejezet elején említett deklarációs példában a napok azonosító az opcionálisan megadható enum címke, mely később enum napok típusú változók definícióiban használható fel. Például: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
enum napok fizetes_nap, unnepnap; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Térjünk egy kicsit vissza az enumerátorokhoz! Láttuk, hogy az enum konstans a felsorolás típus deklarációjában definiált azonosító. Miután az enumerátor egész adattípusú, kifejezésekben ott használható, ahol egyébként egész konstans is megadható. Az enumerátor azonosítójának egyedinek kell lennie az enum deklaráció hatáskörében beleértve a normál változók neveit és más enumerátorlisták azonosítóit. Az enum konstansok az egyszerű változók névterületén helyezkednek el tehát. Az enum címkéknek viszont az enum, a struktúra és az uniócímkék névterületén kell egyedinek lenniük. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A névterület olyan azonosító csoport, melyen belül az azonosítóknak egyedieknek kell lenniük. A C-ben több névterület van, amiből itt kettőt meg is említettünk. Két különböző névterületen létező, ugyanazon azonosítónak semmi köze nincs egymáshoz. A névterületeket majd egy későbbi fejezetben tárgyaljuk! | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Lássunk példákat ezen közbevetés után! | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
int hetfo = 11; /* A hetfo egyszerű int típusú változó.*/ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Az enum napok deklarációban szereplő enum konstansok implicit módon kaptak értéket zérustól indulva és mindig eggyel növekedve. A vasar így 0, a hetfo 1, ..., és a pentek 6. Az enum konstansok azonban expliciten is inicializálhatók. Akár negatívak is lehetnek, ill. több enumerátor lehet azonos értékű is. Például: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
enum ermek{ egyes=1, kettes, otos=5, tizes=2*otos, | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Vegyük észre, hogy az enumerátor definiált már az enumerátorlista következő tagjához érve! | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Mondottuk, hogy a felsorolás típusok mindenütt feltűnhetnek, ahol egyébként az egész típusok megengedettek. Például: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
enum napok{ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
enum típusú változóhoz egész érték hozzárendelése megengedett, de explicit típusmódosító szerkezet használata javallott. Tehát a | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fizetes_nap = 5; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
helyett | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fizetes_nap = (enum napok) 5; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
írandó. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A fordítóban nincs mechanizmus a konvertálandó egész érték érvényességének ellenőrzésére! Pontosabban a következő lehetetlenség elkerülése a programozó felelőssége: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
n = (napok) 958; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Az enum típus egész (integral) típus. Implicit módon konvertál így egésszé bármely enumerátort a fordító, de a másik irányban az explicit típusmódosítás javasolt: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
int i; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Egész típusnak az egész értékek tárolására alkalmas, aritmetikai adattípusokat (char, short, int, long és enum) nevezzük. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Valós típusok és konstans | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Az IEEE lebegőpontos belsőábrázolású valós alaptípusok a float és a double. Egyedül a long módosító használata megengedett, s az is csak a double előtt, azaz van még long double származtatott típus. A float típusú, egyszeres pontosságú lebegőpontos ábrázolás 4 bájtot foglal, melyből 8 bit a 128 többletes, bináris exponens, 1 bit a mantissza előjele (1 a negatív!) és 23 bit a mantissza. A mantissza 1.0 és 2.0 közötti szám. Miután a mantissza legnagyobb helyiértékű bitje mindig egy, az ábrázolás ezt nem tárolja. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A double exponens 11-, s a mantissza 52 bites. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A lebegőpontos belsőábrázolás méretei, megközelítő határai és decimális jegyben mért pontossága a következő táblázatban látható: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Ehhez már csak annyit kell hozzáfűzni, hogy lebegőpontos zérus az, amikor a belsőábrázolás minden bitje zérus. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A leírás az IEEE szabványos lebegőpontos ábrázolásról szól, de elképzelhető, hogy a konkrét fordító más formával dolgozik. A szabványos float.h fejfájlban azonban mindig megtalálhatók szimbolikus állandók (FLT_MIN, DBL_MAX stb.) alakjában az ábrázolási határok és más konkrétumok az aktuális belsőábrázolásról. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
lebegőpontos-konstans: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
tört-konstans: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
exponens-rész: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
előjel: (a következők egyike!) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
számjegy-sor: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
float-utótag: (a következők egyike!) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
double belsőábrázolású lebegőpontos konstansok: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
-.5e35, 5., 5E-4, 3.4 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Ugyanezek float és long double belsőábrázolásban: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
-.5e35f, 5.L, 5E-4F, 3.4l | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Az egyszeri programozó beírta a forrásszövegébe a | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
float v=143736120; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
sorokat, és meglepődött a 143736128-as eredményen. Ha v értékét eggyel csökkentette, akkor meg 143736112-őt kapott. Mi lehet a probléma? | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A 143736120 (0X8913D38) binárisan | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1000 1001 0001 0011 1101 0011 | 1000 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
de csak 24 bit fér el a belsőábrázolás mantisszájában. A fordító a legmagasabb helyi értékű, lecsorduló bit értékével megnöveli a mantisszát. Most, a karakterisztikával nem foglalkozva, az új érték: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1000 1001 0001 0011 1101 0100 | 0000 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ami éppen 143736128 (0X8913D40). | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A 143736119 (0X8913D37) binárisan | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1000 1001 0001 0011 1101 0011 | 0111 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
esetében az eredmény | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1000 1001 0001 0011 1101 0011 | 0000 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
lesz, ami143736112 (0X8913D30). | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Komolyan kell tehát venni a lebegőpontos ábrázolások decimális jegyben mért pontosságát, és az ábrázolási határokat. Még két dologra feltétlenül oda kell figyelni: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Karakter típus és konstans | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A karakter típusról már szó esett az egész típusok tárgyalásánál. Tudjuk, hogy három karakter típus van: char, signed char és unsigned char. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A karakter típusú objektum helyfoglalása 1 bájt mindenképp. A karakter konstans típusára és helyfoglalására rögtön kitérünk definíciója után! | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
karakter-konstans: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
c-karakter-sor: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
c-karakter: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A definícióból következőleg a karakter konstans aposztrófok közt álló egy vagy több karakter, ill. escape szekvencia. Ezen az elven beszélhetünk egykarakteres és többkarakteres karakter konstansról. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
'An', '\n\r', 'Alfi', 'tag', '\007\007\007' | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Tudjuk, hogy az int belsőábrázolású karakter konstans esetében is érvényben van a signed char alapértelmezés. Ennek következtében az int méreténél kevesebb karakterből álló karakter konstansok előjel kiterjesztéssel alakulnak int belsőábrázolásúvá. (Azaz az újonnan megjelenő, magas helyi értékeken álló biteket az eddigi legmagasabb helyi értéken álló, előjelet jelző bit értékével tölti fel a fordító.) Konkrét példaként tekintsük a 2 bájtos int-et, és a 852-es kódlapot! Az é betű kódja 130 (0X82) és az a betűé 97 (0X61). Az 'é'-ből így 0XFF82 és az 'a'-ból 0X0061 lesz a memóriában, s így igaz lesz a következő reláció: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
'é' < 'a' | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Ha unsigned char az alapértelmezés (ami viszont nem túl gyakori eset), akkor a felső bájt(ok)at bizonyosan 0X00-val tölti fel a fordító (az 'é'-ből 0X0082 lesz), és nem jön elő az előbb taglalt probléma. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A következő kis példa szemlélteti a tárgyalt karakter típus és karakter konstans méreteket! | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#include <stdio.h> | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Szólnunk kell még néhány szót a pontosítás kedvéért az escape szekvenciáról! A \ jelet követheti egy a táblázatban ismertetett karakter, vagy egy legfeljebb háromjegyű oktális szám, vagy x után hexadecimális számjegyek. Például a '\03' a Ctrl+C, a '\x3F' a ? karakter stb. Szóval az escape szekvencia leírhat vezérlő és "igazi" karaktereket egyaránt. Nézzük még a szabályokat! | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Az eddig tárgyalt adattípusokat összefoglaló névvel aritmetikai adattípusoknak is nevezhetjük. Az aritmetikai adattípusok "zavarba ejtő" bősége a nyelvben azonban nem arra szolgál, hogy a programozó | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Készítsen szorzat piramist! A piramis alsó sora 16 darab 100-tól 115-ig terjedő egész szám! A következő sorokat úgy kapjuk, hogy az alattuk levő sor elemeit páronként összeszorozzuk. A második sor így néz ki tehát: 100*101 = 10100, 102*103 = 10506, ..., 114*115 = 13110. A harmadik sorban a következők állnak: 10100*10506 = 106110600, 10920*11342 = 126854640, ..., 12656*13110 = 165920160, és így tovább. Figyeljünk arra, hogy az eredményül kapott számokat mindig a lehető legkisebb helyen tároljuk, de az értékeknek nem szabad csonkulniuk! (A megoldásnál feltételeztük, hogy az adott fordító 2 bájtos short és int, valamint 4 bájtos long típussal dolgozik; ettől eltérő esetben más eredményt adhat, és más típusokat is kellene alkalmazni.) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/* PELDA12.C: Szorzat piramis */ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Már a pelda7.c példában találkoztunk az egészekre vonatkozó h és l hosszmódosítókkal a formátumspecifikációkban. Most a long double típusú paraméter jelzésére való L hosszmódosítót ismerhettük meg. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Ha a szorzat piramis második szintjének kiszámítását végző | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
n2[i/2]=(long)n1[i]*(long)n1[i+1]; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
kifejezésből elhagyjuk a két, explicit (long) típusmódosítót, akkor a listarész a következőképp módosul: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Szorzat piramis: második szint | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Ez vitathatatlanul rossz, de miért? | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Karakterlánc (string literal) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A karakterláncokról már esett szó korábban, de most megadjuk a formális definíciójukat is: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
karakterlánc: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
s-karakter-sor: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
s-karakter: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A karakterlánc adattípusa char tömb. A tömb mérete mindig eggyel hosszabb, mint ahány karakterből a karakterlánc áll, mert a nyelv a lánc végét '\0' karakterrel jelzi. A karakterlánc konstansokat mindig a statikus adatterületen helyezi el a fordító. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Például a "Jani" karakterlánc egymást követő, növekvő című memória bájtokon így helyezkedik el. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A karakterlánc karaktereiként használható az escape szekvencia is. Például a | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"\t\t\"Név\"\\\tCím\n\n | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
karakterláncot printf függvény paramétereként megadva | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"Név"\ Cím | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
jelenik meg utána két soremeléssel. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A csak fehér karakterekkel elválasztott karakterlánc konstansokat a fordító elemzési fázisa alatt egyetlen karakterlánccá egyesíti: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"Egy " "kettő, " "három... " -> "Egy kettő, három..." | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Tudjuk, hogy a karakterlánc konstans a folytatássor (\) jelet használva több sorba is írható: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
printf("Ez igazából egyetlen \ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Írjunk meg néhány karakterláncot kezelő függvényt! Legyen az első az unsigned strlen(char s[]), ami a paraméter karakterlánc hosszát szolgáltatja! Indítsunk egy változót zérustól, és indexeljünk előre vele a karakterláncon, míg a lánczáró nullát el nem érjük! Ez az index a karakterlánc hossza is egyben. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
unsigned strlen(char s[]){ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Valósítson meg a void strcopy(char cél[], char forrás[]) hozzárendelést a karakterláncok körében azzal, hogy a forrás karakterláncot átmásolja a cél karaktertömbbe! Indexeljünk most is végig egy változóval a forrás karakterláncon a lezáró zérusig! Közben minden indexre rendeljük hozzá a forrás tömbelemet a cél tömbelemhez! Vigyázzunk, hogy a lánczáró nulla is átkerüljön! | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
void strcopy(char cél[], char forrás[]){ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Javítsunk kicsit ezen a megoldáson! A while-beli reláció elhagyható, hisz a hozzárendelés is mindig igaz (nem zérus), míg a forrás[i] nem lánczáró zérus. Belátható, hogy a '\0' karakter is átkerül, mert a while csak a hozzárendelés végrehajtása után veszi csak észre, hogy kifejezése hamissá (zérussá) vált. Tehát: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
while(cél[i]=forrás[i]) ++i; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Lássuk be, hogy a | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
while(cél[i++]=forrás[i]); | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
is tökéletesen funkcionál, hisz | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A legjobb megoldásunk tehát: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
void strcopy(char cél[], char forrás[]){ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Készítsünk void strct(char s1[], char s2[]) függvényt, ami egyesíti a két paraméter karakterláncot s1-be! Indexeljünk előre az s1-en a lánczáró nulláig, s ezután ide kell másolni az s2 karakterláncot! Belátható, hogy a helyes megoldáshoz két indexváltozó szükséges, mert a másolásnál az egyiknek s1 lánczáró nullájának indexétől kell indulnia, míg a másiknak s2-n zérustól. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
void strct(char s1[], char s2[]){ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Készítsünk void strup(char s[]) függvényt, ami nagybetűssé alakítja saját helyén az s karakterláncot! Indexeljünk végig az s karaktertömbön a lánczáró zérusig! Egy-egy pozíción meg kell vizsgálni a tömbelem értékét. Ha nem kisbetű, akkor nem kell tenni semmit. Ha kisbetű, át kell írni nagybetűvé. Ha csak az angol ábécé betűivel foglalkozunk, akkor meg kell határozni a kisbetű tömbelem eltolását 'a'-hoz képest, s ezt az eltolást hozzá kell adni 'A'-hoz. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
void strup(char s[]){ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Feltétlenül meg kell említeni, hogy a most megírt karakterlánc kezelő függvények kicsit más névvel, de azonos funkcióval, és paraméterezéssel léteznek a szabvány könyvtárban. (Ez egyes fordítóprogramoknak gondot is okozhat. Ebben az esetben próbálkozzunk a függvények átnevezésével!) Használatukhoz azonban a string.h fejfájlt be kell kapcsolni. A névlista: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
strlen -> strlen | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
strcopy -> strcpy | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
strct -> strcat | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
strup -> strupr | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Próbáljuk ki a megírt függvényeinket egy rövid programmal! Kérjünk be egy sort a szabvány bemenetről! Alakítsuk át nagybetűssé! Tegyük elé az ELEJE:, és mögé a :VÉGE szöveget! Jelentessük meg az eredményt! Írjuk még ki az eredeti és az egyesített karakterlánc hosszát! | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Az ismétlés elkerülése miatt most a függvények teste helyett csak /* ... */-eket közlünk. Működőképes programhoz persze oda kell másolni a függvénydefiníció forrásszövegét is. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/* PELDA13.C: Karakterlanc kezelese */ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Deklaráció | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A deklaráció megteremti a kapcsolatot az azonosító és az objektum között, ill. rögzíti például többek között az objektum adattípusát. Kétféle deklarációról beszélhetünk: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Tudjuk azt is, hogy a deklaráció elhelyezése és maga a deklaráció meghatározza az objektum attribútumait: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
int x; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A deklarálható objektumok a következők: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A deklarátor szintaktika rekurzivitása miatt egészen komplex deklarátorok is megengedettek. Ezt el szokás kerülni típusdefinícióval (typedef). A deklaráció metanyelvi leírása a következő: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
deklaráció: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
deklaráció-specifikátorok: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
init-deklarátorlista: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
init-deklarátor: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
inicializátor: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
inicializátorlista: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
tárolási-osztály-specifikátor: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
típusspecifikátor: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
typedef-név: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
deklarátor: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
direkt-deklarátor: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
konstans-kifejezés: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
azonosítólista: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A mutatókkal, a struktúrával, az unióval, a függvényekkel, az utasítás címkékkel és a makrókkal később foglalkozunk, így a vonatkozó metanyelvi leírások is ott lesznek találhatók. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A tárolási-osztály-specifikátorokat teljes részletességgel majd később taglaljuk, de közülük kettőről (auto és extern) már esett szó korábban. A következő pontban némi előzetes képet kapunk a typedef-ről is. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A típusspecifikátorokat alaptípusokra és típusmódosítókra bontottuk korábban. A típusmódosítók és alaptípusok megengedett, együttes használatát korábban tisztáztuk. A const és a volatile viszont bármely alaptípussal és típusmódosítóval együtt szinte korlátozás nélkül használható. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A deklarátor egyedi azonosítót határoz meg. Mikor az azonosító megjelenik egy vele egyező típusú kifejezésben, akkor a vele elnevezett objektum értékét eredményezi. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A konstans-kifejezés mindig fordítási időben is meghatározható konstans értékké értékelhető ki, azaz értéke bele kell, hogy férjen a típus ábrázolási határaiba. A konstans kifejezés bárhol alkalmazható, ahol konstans egyébként használható. A konstans kifejezés operandusai lehetnek egész konstansok, karakter konstansok, lebegőpontos konstansok, enumerátorok, típusmódosító szerkezetek, sizeof kifejezések stb. A konstans kifejezés azonban a sizeof operátor operandusától eltekintve nem tartalmazhatja a következő operátorok egyikét sem: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Elemi típusdefiníció (typedef) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Nem tartozik igazán ide a típusdefiníció tárgyalása, de miután a typedef kulcsszót a tárolási osztály specifikátor helyére kell írni, itt adunk róla egy rövid ismertetést. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A typedef kulcsszóval nem új adattípust, hanem új adattípus specifikátort definiálunk. Legyen szó például az | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
auto long int brigi; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
definícióról, mely szerint a brigi egy 32 bites, signed long int típusú, lokális élettartamú objektum azonosítója. Használjuk most az auto kulcsszó helyett a typedef-et, és az azonosítót írjuk át nagybetűsre! | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
typedef long int BRIGI; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ahol a BRIGI azonosító nem képez futásidejű objektumot, hanem egy új típusspecifikátor csak. A programban ezután a BRIGI típusspecifikátorként alkalmazható deklarációkban. Például az | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
extern BRIGI fizetni; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ugyanolyan hatású, mint az | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
extern long int fizetni; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Ez az egyszerű példa megoldható lenne a | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#define BRIGI long | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
módon is, a typedef-fel azonban az egyszerű szöveghelyettesítésnél komplexebb alkalmazások is megvalósíthatóak. A typedef nem hoz létre új típust tulajdonképpen, csak létező típusokra kreálható vele új kulcsszó. Komplexebb deklarációk egyszerűsítésére való. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A típusdefiníció "megbonyolítására" a későbbiekben még visszatérünk! Meg kell jegyeznünk azonban annyit, hogy a typedef-fel létrehozott típusspecifikátor nem használható a deklarációban más típusspecifikátorokkal együtt! Legfeljebb a const és a volatile módosítók alkalmazhatók rá! Például | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
unsigned BRIGI keresni; /* HIBÁS. */ |
Feladatok | |||||||||||||
1. Jelölje meg, hogy mely azonosítók helyesek, és melyek nem!
![]() | |||||||||||||
2. Olyan függvényt szerettünk volna írni, ami igaz értéket szolgáltat, ha a paraméter karakterlánc SS:SS:SS formátumú, ahol S egy tetszőleges számjegy, egyébként hamisat. Sajnos nem sikerült. | |||||||||||||
/*1*/int idoe(char s[]) { | |||||||||||||
Jelölje meg azokat a sorokat, amikkel a függvény helyes működésre bírható!
![]() | |||||||||||||
3. Olyan függvényt szerettünk volna írni, ami visszaadja a SS:SS:SS formátumú karakterlánc adott indexű helyén kezdődő, két számjegyű szám értékét, de sajnos nem sikerült. | |||||||||||||
/*1*/int ertek(char s[], int i) { | |||||||||||||
Jelölje meg azokat a sorokat, amikkel a függvény helyes működésre bírható!
![]() | |||||||||||||
4. El szerettük volna készíteni azt a függvényt, ami kisbetűssé alakítja saját helyén az s karakterláncot, de sajnos nem sikerült. | |||||||||||||
/*1*/void strlw(char s[]) { | |||||||||||||
Jelölje meg azokat a sorokat, amikkel a függvény helyes működésre bírható!
![]() | |||||||||||||
5. El szerettük volna készíteni azt a függvényt, ami kitörli az s karakterláncból a nem kívánatos c betűket, de sajnos nem sikerült. | |||||||||||||
/*1*/void chdel(char s[], int c){ | |||||||||||||
Jelölje meg azokat a sorokat, amikkel a függvény helyes működésre bírható!
![]() | |||||||||||||
6. Készítsen olyan függvényt, ami képes a paraméterként adott karakterlánc betűinek sorrendjét a saját helyén megfordítani (pl. mozi -> izom)! Készítsen tesztprogramot is a függvény kipróbálásához! | |||||||||||||
#define MAX 128 | |||||||||||||
7. Olyan programot szerettünk volna írni, ami képes egy öt elemű, egészekből álló tömb elemeit egymástól vesszővel elválasztva kiírni, az utolsó elem után pedig pontot tenni. Sajnos ez nem sikerült. | |||||||||||||
/*01*/#include <stdio.h> | |||||||||||||
Jelölje meg azokat a sorokat, amelyek felhasználásával a program működőképessé tehető!
![]() | |||||||||||||
8. Olyan programot szerettünk volna írni, ami képes egy öt elemű, egészekből álló tömb elemeit egymástól vesszővel elválasztva fordított sorrendben kiírni, az utolsó elem után pedig pontot tenni. Sajnos ez nem sikerült. | |||||||||||||
/*01*/#include <stdio.h> | |||||||||||||
Jelölje meg azokat a sorokat, amelyek felhasználásával a program működőképessé tehető!
![]() | |||||||||||||
9. Olyan programot szerettünk volna írni, ami képes egy öt elemű, egészekből álló tömb elemeit összeadni, majd a szabvány kimeneten megjeleníteni. Sajnos ez nem sikerült. | |||||||||||||
/*1*/#include <stdio.h> | |||||||||||||
Jelölje meg azokat a sorokat, amelyek felhasználásával a program működőképessé tehető!
![]() |