Professional Documents
Culture Documents
C Programozas PDF
C Programozas PDF
1BEVEZETS....................................................................................................................5
2JELLSEK.....................................................................................................................7
3ALAPISMERETEK..........................................................................................................8
3.1Forrsprogram............................................................................................................8
3.2Fordts...................................................................................................................... 8
3.3Kapcsolszerkeszts (link).................................................................................... 12
3.4Futtats.....................................................................................................................12
3.5Tblzat ksztse.................................................................................................... 13
3.6Bemenet, kimenet.................................................................................................... 21
3.7Tmbk....................................................................................................................28
3.8Fggvnyek..............................................................................................................31
3.9Prodzsekt................................................................................................................. 35
3.10Karaktertmb s karakterlnc................................................................................ 37
3.11Loklis, globlis s bels, kls vltozk..............................................................41
3.12Inicializls............................................................................................................ 46
4TPUSOK S KONSTANSOK......................................................................................49
4.1Elvlaszt-jel........................................................................................................... 50
4.2Azonost................................................................................................................. 51
4.3Tpusok s konstansok a nyelvben...........................................................................52
4.3.1Egsz tpusok s konstansok.............................................................................55
4.3.2Felsorols (enum) tpus s konstans................................................................. 58
4.3.3Vals tpusok s konstans................................................................................. 61
4.3.4Karakter tpus s konstans................................................................................ 63
4.4Karakterlnc (string literal):.....................................................................................68
4.5Deklarci ...............................................................................................................71
4.5.1Elemi tpusdefinci (typedef).......................................................................... 75
5MVELETEK S KIFEJEZSEK................................................................................ 77
5.1Aritmetikai mveletek (+, -, *, / s %).....................................................................79
5.1.1Multiplikatv opertorok (*, / s %)..................................................................80
5.1.2Additv opertorok (+ s -)............................................................................... 83
5.1.3Matematikai fggvnyek...................................................................................83
5.2Relci opertorok ( >, >=, <, <=, == s !=)........................................................... 85
5.3Logikai mveletek ( !, && s ||)...............................................................................86
5.4Implicit tpuskonverzi s egszellptets...........................................................87
5.5Tpusmdost szerkezet......................................................................................... 89
5.6sizeof opertor......................................................................................................... 90
5.7Inkrementls (++), dekrementls (--) s mellkhats........................................... 91
5.8Bit szint opertorok ( ~, <<, >>, &, ^ s |).............................................................92
5.9Feltteles kifejezs ( ? :).......................................................................................... 96
5.10Hozzrendels opertorok..................................................................................... 98
5.11Hozzrendelsi konverzi....................................................................................100
5.12Vessz opertor................................................................................................... 101
5.13Mveletek prioritsa ........................................................................................... 102
6UTASTSOK............................................................................................................. 106
6.1sszetett utasts....................................................................................................106
6.2Cmkzett utasts.................................................................................................. 107
6.3Kifejezs utasts................................................................................................... 107
6.4Szelekcis utastsok............................................................................................. 108
6.5Itercis utastsok.................................................................................................111
6.6Ugr utastsok...................................................................................................... 116
2 TARTALOMJEGYZK S ELSZ
13FGGELK............................................................................................................... 281
13.1CHDEL.C............................................................................................................ 281
13.2EGYESIT.C......................................................................................................... 281
13.3HEXA.C...............................................................................................................282
13.4IKSZ.C.................................................................................................................283
13.5INDEXEU.C........................................................................................................284
13.6JANI.C................................................................................................................. 285
13.7KOZEPRE.C........................................................................................................285
13.8LAPOZ.C.............................................................................................................286
13.9NEVREND.C.......................................................................................................287
13.10PELDA18X.C....................................................................................................288
13.11PELDA18Y.C....................................................................................................289
13.12PELDA28X.C....................................................................................................291
13.13PLUSSZ.C......................................................................................................... 293
13.14ROTL.C............................................................................................................. 293
13.15STRMAKRO.C................................................................................................. 293
13.16STRMIN.C........................................................................................................ 294
13.17STRRV.C...........................................................................................................295
13.18STRSTRXT.C....................................................................................................296
13.19TOBBOSZL.C................................................................................................... 297
13.20XPLUSZOR.C................................................................................................... 297
1 BEVEZETS
A Szchenyi Istvn Egyetem klnfle informatika szakjai s szakir-
nyai C programnyelvi jegyzetignyt hivatott kielgteni ez a dokumen-
tum. Az olvasrl felttelezi, hogy tisztban van a szmtstechnikai alap-
fogalmakkal [1]. Alapos strukturlt programozsi ismereteket szerzett, s
jratos az alapvet algoritmikus elemekben [2]. Jratos mr egy program-
nyelvben s fejleszt krnyezetben. Magyarn ismer, s kezel ilyen fogal-
makat, mint:
Adatok, adattpusok s adatstruktrk.
Konstansok, vltozk s azonostk.
Vezrlsi szerkezetek: szekvencia, szelekci s iterci. Utastsok.
Tmbk s sztringek (karakterlncok).
Programszerkezeti elemek: eljrsok, fggvnyek, blokkok s prog-
rammodulok.
Lncolt adatszerkezetek: listk s fk.
Elemi bemeneti s kimeneti eszkzk, fjlok stb.
A C nyelvet tervezje, Dennis
Ritchie, a Bell Laboratriumban
fejlesztette ki az 1970es vek
K&R vgn [4], s a UNIX opercis
rendszer programnyelvnek
sznta. Ezt a vltozatot jelli az
brn a K&R. A C nyelv ezt k-
veten praktikussga miatt sz-
les krben elterjedt. Sokan k-
ANSI C
sztettek sokfle C fordtt sajt,
vagy krnyezetk ignyeinek
megfelelen. A soksznsgben
fordt amerikai nemzeti szabvnnyal
(ANSI) teremtettek rendet az
1980as vek vgn [5]. Az
ANSI C szabvnyt aztn Eurpban (ISO) is elfogadtk nhny vvel k-
sbb. Az brbl ltszik, hogy az ANSI C bvtette a K&R C halmazt.
Tovbbi trtneti ttekintshez a [4] s az [5] bevezet rszeit ajnl-
juk!
6 BEVEZETS S ALAPISMERETEK
2 JELLSEK
Figyelem felkelts. Valamely kvetkeztets levonsa az eddigiek-
bl. Esetleg: merre tallhatk tovbbi rszletek a krdses tmval kap-
csolatban.
Lexiklis ismeretek taglalsa. Valamely folyamat pontosabb rszle-
tei. Egy fogalom preczebb defincija.
Valamilyen arnylag knnyedn elkvethet, de nehezen lokalizl-
hat hiba.
Egy alapvet, gy nevezett kl szably.
Forrsprogramok s kperny tartalmak szvege.
Valamilyen konkrtummal helyettestend szintaktikai egysg.
Kulcssz vagy valamilyen azonost.
A fogalom els elfordulsnak jellsre szolgl.
A megoldand feladatokat gy jelltk. Ha a feladat lersnak vgn
{nv.C} fjlazonost ll, akkor a FGGELKben ugyanezen fejezetc-
men megtallhat egy megolds programlista is.
8 BEVEZETS S ALAPISMERETEK
3 ALAPISMERETEK
3.1 Forrsprogram
Els kzeltsben induljunk ki abbl, hogy a C program (a forrsprog-
ram) fjlazonostjban C kiterjesztssel rendelkez, ASCII kd szveg-
fjl, mely elllthat, ill. mdosthat
akrmilyen ASCII kd szvegszerkesztvel, vagy
a programfejleszt rendszer beptett szvegszerkesztjvel.
Az ASCII kd szvegfjl sorokbl ll. Egy sorban a szveg sorbeli
karaktereinek ASCII kdjai kvetkeznek rendre az egyms utni bjtok-
ban. A sorhoz vgl mg kt, a soremelst ler bjt tartozik, melyekben
egy soremels (Line Feed 10) s egy kocsi vissza (Carriage Return 13)
vezrl karakter van.
Vigyzni kell ASCII kd szvegfjlban a decimlisan 31 rtk
bjt hasznlatval, mert ez fjlvg jelzs a legtbb opercis rendszerben!
Ksztsk el els C programunkat, s mentsk el PELDA1.C nven!
/* PELDA1.C */
#include <stdio.h>
void main(void){
printf(Ez egy C program!\n); }
Fordtsuk le a programot, szerkesszk meg a vgrehajthat fjlt, s fut-
tassuk le!
A mindenki ltal gyantott vgeredmny az a kpernyn, hogy megjele-
nik a szveg, s a kvetkez sor elejn villog a kurzor:
Ez egy C program!
_
3.2 Fordts
A fordt sikeres esetben a forrsprogrambl egy vele azonos nev
(OBJ kiterjeszts) trgymodult llt el,
PELDA1.C fordt PELDA1.OBJ
1. bra: Fordts
s zeneteket jelentet meg tbbek kzt a hibkrl. A hibazenetek leg-
albb ktszintek:
(fatlis) hibazenetek s
C programnyelv 9
figyelmeztet zenetek.
A (fatlis) hibkat, melyek jobbra szintaktikai jellegek, mindig ki-
javtja a programoz, mert korrekcijuk nlkl nem kszti el a trgymo-
dult a fordt. A figyelmeztet zenetekkel azonban, melyek sok esetben a
legslyosabb problmkat jelzik, nem szokott trdni, mert a fordt ltre-
hozza a trgymodult, ha csak figyelmeztet zenetekkel zrul a fordts.
A PELDA1.C programunk els sora megjegyzs (comment). A meg-
jegyzs rsszablya ltszik a sorbl, azaz:
/* karakter prral kezddik s
*/ karakter prral vgzdik.
A megjegyzs tbb forrssoron t is tarthat, minden sorba is rhat egy,
st akr egy soron bell tbb is megadhat a szintaktikai egysgek kztt.
Egyetlen tilos dolog van: a megjegyzsek nem gyazhatk egyms-
ba!
/* Ez a befoglal megjegyzs eleje.
/* Itt a begyazott megjegyzs. */
Ez meg a befoglal megjegyzs vge. */
Vegyk szre, hogy brmely hibs program rgtn hibtlann vlik,
ha /*ot tesznk az elejre, s a zr */t elfelejtjk megadni a tovbbi
forrsszvegben!
A fordtt egybeptettk egy specilis elfeldolgozval (preprocessor),
mely az igazi fordts eltt
elhagyja a forrsszvegbl a megjegyzseket,
vgrehajtja a neki szl direktvkat, s
ezeket is elhagyja a forrsszvegbl.
elfeldolgoz
PELDA1.C PELDA1.OBJ
fordt
2. bra: Fordts pontosabban
Az elfeldolgoz direktvk egy sorban helyezkednek el, s #tel kez-
ddnek. Pontosabban # kell, legyen a sor els nem fehr karaktere.
Fehr karakterek a szkz, a soremels, a lapdobs karakter, a vz-
szintes s a fggleges tabultor karakter. Meg kell emlteni, hogy a meg-
jegyzs is fehr karakternek minsl. A fehr karakterek szolglhatnak
10 BEVEZETS S ALAPISMERETEK
\ egyetlen karakter
\\ egyetlen \ karakter
\0 karakterlnc zr bjt, melynek
minden bitje zrus
\ooo az ok oktlis szmok
Vegyk szre, hogy ha idzjelet kvnunk a karakterlnc konstans-
ba rni, akkor azt csak \ mdon tehetjk meg! Ugyanez a helyzet az esca-
pe szekvencia kezdkaraktervel, mert az meg csak megkettzve kpez
egy karaktert! Lssuk mg be, hogy a \ooo alakkal az ASCII kdtbla br-
mely karaktere lerhat! Pldul a \012 azonos a \nnel, vagy a \060 a 0
szmjegy karakter.
A printf fggvnyhvs utn ll ; utastsvg jelzs.
PELDA1.C programunk utols fehr foltja a printf, mely egyike
a szabvnyos bemenet s kimenet fggvnyeinek.
knyvtrak (LIB)
3. bra: Kapcsolszerkeszts
A programfejleszt keretrendszerben a sikeres mkdshez bizo-
nyosan be kell lltani a statikus knyvtrfjlok (library) keressi tjait.
Azt is meg kell adni termszetesen, hogy hova kerljenek a fordts s a
kapcsolszerkeszts sorn keletkez kimeneti fjlok.
3.4 Futtats
A vgrehajthat fjl a parancssorbl azonostjnak begpelsvel indt-
hat. Valsznleg a programfejleszt rendszer menjben is van egy
pont, mellyel az aktulis vgrehajthat fjl futtathat.
Tbbnyire ltezik a hrom lpst (fordts, kapcsolszerkeszts s fut-
tats) egyms utn megvalst egyetlen menpont is.
C programnyelv 13
if(k>='0'&&k<='9')++num;
else if(k==' '||k=='\n'||k=='\t')++feher;
else ++egyeb;
printf("Karakter szmok:\n"
"----------------\n"
"numerikus: %5hd\n"
"fehr: %5hd\n"
"egyb: %5hd\n"
"----------------\n"
"ssz: %10ld\n",
num, feher, egyeb,
(long)num+feher+egyeb); }
Pontostani kell a deklarcis utasts eddig megismert szintaktikjt!
<tpusmdostk> <alaptpus> azonostlista;
Az elhagyhat alaptpus alaprtelmezs szerint int. Az ugyancsak elhagy-
hat tpusmdostk az alaptpus valamilyen jellemzjt vltoztatjk meg.
int tpus esetn:
Az egsz alaprtelmezs szerint eljeles (signed), s lehetne mg
eljeltelen (unsigned). A signed s az unsigned mdostk egy-
mst kizrak.
Kt, egymst kizr hosszmdostval az egsz belsbrzolsa
bizonyosan 16 bites (short), ill.
biztos 32 bites (long).
Vgl is a klnfle int tpusok mretei gy sszegezhetk:
short <= int <= long
Vegyk szre, hogy az ismertetett szablyok szerint a short, a short
int s a signed short int azonos tpusok. A short s a short int rsmd-
nl figyelembe vettk, hogy signed az alaprtelmezs. A short felrsakor
mg arra is tekintettel voltunk, hogy a meg nem adott alaptpus alaprtel-
mezse int. Ugyanezek mondhatk el a long, a long int s a signed long
int vonatkozsban is.
Ugyan a szintaktika azt mutatja, de a deklarcis utastsban a t-
pusmdostk s az alaptpus egyszerre nem hagyhatk el!
Feltve, hogy a, b s c balrtkek, az
a=b=c=kifejezs
rtelmezse megint abbl fakad, hogy a hozzrendels a Cben opertor,
azaz:
a=(b=(c=kifejezs))
26 BEVEZETS S ALAPISMERETEK
3.7 Tmbk
Ksztsnk programot, mely a szabvny bemenetet olvassa EOF-ig!
Megllaptand s kijelzend, hogy hny A, B, C stb. karakter rkezett! A
kis s nagybetk kztt nem tesznk klnbsget! A betkn kvli tb-
bi karaktert tekintsk egy kategrinak, s ezek darabszmt is jelezzk ki!
Megoldsunkban az elvalaszto karakteres vltoz, a k, a tobbi s a betu
viszont egsz tpus. A k tartalmazza a beolvasott karaktert, s ciklusvl-
tozi funkcikat is ellt. A tobbi s a betu szmllk. A betu annyi ele-
m tmb, mint ahny bet az angol bcben van. A tobbi a betkn k-
vli tbbi karakter szmllja. Az elvalaszto karakteres vltozra azrt
van szksg, mert az eredmny csak kt oszlop pros listaknt kzlhet
egy kpernyn. Az algoritmus:
C programnyelv 29
jelentetjk meg, azaz rendre 65t, 66ot, 67et stb. ratunk ki karaktere-
sen, teht At, Bt, Ct stb. ltunk majd.
Lssuk mg be, hogy az elvalaszto vltoz rtke szkz s sor-
emels karakter kzt vltakozik, s gy kt betdarab pr kpes megjelen-
ni egy sorban. Teht az elvalaszto vltoz segtsgvel produkljuk a kt
oszlop pros eredmnylistt.
Listzni csak azt rdemes, ami valamilyen informcit hordoz!
Teht a zrus darabszm betk kijelzse teljesen felesleges! Magyarn
a for ciklusbeli printfet gy kne mdostani:
if(betu[k]>0) printf("%4c|%5d%c", k+'A',
betu[k], elvalaszto);
Megoldand feladatok:
Fokozza gy a PELDA8.Cben megoldott feladatot, hogy megszmll-
ja a magyar kezetes kis s nagybetket is!
Ksztsen programot, mely a szabvny bemenetet EOFig olvassa!
Szmllja meg s jelezze ki, hogy hny 0, 1, 2 stb. karakter rkezik! A
nem numerikus karaktereket tekintse egy kategrinak, s ezek szmt is
kzlje!
3.8 Fggvnyek
A fggvnyeket tbbflekppen csoportosthatnnk, de a legpraktiku-
sabb gy, hogy:
Vannak elre megrtak. Knyvtrakban (.LIB), vagy trgymodulok-
ban (.OBJ) tallhatk, s a kapcsol-szerkeszt kapcsolja be ket a
vgrehajthat fjlba. Pldul: a printf, a getchar, a putchar, vagy a
main stb. Minden vgrehajthat programban kell lennie egy fgg-
vnynek, az indt programnak (a main-nek), mely az egsz prog-
ram belpsi pontjt kpezi.
Mi rjuk ket. Forrsfjlokban helyezkednek el, s kdjukat a fordt
generlja.
A nyelv kzponti eleme a fggvny. A ms programozsi nyelvekben
szoksos eljrs (procedure) itt explicit mdon nem ltezik, mert a C szel-
lemben az egy olyan fggvny, aminek nincs visszaadott rtke:
void eljrs();
Jelezzk ki egy tblzatban az 1001 s 1010 kztti egsz szmok k-
bt!
32 BEVEZETS S ALAPISMERETEK
/* PELDA9.C: Kbtblzat */
#include <stdio.h>
#define TOL 1001 /* A tartomny kezdete. */
#define IG 1010 /* A tartomny vge. */
long kob(int); /* Fggvny prototpus. */
void main(void){
int i;
printf(" Szm|%11s\n-----+-----------\n", "Kbe");
for(i=TOL; i<=IG; ++i) /* Fggvnyhvs. */
printf("%5d|%11ld\n", i, kob(i)); }
long kob(int a){ /* Fggvnydefinci. */
return (long)a*a*a; }
A fggvnydefinci s a fggvnyhvs fogalmval megismerkedtnk
mr a Kapcsolszerkeszts fejezetben. A fggvnydefinciban van
meg a fggvny teste, azaz az a kd, amit a fggvny meghvsakor vg-
rehajt a processzor.
Egy fggvnyre a programban csak egyetlen definci ltezhet, s
ennek nem mondhatnak ellent a prototpusok (deklarcik)!
A fggvnydefinciban elrt visszaadott rtk tpusnak egyeznie kell
ebbl kvetkezleg a programban brhol elfordul, e fggvnyre vonat-
koz prototpusokban (deklarcikban) megadott visszatrsi rtk tpus-
sal. A meghvott fggvny akkor ad vissza rtket a hv fggvnynek a
hvs pontjra, ha a processzor kifejezssel elltott return utastst hajt
vgre benne. A valamit szolgltat fggvnyben teht lennie kell leg-
albb egy return kifejezs; utastsnak, s r is kell, hogy kerljn a ve-
zrls. A visszaadott rtk meghatrozatlan, ha a processzor nem hajt vg-
re return utastst, vagy a return utastshoz nem tartozott kifejezs.
A visszaadott rtk tpusa brmi lehet vgl is eltekintve a tmbtl
s a fggvnytl. Lehet valamilyen alaptpus, de el is hagyhat, amikor is
az alaprtelmezs lesz rvnyben, ami viszont int.
Nzzk a return szintaktikjt!
return <kifejezs>;
A fordt kirtkeli a kifejezst. Ha a fggvny visszatrsi tpusa tpus,
akkor a kifejezs tpusnak is ennek kell lennie, vagy implicit konverzi-
val ilyen tpusv alaktja a kifejezs rtkt a fordt, s csak azutn adja
vissza.
Lssuk be, hogy a PELDA9.Cbeli returnben az explicit (long)
tpusmdosts nem azrt van, hogy megtakartsuk a kifejezs rtknek
visszaads eltti implicit konverzijt! Az igazi ok az, hogy egy 16 bites
int kbe nem biztos, hogy elfr az intben! Gondoljunk 1000 kbre, ami
1000000000! Ez jval meghaladja a 32767es felsbrzolsi korltot.
C programnyelv 33
3.9 Prodzsekt
Ha a vgrehajthat program forrsszvegt tmnknt, vagy funkcin-
knt klnkln forrsfjlokban kvnjuk elhelyezni, akkor Cs prog-
ramfejleszt rendszerekben ennek semmifle akadly sincs. Be kell azon-
ban tartani a kvetkez szablyokat:
Egy s csak egy forrsmodulban szerepelnie kell az indt program-
nak (main).
Prodzsektfjlt kell kszteni, melyben felsorolandk a program tel-
jes szvegt alkot forrsfjlok.
Szedjk szt kt forrsmodulra: FOPROG.Cre s FUGGV.Cre, a
PELDA9.C programunkat!
/* FOPROG.C: Kbtblzat */
#include <stdio.h>
#define TOL 1001 /* A tartomny kezdete. */
#define IG 1010 /* A tartomny vge. */
long kob(int); /* Fggvny prototpus. */
void main(void){
int i;
printf(" Szm|%11s\n-----+-----------\n", "Kbe");
for(i=TOL; i<=IG; ++i) /* Fggvnyhvs: */
printf("%5d|%11ld\n", i, kob(i)); }
/* FUGGV.C: A fggvnydefinci. */
long kob(int a){return (long)a*a*a; }
Hozzunk ltre egy j prodzsektet! Soroljuk fel benne, vagy szrjuk bele
a kt forrsfjlt, s mentsk el, mondjuk, PRODZSI fjlazonostval! A
prodzsektfjl nvadsnl csak arra vigyzzunk, hogy egyetlen benne fel-
sorolt fjl azonostjval se egyezzen meg a neve!
Azrt nem konkretizljuk a prodzsektfjl kiterjesztst, mert az
programfejleszt rendszerenknt msms lehet!
A programfejleszt rendszerben kell lennie olyan menpontoknak,
melyekkel j prodzsektet hozhatunk ltre, meglvt tlthetnk be, nyitha-
tunk meg, menthetnk el, trlhetnk, zrhatunk le stb.
Betlttt, vagy megnyitott prodzsekt esetn azonban a fejleszt
rendszer mindaddig a prodzsekt fordtsval, kapcsolszerkesztsvel s
futtatsval foglalkozik, mg nem trljk, nem zrjuk be. Akrmilyen
36 BEVEZETS S ALAPISMERETEK
FOPROG.C FOPROG.OBJ
fordts
FUGGV.C FUGGV.OBJ
4. bra: A PRODZSI prodzsekt fordtsa
FOPROG.OBJ
FUGGV.OBJ kapcsol
indt program PRODZSI.EXE
(OBJ) szerkeszts
knyvtrak (LIB)
5. bra: A PRODZSI prodzsekt kapcsolszerkesztse
Fedezzk fel, hogy a vgrehajthat fjl a prodzsekt nevt kapja
meg!
A prodzsektet alkot fjlok kztt implicit fggsg van. Ez azt je-
lenti, hogy a prodzsekt futtatsakor csak akkor trtnik meg a trgymodul
alakjban is rendelkezsre ll forrsfjl fordtsa, ha a forrsfjl utols
mdostsnak ideje (dtuma s idpontja) ksbbi, mint a vonatkoz
trgymodul. A kapcsolszerkeszts vgrehajtshoz az szksges, hogy
a trgymodulok, ill. a knyvtrak valamelyiknek ideje ksbbi legyen a
vgrehajthat fjlnl. Az implicit fggsg fennll a forrsfjl s a bele
#include direktvval bekapcsolt fjlok kztt is. A trgymodult akkor is
jra kell fordtani, ha valamelyik forrsfjlba behozott fjl ideje ksbbi a
trgymodulnl.
Bizonyos programfejleszt rendszereknl elfordulhat, hogy az
implicit fggsgi mechanizmust gy kell kln aktivlni (menpont), ill.
hogy a forrsfjlok, s a beljk behozott fjlok kzti fggsget explicit
mdon kell biztostani.
C programnyelv 37
foprog.c foprog.obj
stdio.h
fuggv.c fuggv.obj
PRODZSI.EXE
indt prog.
knyvtrak
#include <string.h>
, s trljk ki a forrsszvegbl az strcmp prototpust s defincijt!
Vgl prbljuk ki!
Feltve, hogy s1 s s2 karaktertmbk, lssuk be, hogy C program-
ban, ugyan szintaktikailag nem helytelen, semmi rtelme sincs az ilyen
kdolsnak, hogy:
s1==s2, s1!=s2, s1>=s2, s1>s2, s1<=s2, s1<s2
E mdon ugyanis s1 s s2 memriabeli elhelyezkedst hasonltjuk ssze,
azaz bizton llthatjuk, hogy az s1==s2 mindig hamis, s az s1!=s2 pedig
mindig igaz.
A getline ciklusvltozja ugyancsak zrusrl indul, s a ciklus vgig
egyesvel halad. A ciklusmagbl ltszik, hogy a szabvny bemenetrl r-
kez karakterekkel tlti fel az s karaktertmbt. A ciklus akkor ll le,
ha az s tmb kimerlt, s nem tlthet tovbb (i>=n), vagy
ha a beolvasott karakter EOF jelzs (c==EOF), vagy
ha a bejv karakter soremels (c==\n).
Ezutn kitesszk a tmb iik elemre a lnczr zrust, s visszaadjuk it,
azaz a behozott karakterlnc hosszt.
getline fggvnynk j prblkozs az egy sor behozatalra a szabvny
bemenetrl, de van nhny problmja, ha a bemenet a billentyzet:
1. A bemeneti pufferben lev karakterek csak soremels (Enter) utn
llnak rendelkezsre, s addig nem.
2. Az EOF karakter (Ctrl+Z) rkezse nem jelenti tulajdonkppen a
bemenet vgt, mert utna mg egy soremelst is vgre kell hajtani,
hogy szlelni tudjuk.
3. Ha a bemeneti pufferben az Enter megnyomsakor nnl tbb ka-
rakter van, akkor a puffer (az egy sor) csak tbb getline hvssal ol-
vashat ki.
rjuk csak t a PELDA10.C mainjben a
while(getline(s,MAX)>0)
sort a kvetkezre
while(getline(s,4)>0)
, s a program indtsa utn gpeljk be a
JenJaniJojJani
C programnyelv 41
sorokat!
Az els kt problma az opercis rendszer viselkedse miatt van, s je-
lenleg sajnos nem tudunk rajta segteni. A msodik gondhoz mg azt is
hozz kell fznnk, hogy fjlvget a billentyzet szabvny bemeneten a
getlinenak csak res sor megadsval tudunk elidzni.
A harmadik problma viszont knnyedn orvosolhat, csak ki kell ol-
vasni a bemeneti puffert vgig a getlinebl val visszatrs eltt. Teht:
int getline(char s[],int n){
int c,i;
for(i=0;i<n&&(c=getchar())!=EOF&&c!='\n';++i)s[i=c;
s[i]='\0';
while(c!=EOF&&c!='\n') c=getchar();
return(i); }
Megoldand feladatok:
Ksztse el a kvetkez fggvnyeket, s prblja is ki ket egy rvid
programmal!
A void strcopy(char cl[], char forrs[]) tmsolja a cl karakter-
tmbbe a forrs karakterlncot a lezr nulljval egyetemben.
A void strct(char s1[], char s2[]) egyesti s1be a kt paramter
karakterlncot. Javasoljuk, hogy az algoritmus indexeljen elre s1
lnczr zrusig, s ettl kezdve csak ide kell msolni s2t!
Az unsigned strlen(char s[]) visszaadja az s karakterlnc hosszt.
Emlkezznk r, hogy a lnczr zrus indexe a karaktertmbben
egyben a karakterlnc hossza is!
A void strrv(char s[]) megfordtja a sajt helyn a paramter karak-
terlncot. Pldul a Janibl inaJnak kell szletnie.
rjon programot, mely a getline segtsgvel sorokat olvas res sorig a
szabvny bemenetrl, s megkeresi a legrvidebbet, s persze ki is jelzi a
hosszval egytt! Javasoljuk, hogy a pillanatnyi minimum mentshez
hasznlja fel az strcopy fggvnyt! {STRMIN.C}
4 TPUSOK S KONSTANSOK
A fordt a forrskdot szintaktikai egysgekre, vagy ms elnevezssel
szimblumokra, s fehr karakterekre trdeli. A tbb egymst kvet fe-
hr karakterbl csak egyet tart meg. Ebbl kvetkezleg:
Egyetlen C utasts akr szimblumonknt klnkln sorba rha-
t.
Egy sorban azonban tbb C utasts is megadhat.
Pontosan hat szimblum (int i ; float f ;) lesz a kvetkezkbl:
int
i
;
float f ;
vagy
int i; float f;
A karakter, vagy karakterlnc konstansokban elfordul, akrhny
fehr karaktert vltozatlanul hagyja azonban a fordt.
Emltettk mr, hogy a programnyelv szimblumokbl (token) ll. Most
ismertetjk a szimblum defincijt mdostott BackusNaur, metanyel-
vi lerssal:
szimblum (token):
opertor
kulcssz
elvlaszt-jel
azonost
konstans
karakterlnc (string literal)
Az rtelmezs nagyon egyszer: a felsorolt hat fogalom mindegyike
szimblum.
Az opertorokkal nem ebben a szakaszban foglalkozunk, hanem a M-
VELETEK S KIFEJEZSEKben!
A kulcsszavak:
auto double int struct
break else long switch
case enum register typedef
char extern return union
const float short unsigned
continue for signed void
50 TPUSOK S KONSTANSOK
4.1 Elvlaszt-jel
A szintaktikai egysgeket (a szimblumokat) egymstl legalbb egy fe-
hr karakterrel el kell vlasztani. Nincs szksg azonban az elvlaszt fe-
hr karakterre, ha a kt nyelvi egysg kz a szintaktikai szablyok szerint
egybknt is valamilyen elvlaszt-jelet kell rni. Az opertorok is elv-
lasztjelnek minslnek kifejezsekben.
elvlaszt-jel: (a kvetkezk egyike!)
[](){}*,:=;#
Nzzk meg nhny elvlasztjel funkcijt!
Az utastst zr pontosvessz minden pldban benne van.
A kerek zrjeleknek csoportost funkcija van kifejezsekben. Van,
amikor a szintaktika rsze. Fggvnyhvsnl az aktulis paramtereket,
fggvnydeklarciban s definciban a formlis paramtereket ebbe kell
tenni.
d = c*(a+b);
if(d==z) ++x;
fv(akt, par);
void fv2(int n);
A szgletes zrjelek tmbk deklarcijban s indexel opertorknt
hasznlatosak.
char kar, lanc[] = Sztan s Pan.;
kar = lanc[3];
A kapcsos zrjelekbe tett tbb utasts szintaktikailag egyetlen utasts-
nak minsl. A dolgot sszetett utastsnak, blokknak nevezzk.
Az sszetett utasts (blokk) zr kapcsos zrjele utn tilos pontos-
vesszt tenni!
if(a<b){ /* Illeglis pontosvessz hasznlat. */
C programnyelv 51
a=2; z=b+6; };
A csillag elvlaszt-jelnek tbbfle szerepe van a nyelvben. Eddig csak
a szorzs opertor funkcijt ismerjk!
a = 3.14*b;
Az egyenlsg jel hozzrendels opertor, s deklarcis utastsban el-
vlasztja a vltozt az inicializtortl, vagy inicializtorlisttl.
char tomb[5] = {0, 1, 2, 3, 4};
int x=5, b, c=4;
b = x+c;
A ketts kereszt elfeldolgoz (preprocessor) direktva kezdete. A sor-
beli els nem fehr karakternek kell annak lennie.
include <stdio.h>
define TRUE 1
define FALSE 0
4.2 Azonost
azonost:
nem-szmjegy
azonost nem-szmjegy
azonost szmjegy
nem-szmjegy: (a kvetkezk egyike!)
a ... z A ... Z _
szmjegy: (a kvetkezk egyike!)
0123456789
Az azonost vltozknak, fggvnyeknek, felhasznl definilta adatt-
pusoknak stb. adott, a kvetkez pontokban pontostott nv:
Kisbetvel, nagybetvel vagy alhzs (_) karakterrel kteles kez-
ddni.
A tovbbi karakterek lehetnek szmjegyek is.
Az azonost nem lehet kulcssz vagy valamilyen elredefinilt, v-
dett azonost.
Az azonostk kis- s nagybet rzkenyek, azaz az Osszeg, az
osszeg vagy az osszeG hrom klnbz azonost.
Kerlni kell a kt s az egy alhzs karakterrel kezdd nevek
hasznlatt is!
Az azonostk els, mondjuk, 31 karaktere szignifikns. Ez azt je-
lenti, hogy hosszabb nevek is hasznlhatk, de az els 31 karakte-
rkben nem klnbz azonostk ugyanannak minslnek.
52 TPUSOK S KONSTANSOK
egsz-konstans:
decimlis-konstans<egsz-uttag>
oktlis-konstans<egsz-uttag>
hexadecimlis-konstans<egsz-uttag>
decimlis-konstans:
nemzrus-szmjegy
decimlis-konstans szmjegy
oktlis-konstans:
0
oktlis-konstans oktlis-szmjegy
hexadecimlis-konstans:
0xhexadecimlis-szmjegy
0Xhexadecimlis-szmjegy
hexadecimlis-konstans hexadecimlis-szmjegy
nemzrus-szmjegy: (a kvetkezk egyike!)
123456789
oktlis-szmjegy: (a kvetkezk egyike!)
01234567
hexadecimlis-szmjegy: (a kvetkezk egyike!)
0123456789abcdef ABCDEF
egsz-uttag:
unsigned-uttag<long-uttag>
long-uttag<unsigned-uttag>
unsigned-uttag: (a kvetkezk egyike!)
uU
long-uttag: (a kvetkezk egyike!)
lL
A definci szerint:
Az egsz konstans lehet decimlis, oktlis s hexadecimlis.
Az egsz konstansnak nincs eljele (pozitv), azaz a negatv egsz
konstans eltt egy egyoperandusos mnusz opertor ll.
A decimlis egsz konstans int, long int, vagy unsigned long int
belsbrzols a konstans rtktl fggen alaprtelmezs sze-
rint. Az oktlis s hexadecimlis egsz konstans az rtktl fgg-
en int, unsigned int, long int, vagy unsigned long int belsbrzo-
ls.
Decimlis Oktlis Hexadecimlis Tpus
032767 0077777 0X00X7FFF int
0100000 0X80000XFFFF unsigned
01777777
32767 02000000 0X10000 long
2147483647 017777777777 0X7FFFFFFF
58 TPUSOK S KONSTANSOK
karakterlnc lesz.\n);
rjunk meg nhny karakterlncot kezel fggvnyt!
Az unsigned strlen(char s[]) a paramter karakterlnc hosszt szolgl-
tatja.
Indtsunk egy vltozt zrustl, s indexeljnk elre vele a karakterln-
con, mg a lnczr nullt el nem rjk! Ez az index a karakterlnc hossza
is egyben.
unsigned strlen(char s[]){
unsigned i=0u;
while(s[i]!=\0) ++i;
return i; }
A void strcopy(char cl[], char forrs[]) a hozzrendelst valstja
meg a karakterlncok krben azzal, hogy a forrs karakterlncot tm-
solja a cl karaktertmbbe.
Indexeljnk most is vgig egy vltozval a forrs karakterlncon a lez-
r zrusig! Kzben minden indexre rendeljk hozz a forrs tmbelemet
a cl tmbelemhez! Vigyzzunk, hogy a lnczr nulla is tkerljn!
void strcopy(char cl[], char forrs[]){
int i=0;
while((cl[i]=forrs[i])!=0) ++i; }
Javtsunk kicsit ezen a megoldson! A whilebeli relci elhagyhat,
hisz a hozzrendels is mindig igaz (nem zrus), mg a forrs[i] nem
lnczr zrus. Belthat, hogy a \0 karakter is tkerl, mert a while
csak a hozzrendels vgrehajtsa utn veszi csak szre, hogy kifejezse
hamiss (zruss) vlt. Teht:
while(cl[i]=forrs[i]) ++i;
Lssuk be, hogy a
while(cl[i++]=forrs[i]);
is tkletesen funkcionl, hisz
Ellltja a forrs tmb iik elemt.
Ezt hozzrendeli cl tmb iik elemhez.
Az uttag ++ miatt mellkhatsknt kzben i rtke is n egyet.
A legjobb megoldsunk teht:
void strcopy(char cl[], char forrs[]){
int i=0;
while(cl[i++]=forrs[i]); }
70 TPUSOK S KONSTANSOK
4.5 Deklarci
A deklarci megteremti a kapcsolatot az azonost s az objektum k-
ztt, ill. rgzti pldul tbbek kztt az objektum adattpust. Ktfle
deklarcirl beszlhetnk:
72 TPUSOK S KONSTANSOK
fggvnyek,
tpusok,
tpusok tmbjei,
enum konstansok s cmkk.
Deklarlhatk mg a kvetkez ksbbi fejezetekben trgyalt objek-
tumok is: struktra, uni s utasts cmkk, struktra s unitagok, vala-
mint elfeldolgoz makrk.
A deklartor szintaktika rekurzivitsa miatt egszen komplex deklarto-
rok is megengedettek. Ezt el szoks kerlni tpusdefincival (typedef). A
deklarci metanyelvi lersa a kvetkez:
deklarci:
deklarci-specifiktorok<init-deklartorlista>
deklarci-specifiktorok:
trolsi-osztly-specifiktor<deklarci-specifiktorok>
tpusspecifiktor<deklarci-specifiktorok>
init-deklartorlista:
init-deklartor
init-deklartorlista, init-deklartor
init-deklartor:
deklartor
deklartor=inicializtor
inicializtor:
hozzrendels-kifejezs
{inicializtorlista}
{inicializtorlista ,}
inicializtorlista:
inicializtor
inicializtorlista, inicializtor
trolsi-osztly-specifiktor:
auto
register
extern
static
typedef
tpusspecifiktor:
void
char
short
int
long
float
double
signed
74 TPUSOK S KONSTANSOK
unsigned
const
volatile
struktra-vagy-uni-specifiktor
enum-specifiktor
typedef-nv
typedef-nv:
azonost
deklartor:
<mutat>direkt-deklartor
direkt-deklartor:
azonost
(deklartor)
direkt-deklartor [<konstans-kifejezs>]
direkt-deklartor (paramter-tpus-lista)
direkt-deklartor (<azonostlista>)
konstans-kifejezs:
feltteles-kifejezs
azonostlista:
azonost
azonostlista, azonost
A mutatkkal, a struktrval, az unival, a fggvnyekkel, az utas-
ts cmkkkel s a makrkkal ksbbi szakaszokban s fejezetekben fog-
lalkozunk, gy a vonatkoz metanyelvi lersok is ott tallhatk.
A trolsi-osztly-specifiktorokat teljes rszletessggel majd egy k-
sbbi fejezetben taglaljuk, de kzlk kettrl (auto s extern) mr sz
volt a BEVEZETS S ALAPISMERETEK szakaszban. A kvetkez
fejezet nmi elzetes kpet ad a typedefrl.
A tpusspecifiktorokat alaptpusokra s tpusmdostkra bontottuk ko-
rbban. A tpusmdostk s alaptpusok megengedett, egyttes hasznla-
tt e szakasz elz fejezeteiben tisztztuk. A const s a volatile viszont
brmely alaptpussal s tpusmdostval egytt szinte korltozs nlkl
hasznlhat.
A deklartor egyedi azonostt hatroz meg. Mikor az azonost megje-
lenik egy vele egyeztpus kifejezsben, akkor a vele elnevezett objek-
tum rtkt eredmnyezi.
A konstans-kifejezs mindig fordtsi idben is meghatrozhat kons-
tans rtkk rtkelhet ki, azaz rtke bele kell hogy frjen a tpus br-
zolsi hatraiba. A konstans kifejezs brhol alkalmazhat, ahol konstans
egybknt hasznlhat. A konstans kifejezs operandusai lehetnek egsz
konstansok, karakter konstansok, lebegpontos konstansok, enumerto-
rok, tpusmdost szerkezetek, sizeof kifejezsek, stb. A konstans kifeje-
C programnyelv 75
5 MVELETEK S KIFEJEZSEK
A mveleteket a nyelv opertorokkal (mveleti jelekkel) valstja meg.
A mveletek lehetnek:
Egyoperandusosak. Alakjuk opertor operandus, ahol az operan-
dus az a kifejezs, melyen az egyoperandusos mveletet el kell v-
gezni. Pldul: 6, vagy a sizeof(int) stb.
Ktoperandusosak, azaz operandus1 opertor operandus2 form-
jak. Pldul: a + b.
Hromoperandusosak: A C-ben egyetlen ilyen mvelet van, az n.
feltteles kifejezs. Pldul: (a > b) ? a : b rtke a, ha a > b s b
msklnben.
opertor: (a kvetkezk egyike!)
[ ] ( ) . -> ++ -- & * + - ~ ! sizeof / % << >> < > <= >= == != = ^ | && || ?: *= /= +=
-= %= <<= >>= &= ^= |= ,
A kifejezs opertorok, operandusok (s elvlaszt-jelek) sorozata, mely
az albbi tevkenysgek valamilyen kombincijt valstja meg:
rtket szmt ki.
Objektumot vagy fggvnyt r el.
Mellkhatst generl.
A kifejezsbeli operandusokat elsdleges kifejezsnek nevezik.
elsdleges-kifejezs:
azonost
konstans
karakterlnc
(kifejezs)
kifejezs:
hozzrendels-kifejezs
kifejezs, hozzrendels-kifejezs
A konstansokat, a karakterlncot trgyaltuk a TPUSOK S KONS-
TANSOK szakaszban, a hozzrendels-kifejezst definilni fogjuk a hoz-
zrendels opertoroknl. Az azonost lehet brmilyen egsz vagy lebe-
gpontos tpus. Lehet enum, tmb, mutat, struktra, uni, vagy fgg-
vny tpus. Lehet teht:
vltoz azonost belertve az indexel opertort is, azaz az azono-
st[kifejezs]-t is, s az uni, ill. a struktratagokat, vagy
78 MVELETEK S KIFEJEZSEK
egyoperandusos-kifejezs:
uttag-kifejezs
++ egyoperandusos-kifejezs
-- egyoperandusos-kifejezs
egyoperandusos-opertor eltag-kifejezs
sizeof(egyoperandusos-kifejezs)
sizeof(tpusnv)
egyoperandusos-opertor: ( a kvetkezk egyike!)
&*+-~!
eltag-kifejezs:
egyoperandusos-kifejezs
(tpusnv) eltag-kifejezs
tpusnv:
tpusspecifiktor-lista<absztrakt-deklartor>
absztrakt-deklartor:
mutat
<mutat><direkt-absztrakt-deklartor>
direkt-absztrakt-deklartor:
(absztrakt-deklartor)
<direkt-absztrakt-deklartor>[<konstans-kifejezs>]
<direkt-absztrakt-deklartor>(<paramter-tpus-lista>)
A tpusnv az adattpus tpusneve. Szintaktikailag az adott tpus objek-
tum olyan deklarcija, melybl hinyzik az objektum neve.
A hozzrendels-kifejezst, melyrl most csak annyit jegyznk meg,
hogy nem balrtk, majd a hozzrendelsi mveleteknl ismertetjk!
vagy-kifejezs:
kizr-vagy-kifejezs
vagy-kifejezs | kizr-vagy-kifejezs
Az egyenlsgi-kifejezs defincija a relciknl megtallhat!
Ha szksges, akkor a mvelet elvgzse eltt a fordt implicit tpus-
konverzit hajt vgre az egsz tpus operandusok rtkn. Az eredmny
tpusa az operandusok konverzi utni tpusa. A mvelet bitrl-bitre val-
sul meg az operandusok rtkn, s egy bitre vonatkoztatva az eredmny
gy nz ki:
K1 K2 K1 & K2 K1 ^ K2 K1 | K2
0 0 0 0 0
1 0 0 1 1
0 1 0 1 1
1 1 1 0 1
Befejezve az egyes komplemensnl megkezdett pldt, az x|maszk rt-
ke 11111000111100102. llthatjuk, hogy az eredmnyben minden olyan
bit egy, ami a maszkban az volt. Az x^x eredmnye biztosan tiszta z-
rus. Az x&~maszk rtke 00001000000000102. Megemltjk, hogy az
eredmny minden olyan bitpozcijn 0 van, ahol a maszk bitje 1. Teht a
kifejezs azokat a biteket bizonyosan trlte, ahol a maszk bit 1 volt.
Nem szabad sszekeverni a logikai vagy (||) s a bitenknt vagy (|),
ill. a logikai s (&&) s a bit szint s (&) mveleteket! Feltve, hogy kt,
egsz tpus vltoz rtke: a=2 s b=4, akkor az
a && b 1 (igaz)
de az
a & b 0
Az ANSI szabvny szerint a bit szint mveletek signed egsze-
ken implementcifggk. A legtbb C fordt azonban signed egszeken
ugyangy dolgozik, mint unsignedeken. Pldul short intben gondol-
kodva a 16 & 99 eredmnye 96, mert:
1111111111110000&0000000001100011 0000000001100000
A fjl utols mdostsnak dtumt s idejt egy-egy szban, azaz C
nyelvi fogalmakkal: egy-egy unsigned short int-ben troljuk. A kt sz
bitfelosztsa legyen a kvetkez:
dtum v 1980 hnap nap
id ra perc 2 msodperc
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
C programnyelv 95
putchar((maszk&x)? 1: 0);
A PELDA4.Cbeli
for(ft=ALSO; ft<=FELSO; ft=ft+LEPES)
100 MVELETEK S KIFEJEZSEK
most gy rhat:
for(ft=ALSO; ft<=FELSO; ft+=LEPES)
#include <stdio.h>
#include <string.h> /* Az strlen miatt! */
#define INP 66 /* Az input puffer mrete. */
void strrv(char s[]){
int also, felso, csere;
for(also=0, felso=strlen(s)-1; also<felso;
++also, --felso){
csere=s[also]; s[also]=s[felso]; s[felso]=csere; } }
int getline(char s[],int n){
int c,i;
for(i=0;i<n&&(c=getchar())!=EOF&&c!='\n';++i) s[i]=c;
s[i]='\0';
while(c!=EOF&&c!='\n') c=getchar();
return(i); }
void main(void){
char s[INP+1]; /* Az input puffer. */
printf("A szabvny bemenet sorainak megfordtsa.\n"
"Programvg: res sor.\n\n");
while(printf("Jhet a sor! "), getline(s,INP)){
strrv(s);
printf("Megfordtva: %s\n", s); } }
A STRING.H fejfjlt bekapcsolva rendelkezsre ll az strrv szab-
vny knyvtri vltozata, mely ugyanilyen paramterezs s funkcij,
de strrev a neve, s ms egy kicsit a visszatrsi rtknek a tpusa.
Vegyk szre, hogy a mainbeli whileban is vesszs kifejezst
hasznltunk!
Olyan szvegkrnyezetben, ahol a vessz szintaktikai jelents, a
vessz opertort csak zrjelbe tett csoporton bell szabad hasznlni.
Ilyen helyek: az inicializtorlista pldul, vagy a fggvny paramterlist-
ja. A
fv(b, (a = 2, t += 3), 4);
kitnen mutatja, hogy az fv fggvny hrom paramterrel rendelkezik. A
hvsban a msodik paramter vesszs kifejezs, ahol a elbb 2 rtk
lesz, aztn t megn hrommal, s ezt az rtket kapja meg a fggvny is
msodik aktulis paramterknt. Ha a fggvny prototpusa mst nem
mond, akkor a msodik paramter tpusa t tpusa.
Fedezzk fel, hogy itt nem arrl van sz, hogy a fordt a kvetkez
fordtskor msknt rendezi t a kifejezst, hisz a fordts determiniszti-
kus dolog, hanem arrl, hogy klnbz C fordtk msms eredmnyre
juthatnak!
Problma lehet az olyan kifejezssel,
melyben ugyanazt az objektumot egynl tbbszr mdostjuk, ill.
melyben ugyanazon objektum rtkt vltoztatjuk s felhasznljuk.
Pldul:
i = v[i++]; /* Dntsk el, mit is akarunk i-vel! */
i = a+++b[a]; /* b indexe attl fgg, hogy az sszeads
melyik tagjt rtkeli ki elbb a fordt. */
A fentiek akkor is igazak, ha kifejezsnket jl sszezrjelezzk:
int osszeg=0;
sum = (osszeg=3)+(++osszeg);/* sum == 4 vagy 7 ? */
Segdvltozk bevezetsvel a dolgok midig egyrtelmsthetk:
int seged, osszeg=0;
seged = ++osszeg; /* seged == 1, osszeg == 1. */
sum = (osszeg=3)+seged; /* sum == 4. */
Ha a szintaktika rgzti a kirtkelsi sorrendet (az &&, a ||, a ?: s a
vessz opertor esetben ez gy van), akkor ott brmit megtehetnk.
Pldul:
sum = (i=3, i++, i++); /* OK, sum == 4 s i == 5. */
A kifejezs kirtkelsi sorrendjt ugyan () prokkal befolysolhatjuk:
f = a*(b+c);
, de asszociatv s kommutatv opertorok operandusait mg agyonzr-
jelezve is sszecserlheti a fordt, hisz felttelezheti, hogy a kifejezs
rtkt ez nem befolysolja:
f = (a+b) + (c+d);
Hatrozatlan a fggvny aktulis paramtereinek kirtkelsi sorrendje
is:
printf(%d %d\n, ++n, fv(n));
A bitenknti opertorok prioritsa alacsonyabb a relciknl, gy a
c & 0XF == 8
mindig hamis, mert az elbb kirtkelsre kerl egyenlsgi relci so-
hasem lehet igaz. A kifejezs helyesen:
C programnyelv 105
(c & 0XF) == 8.
Vigyzzunk a hozzrendels (=) s az egyenl relci (==) opertor fel-
cserlsre, mert pldul az
if( i = 2 ) utasts1; else utasts2;
else gra sohasem jut el a vezrls tekintettel arra, hogy a 2 hozzrende-
lse ebben az letben sem vlik hamiss.
gyeljnk azokkal a kifejezsekkel is, melyekben csak logikai s (&&)
vagy csak logikai vagy (||) mveletek vannak, mert ezeket balrl jobbra
haladva
&& esetn csak az els hamis tagig, ill.
|| opertornl csak az els igaz tagig
fogja kirtkelni a fordt! Az
x && y++
kifejezsben y nvelse csak akkor trtnik meg, ha x nem zrus.
Kifejezs kirtkelse kzben addhatnak thidalhatatlan szitu-
cik. Ilyenek
a zrussal val oszts s
a lebegpontos tl vagy alulcsorduls.
jra felhvjuk azonban a figyelmet arra, hogy a nyelvben nem lte-
zik sem egsz tl, sem alulcsorduls!
106 UTASTSOK
6 UTASTSOK
Az utastsokat ha mst nem mondanak megadsuk sorrendjben
hajtja vgre a processzor. Az utastsoknak nincs rtke. Vgrehajtsuk
hatssal van bizonyos adatokra, vagy programelgazst valstanak meg
stb. Defincijuk a kvetkez:
utasts:
sszetett-utasts
cmkzett-utasts
kifejezs-utasts
szelekcis-utasts
itercis-utasts
ugr-utasts
7 ELFELDOLGOZ (PREPROCESSOR)
A fordt els menete sorn mindig meghvja az elfeldolgozt a forrs-
fjlra.
Ha szeretnnk tudni, hogy fest az elfeldolgozson tesett forrsfjl
(a fordtsi egysg), akkor a programfejleszt rendszerben utna kell nz-
ni, hogy tehetjk lthatv az elfeldolgozs eredmnyt. Az elfeldolgo-
zott forrsfjlban aztn megtekinthetjk:
a makrk kifejtst,
a behozott (include) fjlokat,
a feltteles fordtst,
a szomszdos karakterlnc konstansok egyestst,
a direktvk elhagyst s
a megjegyzsek kimaradst (helyettestst egyetlen szkz karak-
terrel).
A nem karakter, vagy karakterlnc konstansban elfordul, egymst
kvet, tbb fehr karaktert mindig eggyel helyettesti az elfeldolgoz.
Az elfeldolgoz direktvk rsszablya, mely fggetlen a C nyelv tb-
bi rsztl, a kvetkez:
A sor els, nem fehr karakternek #-nek kell lennie.
A #-et kvetheti aztn fehr karakter a soremelst kivve. A sorokra
trdels nagyon lnyeges elem, mert az elfeldolgoz sorokra bont-
va elemzi a forrsszveget.
A karakter konstansban, a karakterlnc konstansban s a megjegy-
zsben lev # karakter nem minsl elfeldolgoz direktva kezde-
tnek.
A direktvkat - miutn nem C utastsok - tilos pontosvesszvel le-
zrni!
Ha a direktvban a soremelst \ karakter elzi meg, akkor a kvet-
kez sor folytatssornak minsl, azaz az elfeldolgoz elhagyja a
\t s a soremelst, s egyesti a kt sort.
Az elfeldolgoz direktvkba megjegyzs is rhat.
120 ELFELDOLGOZ DIREKTVK
8 OBJEKTUMOK S FGGVNYEK
Az azonostk rtelmt a deklarcik rgztik. Tudjuk, hogy a dekla-
rci nem jelent szksgkppen memriafoglalst. Csak a defincis dek-
larci ilyen.
deklarci:
deklarci-specifiktorok<init-deklartorlista>
init-deklartorlista:
init-deklartor
init-deklartorlista, init-deklartor
init-deklartor:
deklartor
deklartor=inicializtor
Az inicializtorokkal s inicializtorlistkkal a BEVEZETS S A-
LAPISMERETEK szakasz Inicializls fejezetben foglalkoztunk. A
deklartorok a deklarland neveket tartalmazzk. A deklarci-specifi-
ktorok tpus s trolsi osztly specifiktorokbl llnak:
deklarci-specifiktorok:
trolsi-osztly-specifiktor<deklarci-specifiktorok>
tpusspecifiktor<deklarci-specifiktorok>
tpusmdost<deklarci-specifiktorok>
A tpusspecifiktorokat a TPUSOK S KONSTANSOK szakaszban
trgyaltuk, s ezek kzl kivettk a const s a volatile tpusmdostkat.
8.1.3.5 Lthatsg
A forrskd azon rgija egy azonostra vonatkozan, melyben leglis
mdon elrhet az azonosthoz kapcsolt objektum. A hatskr s a ltha-
tsg tbbnyire fedik egymst, de bizonyos krlmnyek kztt egy ob-
jektum ideiglenesen rejtett vlhat egy msik ugyanilyen nev azonost
feltnse miatt. A rejtett objektum tovbbra is ltezik, de egyszeren az
azonostjval hivatkozva nem rhet el, mg a msik ugyanilyen nev
azonost hatskre le nem jr. Pldul:
{ int i; char c = z; /* Az i s c hatskre indul. */
i = 3; /* int i-t rtk el. */
/* . . . */
{ double i = 3.5e3; /* double i hatskre itt kezd-
dik, s elrejti int i-t, br */
/* . . . */ /* hatskre nem sznik meg. */
c = A; /* char c lthat s hatskre
itt is tart. */
} /* A double i hatskrnek vge */
/* int i s c hatskrben s lthatk. */
++i;
144 OBJEKTUMOK S FGGVNYEK
8.2 Fggvnyek
A fggvnyekkel kapcsolatos alapfogalmakat tisztztuk mr a BEVE-
ZETS S ALAPISMERETEK szakaszban, de fussunk t rajtuk mg
egyszer!
A fggvnynek kell legyen defincija, s lehetnek deklarcii. A fgg-
vny defincija deklarcinak is minsl, ha megelzi a forrsszvegben
146 OBJEKTUMOK S FGGVNYEK
8.2.1 Fggvnydefinci
A fggvnydefinci specifiklja a fggvny nevt, a formlis paramte-
rek tpust, sorrendjt s szmt, valamint a visszatrsi rtk tpust, a
fggvny trolsi osztlyt s ms attribtumait. A fggvnydefinciban
van a fggvny teste is, azaz a hasznlatos loklis vltozk deklarcija,
s a fggvny tevkenysgt megszab utastsok. A szintaktika:
C programnyelv 147
fordtsi-egysg:
kls-deklarci
fordtsi-egysg kls-deklarci
kls-deklarci:
fggvnydefinci
deklarci
fggvnydefinci:
<deklarci-specifiktorok> deklartor <deklarcilista> sszetett-utasts
deklartor:
<mutat> direkt-deklartor
direkt-deklartor:
direkt-deklartor(paramter-tpus-lista)
direkt-deklartor(<azonostlista>)
deklarcilista:
deklarci
deklarcilista deklarci
A kls-deklarcik hatskre a fordtsi egysg vgig tart. A kls-
deklarci szintaktikja egyezik a tbbi deklarcival, de fggvnyeket
csak ezen a szinten szabad definilni, azaz:
tilos fggvnyben msik fggvnyt definilni!
A deklarci s az azonostlista defincik a TPUSOK S
KONSTANSOK szakasz Deklarci fejezetben megtallhatk. A muta-
tkat a kvetkez szakasz tartalmazza.
A fggvnydefincibeli sszetett-utasts a fggvny teste, mely tartal-
mazza a hasznlatos loklis vltozk deklarciit, a klsleg deklarlt t-
telekre val hivatkozsokat, s a fggvny tevkenysgt megvalst uta-
stsokat.
Az opcionlis deklarci-specifiktorok s a ktelezen megadand
deklartor egytt rgztik a fggvny visszatrsi rtk tpust s nevt. A
deklartor termszetesen fggvnydeklartor, azaz a fggvnynv s az t
kvet zrjel pr. Az els direkt-deklartor(paramter-tpus-lista) alak a
fggvny j (modern) stlus defincijt teszi lehetv. A deklartor
szintaktikban szerepl direkt-deklartor a modern stlus szerint a defini-
ls alatt ll fggvny nevt rgzti, s a kerek zrjelben ll param-
ter-tpus-lista specifiklja az sszes paramter tpust. Ilyen deklartor tu-
lajdonkppen a fggvny prototpus is. Pldul:
char fv(int i, double d){
/* . . . */ }
A msodik direkt-deklartor(<azonostlista>) forma a rgi stlus defi-
nci:
char fv(i, d)
148 OBJEKTUMOK S FGGVNYEK
int i;
double d; {
/* . . . */ }
A tovbbiakban csak az j stlus fggvnydefincival foglalkozunk, s
nem emlegetjk tovbb a rgit!
deklarci-specifiktorok:
trolsi-osztly-specifiktor <deklarci-specifiktorok>
tpusspecifiktor <deklarci-specifiktorok>
tpusmdost <deklarci-specifiktorok>
tpusmdost: (a kvetkezk egyike!)
const
volatile
A trolsi-osztly-specifiktorok s a tpuspecifiktorok defincii a
TPUSOK S KONSTANSOK szakasz Deklarci fejezetben megte-
kinthetk!
paramterdeklarci:
deklarci-specifiktor deklartor
deklarci-specifiktor <absztrakt-deklartor>
absztrakt-deklartor:
mutat
<mutat><direkt-absztrakt-deklartor>
direkt-absztrakt-deklartor:
(absztrakt-deklartor)
<direkt-absztrakt-deklartor>[<konstans-kifejezs>]
<direkt-absztrakt-deklartor>(<paramter-tpus-lista>)
A paramterdeklarci nem tartalmazhat ms trolsi-osztly-specifi-
ktort, mint a registert. A deklarci-specifiktor szintaktikabeli tpus-
specifiktor elhagyhat, ha a tpus int, s egybknt megadjk a register
trolsi osztly specifiktort. sszestve a formlis paramterlista egy ele-
mnek formja a kvetkez:
<register> tpusspecifiktor <deklartor>
Az autonak deklarlt fggvnyparamter fordtsi hiba!
A C szablyai szerint a paramter lehet brmilyen aritmetikai tpus. Le-
het akr tmb is, de fggvny nem (az erre mutat mutat persze megen-
gedett). A paramter lehet termszetesen struktra, uni vagy mutat is,
melyekrl majd ksbbi szakaszokban lesz sz. A paramterlista lehet
void is, ami nincs paramter jelents.
A formlis paramterazonostk nem definilhatk t a fggvny
testnek kls blokkjban, csak egy ebbe begyazott bels blokkban, azaz
a formlis paramterek hatskre s lettartama a fggvnytest teljes leg-
kls blokkja. Az egyetlen rjuk is leglisan alkalmazhat trolsi osztly
specifiktor a register. Pldul:
int f1(register int i){/* ... */}/* Igny regiszteres
paramter tadsra. */
A const s a volatile mdostk hasznlhatk a formlis paramter dek-
lartorokkal. Pldul a
void f0(double p1, const char s[]){
/* . . . */
s[0]=A;
/* Szintaktikai hiba. */}
constnak deklarlt formlis paramtere nem lehet balrtk a fggvny
testben, mert hibazenetet okoz.
Ha nincs tadand paramter, akkor a paramterlista helyre a definci-
ban s a prototpusban a void kulcssz rand:
int f2(void){/* ... */} /* Nincs paramter. */
C programnyelv 151
absztrakt-deklartor:
mutat
<mutat><direkt-absztrakt-deklartor>
direkt-absztrakt-deklartor:
(absztrakt-deklartor)
<direkt-absztrakt-deklartor>[<konstans-kifejezs>]
<direkt-absztrakt-deklartor>(<paramter-tpus-lista>)
Az absztrakt-deklartorban mindig megllapthat az a hely, ahol az azo-
nostnak lennie kellene, ha a konstrukci deklarcin belli deklartor
lenne. A kvetkez tpusnevek jelentse: int, 10 elem int tmb s nem
meghatrozott elemszm int tmb:
int, int [10], int []
Lssuk be, hogy a fggvny prototpus a kd dokumentlsra is j!
Szinte rgtn tudunk mindent a fggvnyrl:
void strcopy(char cel[], char forras[]);
A
<tpus> fv(void);
olyan fggvny prototpusa, melynek nincsenek paramterei.
Norml esetben a fggvny prototpus olyan fggvnyt deklarl, mely
fix szm paramtert fogad. Lehetsg van azonban vltoz szm vagy
tpus paramter tadsra is. Az ilyen fggvny prototpus paramterlis-
tja ...-tal vgzdik:
<tpus> fv(int, long, ...);
A fixen megadott paramtereket fordtsi idben ellenrzi a fordt, s a
vltoz szm vagy tpus paramtert viszont a fggvny hvsakor tpus-
ellenrzs nlkl adja t a veremben.
Az STGARG.H fejfjlban vannak olyan makrk, melyek segtik a
felhasznli, vltoz szm paramteres fggvnyek megalkotst! A t-
mra visszatrnk mg a MUTATK kapcsn!
Nzznk nhny plda prototpust!
int f(); /* int-et visszaad fggvny, melynek
paramtereirl nincs informcink. */
int f1(void); /* Olyan int-et szolgltat fggvny,
melynek nincsenek paramterei. */
int f2(int, long);/* int-et visszaad fggvny, mely
elsnek egy int, s aztn egy long
paramtert fogad. */
int pascal f3(void);/*Paramter nlkli, int-et
szolgltat pascal fggvny. */
int printf(const char [], ...);/* int-tel visszatr
fggvny egy fix, s nem meghatrozott
154 OBJEKTUMOK S FGGVNYEK
i<=honap[ho]) return 1; } }
return 0; }
Megoldand feladatok:
Vltoztasson gy az int datume(const char s[]) fggvnyen, hogy akr
egyjegy is lehessen:
az vszm, majd
a hnap s a napszm is!
int indexe(char s[], char t[]) s int indexu(char s[], char t[]) fggv-
nyek ksztendk, melyek meghatrozzk s visszaadjk a t paramter ka-
rakterlnc s karaktertmbbeli els, illetve utols elfordulsnak indext!
Prblja is ki egy rvid tesztprogrammal a fggvnyeket! {INDEXEU.C}
rjon olyan szoftvert, mely megkeresi egy prba karakterlnc sszes el-
fordulst a szabvny bemenetrl rkez sorokban!
9 MUTATK
A nyelvben a mutatknak kt fajtja van:
(adat) objektumra mutat mutatk s
fggvnyre (kd) mutat mutatk.
Brmilyenek is legyenek, a mutatk memria cmek trolsra szolglnak.
Elbb az adatmutatkkal fogunk foglalkozni. A mutat mindaddig, mg
errl kln nem szlunk, jelentsen adatmutatt!
A tpus tpus mutat tpus tpus objektum cmt tartalmazhatja. A mu-
tatk unsigned egszek, de sajt szablyaik s korltozsaik vannak a
hozzrendelsre, a konverzira s az aritmetikra.
Miutn a mutat is skalr objektum, ltezik a mutatra mutat mutat
is. A mutatk azonban tbbnyire ms skalr vagy void objektumokra (vl-
tozkra), ill. aggregtumokra (tmbkre, struktrkra s unikra) mutat-
nak.
9.1 Mutatdeklarcik
A mutatdeklarci elnevezi a mutat vltozt, s rgzti annak az ob-
jektumnak a tpust, melyre ez a vltoz mutathat.
Teht csak egy bizonyos tpusra (elredefiniltra - belertve a void-ot is
- vagy felhasznl definiltra) mutat mutat deklarlhat
tpus *azonost;
mdon, amikor is az azonost nev mutat tpus tpus objektum cmt
veheti fel.
Vegyk szre, hogy tpus * az azonost tpusa! Pldul az
int *imut;
int *fv(char *);
deklarcik alapjn: imut int tpus objektumra mutat mutat, fv int t-
pus cmet visszaad, s egy char objektumra mutat paramtert fogad
fggvny.
Ha a definilt mutat statikus lettartam, akkor tiszta zrus kezdrt-
ket kap implicit mdon. A fordt tiszta zrus cmen nem helyez el sem
objektumot, sem fggvnyt, s gy a zrus cm (az n. NULL mutat) spe-
cilis felhasznls. Magt a NULL mutatt a szabvnyos fejfjlokban
(pldul az STDIO.Hban) definilja a nyelv.
162 MUTATK
/* . . . */
printf("val cme (%p) van ptr-ben (%p).\n", &val, ptr);
y = *ptr + 3; /* y = val +3 tulajdonkppen. */
y = sqrt((double) ptr);/* y = sqrt(val). */
*ptr += 6; /* val += 6. */
(*ptr)++; /* Zrjel nlkl a ptr-t
inkrementltatnnk. */
printf("val rtke %d.\n", val);
printf("A ptr cmen lev rtk %d.\n", *ptr); }
Fedezzk fel, hogy a cm, vagy mutattartalom kijelzshez haszn-
latos tpuskarakter a p a formtumspecifikciban, s hogy a printf para-
mterlistjban cm rtk kifejezs is llhat, persze akr indirekcival is!
Vigyzzunk nagyon! Ha egy vltoznak nem adunk kezdrtket, s
mondjuk, hozzadogatjuk egy tmb elemeit, akkor a vgeredmny zld-
sg, s a dolog szarvashiba. Ha mutatnak nem adunk kezdrtket, s a
benne lev szemtre, mint cmre, runk ki rtket indirekcival, akkor
az dupln szarvashiba. A szemttel, mint cmmel valahol pancsolunk
a memriban, s fellrjuk valami egszen ms objektum rtkt, s a hiba
is egszen ms helyen jelentkezik, mint ahol elkvettk.
9.1.5 Mutatdeklartorok
deklartor:
<mutat>direkt-deklartor
direkt-deklartor:
azonost
(deklartor)
direkt-deklartor [<konstans-kifejezs>]
direkt-deklartor (paramter-tpus-lista)
direkt-deklartor (<azonostlista>)
mutat:
*<tpusmdost-lista>
*<tpusmdost-lista>mutat
tpusmdost-lista:
tpusmdost
tpusmdost-lista tpusmdost
tpusmdost: (a kvetkezk egyike!)
const
volatile
A deklartorok szerkezetileg az indirekcihoz, a fggvnyhez s a
tmbkifejezshez hasonltanak, s csoportostsuk is azonos. A deklartort
kvetheti egyenlsgjel utn inicializtor, de mindig deklarci-specifi-
ktorok elzik meg. A deklarci-specifiktorok trolsi-osztly-specifi-
ktor s tpusspecifiktor sorozat tulajdonkpp, s igazbl nem csak
egyetlen deklartorra vonatkoznak, hanem ezek listjra.
Megkrjk az olvast, hogy lapozzon vissza egy pillanatra a TPU-
SOK S KONSTANSOK Deklarci fejezethez!
A direkt-deklartor definci els lehetsge szerint a deklartor egy
egyedi azonostt deklarl, melyre a trolsi osztly egy az egyben vonat-
166 MUTATK
*((uttag-kifejezs) + (kifejezs))
mveletet valstja meg. A fordt alkalmazza a kvetkez fejezetben tr-
gyalt konverzis szablyokat a + mveletre s a tmbre. Ha az uttag-ki-
fejezs a tmb s a kifejezs az egsz tpus, akkor a konstrukci a tmb
kifejezsedik elemre hivatkozik.
Mi van a tpussal? A kls zrjel prban mg mutat tpus (tpus *)
van, s ezen hajtja vgre a fordt az indirekcit. Teht az eredmny tpust
a mutat dnti el.
Vegyk a tomb[6] indexes vltozt! A mondottak szerint ebbl
*((tomb) + (6))
lesz, ami nem 6, hanem 6nak, mint indexnek, a hozzadst jelenti a
tomb kezdcmhez, azaz:
*((float *)100 + 6*sizeof(float))
Az sszeads elvgzse utn
*((float *)124)
, ami az indirekci vgrehajtsa utn a tomb 6os index elemt eredm-
nyezi.
A + kommutatv mvelet, gy az indexels is az. Egydimenzis tm-
bkre a kvetkez ngy kifejezs teljesen ekvivalens feltve, hogy p mu-
tat s i egsz:
p[i] i[p] *(p + i) *(i + p)
Folytassuk az index opertor ismertetsnek megkezdse eltt elkezdett
gondolatmenetet, azaz a pt mutat legyen tomb rtk!
pt = tomb;
Ilyenkor:
*pt tomb[0],
*(pt + 1) tomb[1]
s ltalban
*(pt + i) tomb[i].
Vegyk szre, hogy a pt-re szksg sincs a tmbelemek s cmeik
ellltshoz, hisz:
tomb[i] *(tomb + i)
s
&tomb[i] tomb + i.
C programnyelv 171
int i = 6;
float ftomb[50], *fptr = ftomb;
esetn
fptr += i;
hatsra az fptr-beli cm
sizeof(float)*i
-vel (ltalnossgban sizeof(tpus)*egsz-szel) n, azaz a plda szerint
ftomb[6]-ra mutat.
Ha ptr1 a tpus tpus tmb msodik s ptr2 a tizedik elemre mutat,
akkor a kt mutat klnbsge
ptr2 - ptr1 8.
Figyeljk meg, hogy a mutatkhoz indexrtket adunk hozz vagy
vonunk ki belle s a mutatk klnbsge is indexrtk! Igazbl a kt
mutat klnbsge ptrdiff_t tpus egsz indexklnbsg. A ptrdiff_t az
STDDEF.H fejfjlban definilt, s tbbnyire signed int.
9.4.2 Relcik
A kvetkez operandus tpuskombincik hasznlhatk relcikban:
Mindkt operandus lehet ugyanazon tpus objektumra mutat mu-
tat, amikor is a kt objektum memria cmnek sszehasonltsrl
lesz sz.
A mutat sszehasonlts csak egyazon objektum rszeire definilt,
s a mutatk nem tartalmazhatnak ezen objektumon kvlre irnyul
cmet sem egyetlen kivtellel, tmb esetn megengedett az utols
ltez elem utni cmre val hivatkozs. Ha a mutatk tmb ele-
mekre hivatkoznak, akkor az sszehasonlts az indexek sszeha-
sonltsval ekvivalens. A nagyobb index elem cme magasabb.
Az egyenlsgi relcikat hasznlva a mutat hasonlthat a kons-
tans 0 rtkhez, azaz a NULL mutathoz is.
Csak az egyenlsgi relcik esetben a mutat hasonlthat a kons-
tans, 0 rtk, egsz kifejezshez, vagy voidra mutat mutathoz.
Ha mindkt mutat NULL mutat, akkor egyenlk.
9.4.4 Konverzi
A fordt ltal automatikusan elvgzett, implicit konverzikat mr meg-
ismertk a cmaritmetika mveleteinl.
Az explicit tpuskonverzis
(tpusnv) eltag-kifejezs
szerkezetben a (tpusnv) tbbnyire (tpus *) alak lesz, s ilyen tpus
objektumra mutat mutatv konvertlja az eltag-kifejezs rtkt. Pl-
dul:
char *lanc;
int *ip;
/* . . . */
lanc = (char *) ip;
C programnyelv 177
9.5 Karaktermutatk
Tudjuk, hogy a karakterlnc konstans karaktertmb tpus, s ebbl k-
vetkezleg mgtte ugyancsak egy cm konstans van, hisz pldul a
printf(Ez egy karakterlnc konstans.);
kitnen mkdik, holott a printf fggvny els paramtere const char *
tpus. Ez a konstans mutat azonban a tmbtl eltren nem rendelkezik
azonostval sem, teht ksbb nincs mdunk hivatkozni r. Ennek elke-
rlsre, azaz a cm konstans rtknek megrzsre, a kvetkez md-
szerek ajnlhatk:
char *uzenet;
uzenet = Ksz a kv!\n;
vagy
const char *uzenet = Ksz a kv!\n;
A sajt strcmp:
int strcmp(const char *s1, const char *s2 ){
for( ; *s1 == *s2; ++s1, ++s2)
if(!(*s1)) return 0; /* s1 == s2 */
return(*s1 - *s2); } /* s1 < s2 vagy s1 > s2 */
char *strcpy(char *cel, const char *forras);
char *strncpy(char *cel, const char *forras, size_t n);
void *memcpy(void *cel, const void *forras, size_t n);
void *memmove(void *cel, const void *forras, size_t n);
Az strcpy a forras karakterlncot msolja lnczr karaktervel egytt a
cel karaktertmbbe, s visszatr a cel cmmel. Nincs hibt jelz visszat-
rsi rtk. Nincs tlcsorduls ellenrzs a karakterlncok msolsnl.
Az strncpy a forras legfeljebb els n karaktert msolja. Ha a forras n
karakternl rvidebb, akkor cel vgt \0zza n hosszig a rutin. Ha az n
nem kisebb, mint a forras mrete, akkor nincs zrus a msolt karakterlnc
vgn.
A memcpy s a memmove mindenkppen n bjtot msolnak. Egyetlen-
knt a karakterlnc kezel fggvnyek kzl, a memmove akkor is bizto-
stja az tlapol memriaterleteken lev, eredeti forras bjtok fellrs
eltti tmsolst, ha a forras s a cel tfedn egymst.
A sajt strcpy:
char *strcpy(char *cel, const char *forras ){
char *seged = cel;
/* forras cel-ba msolsa lezr \0 karaktervel: */
while(*cel++ = *forras++);
/* Vissza a msolat karakterlnc kezdcme: */
return seged; }
size_t strlen(const char *string);
A rutin a string karakterlnc karaktereinek szmval tr vissza a lncz-
rt nem beszmtva. Nincs hibt jelz visszaadott rtk!
char *strpbrk(const char *string, const char *strCharSet);
A fggvnyek az strCharSetbeli karakterek valamelyikt keresik a
stringben, s visszaadjk az els elforduls cmt, ill. NULL mutatt,
ha a kt paramternek kzs karaktere sincs. A keressbe nem rtendk
bele a lnczr zrusok.
A pldban szmokat keresnk az s karakterlncban.
#include <string.h>
C programnyelv 181
#include <stdio.h>
void main(void){
char s[100] = "3 frfi s 2 fiu 5 disznt ettek.\n";
char *er = s;
int i=1;
while(er = strpbrk(er, "0123456789"))
printf("%d: %s\n", i++, er++); }
A kimenet a kvetkez:
1: 3 frfi s 2 fiu 5 disznt ettek.
2: 2 fiu 5 disznt ettek.
3: 5 disznt ettek.
char *strset(char *string, int c);
char *strnset(char *string, int c, size_t n);
void *memset(void *string, int c, size_t n);
A memset feltlti string els n bjtjt c karakterrel, s visszaadja string
kezdcmt.
A legtbb fejleszt rendszerben ltez, nem ANSI szabvnyos str-
set s strnset a string minden karaktert a lnczr zrus kivtelvel c
karakterre lltjk t, s visszaadjk a string kezdcmt. Nincs hibt jelz
visszatrsi rtk. Az strnset azonban a string legfeljebb els n karaktert
inicializlja cre.
size_t strspn(const char *string, const char *strCharSet);
size_t strcspn(const char *string, const char *strCharSet);
Az strspn annak a string elejn lev, maximlis alkarakterlncnak a
mrett szolgltatja, mely teljes egszben csak az strCharSetbeli karak-
terekbl ll. Ha a string nem strCharSetbeli karakterrel kezddik, akkor
zrust kapunk. Nincs hibt jelz visszatrsi rtk. A keressbe nem r-
tendk bele a lnczr zrus karakterek.
A fggvny visszaadja tulajdonkppen az els olyan karakter indext
a stringben, mely nincs benn az strCharSet karakterlnccal definilt ka-
rakterkszletben.
Az strcspn viszont annak a string elejn lev, maximlis alkarakter-
lncnak a mrett szolgltatja, mely egyetlen karaktert sem tartalmaz az
strCharSetben megadott karakterekbl. Ha a string strCharSetbeli ka-
rakterrel kezddik, akkor zrust kapunk. Pldul a:
#include <string.h>
#include <stdio.h>
void main(void){
char string[] = "xyzabc";
182 MUTATK
tag=(*(int *)((param+=_INTSIZEOF(int))-_INTSIZEOF(int)))
, azaz:
tag=*(int *)((param+=4)-4)
Teht a tag vltoz felveszi a kvetkez, int, aktulis paramter rtkt,
s ekzben param mr a kvetkez aktulis paramterre mutat.
A kvetkez fggvnyek a parlist vltoz paramterlisttl eltekint-
ve ugyangy dolgoznak, mint nevkben v nlkli prjaik. A felsorolt
printf fggvnyek a 3. pont va_arg hvsait maguk intzik, s a format
karakterlnc alapjn a vltoz paramterlista vgt is ltjk. A parlist az
aktulis vltoz paramterlista els elemre mutat mutat.
int vfprintf(FILE *stream, const char *format, va_list parlist);
int vprintf(const char *format, va_list parlist);
int vsprintf(char * puffer, const char * format, va_list parlist);
9.6 Mutattmbk
Mutattmb a
tpus *azonost[<konstans-kifejezs>] <={inicializtorlista}>;
deklarcival hozhat ltre. Az azonost a mutattmb neve: konstans
mutat, melynek tpusa (tpus **), vagyis tpus tpus objektumra mutat
mutatra mutat mutat. Teht olyan konstans mutat, mely (tpus *) mu-
tatra mutat.
Vegyk szre a * mutatkpz opertor rekurzv hasznlatt!
A tmb egy eleme viszont (tpus *) tpus vltoz mutat.
Kezdjnk el egy pldt magyar krtyval!
A szneket kdoljuk a kvetkezkpp: makk (0), piros (1), tk (2) s
zld (3). A krtykat egy sznen bell jelljk gy: hetes (0), nyolcas (1),
kilences (2), tzes (3), als (4), fels (5), kirly (6) s sz (7). A konkrt
krtya kdja gy keletkezik, hogy a sznkd utn lerjuk a krtya kdjt.
Ilyen alapon a 17 pldul piros sz.
Ksztsnk char *KartyaNev(int kod) fggvnyt, mely visszaadja a pa-
ramter kod krtya megnevezst!
/* KARTYA.H fejfjl. */
/* Szimbolikus llandk: */
#define SZINDB 4 /* Sznek szma. */
#define KTYDB 8 /* Krtyk szma egy sznen bell. */
#define OSZTO 10 /* Szn s krtyakd sztvlasztshoz*/
#define PAKLI SZINDB*KTYDB /* Krtyaszm a pakliban. */
C programnyelv 187
dinamikusan.\n", m, n);
if(!(matrix=(OBJEKTUM)calloc(m, sizeof(TIPUS *)))){
printf("Ltrehozhatatlanok a mtrix sorai!\n");
return 1; }
/* Az oszlopok ltrehozsa: */
for(i = 0; i < m; ++i)
if(!(matrix[i]=(TIPUS *)malloc(n*sizeof(TIPUS)))){
printf("Ltrehozhatatlan a mtrix %d. sora!\n",
i);
while(--i>=0) free(matrix[i]);
free(matrix);
return 1; }
/* Mestersges inicializls: */
for(i = 0; i < m; ++i)
for(j = 0; j < n; ++j)
matrix[i][j] = rand();
/* Kirs: */
printf("A mtrix tartalma:\n");
for(i = 0; i < m; ++i) {
for(j = 0; j < n; ++j)
printf("%10.0Lf", matrix[i][j]);
printf("\n"); }
/* Az oszlopok felszabadtsa: */
for(i = 0; i < m; ++i) free(matrix[i]);
/* Sorok felszabadtsa: */
free(matrix);
return 0; }
Vegyk szre, hogy a mainnek van visszaadott rtke, mely zrus, ha minden rend-
ben megy, s 1, ha memriafoglalsi problma lp fel!
Figyeljk meg azt is, hogy a memria felszabadtsa foglalsval ppen ellenkez
sorrendben trtnik, hogy a heapen ne maradjanak foglalt szigetek!
A heap C konstrukci, s ha a program befejezdik, akkor maga is felszabadul, meg-
sznik ltezni.
C programnyelv 195
sszestve: A matrix azonost a tmb kezdetre mutat, vltoz mutat. A tmb kez-
dete viszont m vltoz mutatbl ll mutattmb. A mutattmb egy-egy eleme n
elem, long double tpus tmb kezdetre mutat. A plda a rszek memriabeli el-
helyezkedst is szemllteti, azaz:
elbb az m elem mutattmbt allokljuk, aztn
a mtrix els sora (0-s index) n elemnek foglalunk helyet.
A mtrix msodik sora (1-s index) n elemnek helyfoglalsa kvetkezik.
...
Legvgl a mtrix utols (m-1 index) sornak n elemt helyezzk el a
memriban.
32 bites cmeket felttelezve, 1000rl indulva, m=3 s n=5 esetn, a matrix a
kvetkezkppen helyezkedhet el a memriban:
matrix[0] matrix[1] matrix[2]
matrix: 1012 1062 1112
1000 1004 1008
matrix[0]: matrix[0][0] matrix[0][1] matrix[0][2] matrix[0][3] matrix[0][4]
1012 1022 1032 1042 1052
matrix[1]: matrix[1][0] matrix[1][1] matrix[1][2] matrix[1][3] matrix[1][4]
1062 1072 1082 1092 1102
matrix[2]: matrix[2][0] matrix[2][1] matrix[2][2] matrix[2][3] matrix[2][4]
1112 1122 1132 1142 1152
Hromdimenzis tmbt gy valsthatunk meg, hogy ltrehozunk elbb egy
mutattmbt, melynek mindenegyes eleme egy, az elzekben ismertetett szerkezet
mtrixra mutat.
Nhny sz mg a tbbszrsen alkalmazott index opertorrl! A kifejezs1[kife-
jezs2][kifejezs3]...ban az index opertorok balrl jobbra ktnek, gy a fordt elszr
a legbaloldalibb kifejezs1[kifejezs2] kifejezst rtkeli ki. A szletett mutat rtkhez
aztn hozzadva kifejezs3 rtkt j mutat kifejezst kpez, s ezt a folyamatot a legjob-
boldalibb index kifejezs sszegzsig vgzi. Ha a vgs mutat rtk nem tmb tpust
cmez, akkor az indirekci mvelete kvetkezik. Teht pldul:
matrix[2][3] (*(matrix+2))[3] *(*(matrix+2)+3)
A fordt hasonl mdszerrel dolgozik, de az ltala ltrehozott mtrixszal kapcsolat-
ban az sszes mutat idertve a mtrix azonostjt is konstans.
A tbbdimenzis tmbk tbbflekppen is szemllhetk. A fordt ltal ltrehozott
mtrix (.n. statikus tmb) pldjnl maradva:
long double matrix[m][n];
A matrix egy m elem vektor (tmb) azonostja. E vektor minden eleme egy n
elem, long double tpus vektor.
A matrix[i] (i = 0, 1, ..., m-1) az iedik, n long double elem vektor azono-
stja.
196 MUTATK
9.9.1 Programbefejezs
A return 1 csak a mainben kiadva fejezi be a program futst. Az
STDLIB.H bekapcsolsakor rendelkezsre ll, mindegyik opercis
rendszerben hasznlhat
void exit(int statusz);
void abort(void);
fggvnyek mind befejezik annak a programnak a futst, amiben meg-
hvjk ket akrmilyen mly rutin szintrl is. A statusz paramter rtkt
visszakapja a befejezettet indt (vrakoz szl) program, mint kilpsi
llapotot (exit status). A statusz rtket tveszi persze az opercis rend-
szer is, ha volt a befejezett program indtja. Zrus (EXIT_SUCCESS)
202 MUTATK
Ha van egy
int fv(double, int);
prototpus fggvnynk, akkor erre mutat mutatt
int (*pfv)(double, int);
mdon deklarlhatunk. A pfv azonost ezek utn olyan vltozt deklarl,
melyben egy double, s egy int paramtert fogad s int-tel visszatr
fggvnyek cmeit tarthatjuk. A pfv teht vltoz kdmutat. Kdmutat
konstans is ltezik azonban, s ez a fggvnynv (a pldban az fv).
Vigyzzunk a deklarciban a fggvnymutat krli kerek zrjel
pr el nem hagyhatsgra, mert az
int *pfv(double, int);
olyan pfv azonostj fggvnyt deklarl, mely egy double, s egy int pa-
ramtert fogad, s int tpus objektumra mutat mutatval tr vissza. A
problma az, hogy a mutatkpz opertor (*) prioritsa alacsonyabb a
fggvnykpznl (()).
Hogyan lehet rtket adni a fggvnymutatnak?
Termszetesen a szoksos mdokon, azaz hozzrendelssel:
pfv = fv;
, ill. a deklarciban inicializtor alkalmazsval:
int fv(double, int);
int (*pfv)(double, int) = fv;
Vigyzzunk nagyon a tpussal, mert az most bonyoldott! Csak
olyan fggvny cme tehet be a pfv-be, mely a fggvnymutatval egye-
z tpus, azaz int-et ad vissza, egy double s egy int paramtert fogad
ebben a sorrendben. A
void (*mfv)();
szerint az mfv meg nem hatrozott szm s tpus paramtert fogad
olyan fggvnyre mutat mutat, melynek nincs visszatrsi rtke.
Vegyk szre, hogy a krdses fggvnyek defincija eltt fgg-
vnymutatk inicializlsra is hasznlhat a megadott fggvny protot-
pus!
Hogyan hvhatjuk meg azt a fggvnyt, melynek cmt a kdmutat tar-
talmazza?
204 MUTATK
A
(*vpfv)(0.65);
eredmnyessge elgg megkrdjelezhet, de a
pfv=(int (*)(double, int))vpfv;
utn teljesen rendben lesz a dolog:
a=(*pfv)(0.65, 8);
Emlkezznk csak! Explicit tpusmdostott kifejezs nem lehet
balrtk.
Foglalkozzunk csak jra egy kicsit a tpusnevekkel!
9.10.2 Tpusnv
Explicit tpusmdostsban, fggvnydeklartorban a paramtertpus
rgztsekor, sizeof operandusaknt stb. szksg lehet a tpus nevnek
megadsra. Ehhez kell a tpusnv, mely szintaktikailag a krdses tpus
objektum olyan deklarcija, melybl elhagytk az objektum azonostjt.
tpusnv:
tpusspecifiktor-lista<absztrakt-deklartor>
absztrakt-deklartor:
mutat
<mutat><direkt-absztrakt-deklartor>
direkt-absztrakt-deklartor:
(absztrakt-deklartor)
<direkt-absztrakt-deklartor>[<konstans-kifejezs>]
<direkt-absztrakt-deklartor>(<paramter-tpus-lista>)
Az absztrak-deklartorban mindig lokalizlhat az a hely, ahol az azo-
nostnak kne lennie, ha a konstrukci deklarcin belli deklartor len-
ne.
Lssunk nhny konkrt pldt!
int *
int tpus objektumra mutat mutat.
int **
int tpus objektumra mutat mutatra mutat mutat.
int *[]
Nem meghatrozott elemszm, int tpus mutattmb.
int *()
C programnyelv 209
10 STRUKTRK S UNIK
A struktra s az uni aggregtum. Egy vagy tbb, esetleg klnbz t-
pus vltoz (elnevezett tag) egyttese, melynek nll azonostja van.
A struktrt ms nyelvben rekordnak nevezik. Azt teszi lehetv, hogy a
valamilyen mdon sszetartoz vltozk egsz csoportjra egyetlen nv-
vel hivatkozhassunk, azaz hogy a vltozcsoport kezelse egyszerbb le-
gyen.
Tulajdonkppen minden struktrval s unival j, sszetett, fel-
hasznli adattpust hozunk ltre.
Az ANSI szabvny megengedi, hogy a struktrkat t lehessen msolni
egymsba, hozz lehessen rendelni, s tadhatk legyenek fggvnyek-
nek, ill. rutinok visszatrsi rtke is lehessen struktra. Kpezhet term-
szetesen a struktra cme (&), mrete (sizeof), s benne lehet explicit t-
pusmdost szerkezetben is, de
a struktrk nem hasonlthatk ssze.
A struktrban felsorolt vltozkat struktratagoknak (member) neve-
zik. Struktratag kis megszortsokkal - melyre ksbb kitrnk - akrmi-
lyen tpus lehet. Lehet alap s szrmaztatott tpus brmilyen sorrend-
ben.
A deklarcibeli tpusspecifiktor egyik alternatvja a
struktra-vagy-uni-specifiktor:
struktra-vagy-uni<azonost>{struktratag-deklarcilista}
struktra-vagy-uni azonost
struktra-vagy-uni:
struct
union
A struktratag-deklarcilista struktra, ill. unitag deklarcik soroza-
ta:
struktratag-deklarcilista:
struktratag-deklarci
struktratag-deklarcilista struktratag-deklarci
struktratag-deklarci:
tpusspecifiktor-lista struktra-deklartorlista
tpusspecifiktor-lista:
tpusspecifiktor
tpusspecifiktor-lista tpusspecifiktor
struktra-deklartorlista:
struktra-deklartor
struktra-deklartorlista, struktra-deklartor
C programnyelv 217
10.1 Struktradeklarci
Alakja teht a kvetkez:
<trolsi-osztly-specifiktor> struct <struktracmke> <{
struktratag-deklarcilista }> <azonostlista>;
Pldul:
struct datum{
int ev, ho, nap, evnap;
long datumssz; /* Dtumsorszm. */
char datumlanc[11]; }
d, dptr, dt[10]; /* Azonostlista. */
, ahol:
A trolsi-osztly-specifiktor elhagysval, megadsval s ennek
rtelmezsvel nem foglalkozunk jra!
A datum azonost ennek a struktrnak a cmkje (struktracm-
ke), mely azt biztostja, hogy ksbb struct datum mdon hivatkoz-
ni tudjunk a felhasznli tpusra. Pldul:
struct datum *sptr =
(struct datum *)malloc(sizeof(struct datum));
Az ev, a ho, a nap s az evnap a struct datum tpus struktra int
tpus tagjainak, a datumssz a long tpus tagjnak s a datumlanc
a struktra char* tpus tagjnak az azonosti. A tagneveknek csak
a struktrn bell kell egyedieknek lennik, azaz a tagazonostk
nyugodtan egyezhetnek pldul ms kznsges vltozk neveivel,
vagy a struktracmkkkel.
A d struct datum tpus vltoz, a dptr s az sptr struct datum t-
pus objektumra mutat mutatk, s a dt tz, struct datum tpus
elembl ll tmb azonostja, azaz a dt struktratmb.
A fordt a struktrnak ppen annyi helyet foglal a memriban,
hogy benne a struktra minden tagja elfrjen. A struktratagok a
218 STRUKTRK S UNIK
10.1.1 Tpusdefinci
Az elbb vzolt problma tpusdefinci alkalmazsval thidalha-
t:
220 STRUKTRK S UNIK
int j;
double x; };
struct B {
int i;
char *nev;
struct A a;
double d; } s, *sptr = &s;
/* . . . */
s.i = 3;
s.a.j = 2;
sptr->d = 3.14;
(sptr->a).x = 6.28;
ADAT adat;
struct List1 *kov; };
, ahol az ADAT tpus adat tagon valamilyen, a lista egy elemben tro-
land adatokat ler struktrt kell rteni. A kov az egyirny lista kvet-
kez struct List1 tpus elemre mutat, ill. a lista vgt NULL mutat
jelzi. A lista kezelhetsghez ezen tl mr csak egy horgonypontra, s
esetleg egy seged mutatra
struct List1 *KezdoPont = NULL, *seged;
van szksg a listt manipull programban.
Tegyk fel, hogy ismertek az ADATok, s vegyk fel a lista els elemt!
if(!(KezdoPont=seged=(struct List1*)malloc(
sizeof(struct List1)))){
printf("Elfogyott a memria!\n");
exit(1); }
else{
/* seged->adat vegye fel az ADATok rtkt! */
seged->kov=NULL; }
A lista kvetkez eleme:
if(!(seged->kov=(struct List1*)malloc(
sizeof(struct List1)))){
printf("Elfogyott a memria!\n");
exit(1); }
else{
/* seged->adat vegye fel az ADATok rtkt! */
seged->kov=NULL; }
/* . . . */
Elg! rjunk Beszur1 fggvnyt, mely paramterknt megkapja a be-
szrand ADATokat, s annak a listaelemnek a cmt, mely utnra az j
listaelem kell, hogy kerljn! Ha mg nincs is lista, akkor ezen a pozcin
kapjon NULL mutatt a rutin! A visszatrsi rtk legyen a most ltestett
listaelem cme, ill. NULL mutat, ha elfogyott a memria!
struct List1 *BeSzur1(ADAT a, struct List1 *elozo){
struct List1 *p;
if(p=(struct List1 *)malloc(sizeof(struct List1))){
p->adat=a;
if(elozo){
p->kov=elozo->kov;
elozo->kov=p; }
else p->kov=NULL; }
return p; }
Ekkor a lista ltrehozsa a kvetkez:
KezdoPont=seged=BeSzur1(adatok, NULL);
while(/* Vannak kvetkez adatok? */&&seged!=NULL)
236 STRUKTRK S UNIK
seged=BeSzur1(adatok, seged);
if(!seged){
printf("Elfogyott a memria!\n");
exit(1); }
A ltrehozott egyirny lista felhasznls utn a kvetkez kddal sem-
misthet meg:
while(KezdoPont){
seged=KezdoPont->kov;
free(KezdoPont);
KezdoPont=seged; }
Az egyirny listban lehet j elemet brhov beszrni (BeSzur1), br-
honnt trlni, de a listt ahogyan a megsemmist kd is mutatja
csak elrehaladva lehet elrni, visszafel lpkedve nem. Az odavisszaha-
ladshoz ktirny lista kell:
struct List2{
ADAT adat;
struct List2 *kov, *elo; };
struct List2 *KezdoPont = NULL, *seged;
A visszalpegets lehetsgt a megelz listaelemre mutat, elo muta-
ttag biztostja. A lista vgt mindkt irnyban NULL mutat jelzi. A be-
szrs:
struct List2 *BeSzur2(ADAT a, struct List2 *elozo){
struct List2 *p;
if(p=(struct List2 *)malloc(sizeof(struct List2))){
p->adat=a;
if(elozo){
p->elo=elozo;
p->kov=elozo->kov;
elozo->kov=p;
if(p->kov) p->kov->elo=p; }
else p->elo=p->kov=NULL; }
return p; }
A BeSzur2 csak egyet nem tud: a ltez els elem el beszrni. Ezen
gy segthetnk:
seged=BeSzur2(adatok, NULL);
seged->kov=KezdoPont;
KezdoPont=seged;
A trls:
struct List2 *Torol2(struct List2 *ezt){
struct List2 *p=NULL;
if(ezt){
p=ezt->kov;
if(ezt->elo) ezt->elo->kov=ezt->kov;
if(ezt->kov) ezt->kov->elo=ezt->elo;
C programnyelv 237
free(ezt); }
return p; }
A Torol2 fggvnynek is csak a ltez, legels elem trlsekor kell se-
gteni, hisz vltozik a
KezdoPont=Torol2(KezdoPont);
Felhasznls utn a ktirny lista is ugyangy semmisthet meg, mint
az egyirny.
A fk kzl vlasszuk ki a binris keresft! Ennek pontjaiban legfel-
jebb kett az elgazsok szma, s a pontokban helyet foglal struktrk
ADAT rsze alapjn a fa, mondjuk, nvekvleg rendezett. Ltezik teht
egy
int Hasonlit(ADAT a1, ADAT a2);
rutin, mely zrust szolgltat, ha a1==a2, pozitv rtket, ha a1>a2, ill. ne-
gatvat egybknt. A binris keresfban a mindenkori aktulis pont bal
gn lev pontok kzl egy sem nagyobb, s a jobb gn helyet foglalk
kzl viszont egyik sem kisebb az aktulis pontnl. Az adatstruktra:
struct BinFa{
ADAT adat;
struct BinFa *bal, *jobb; };
struct BinFa *KezdoPont = NULL;
A beszrst vgz rekurzv fggvny a kvetkez:
struct BinFa *BeSzurBF(ADAT a, struct BinFa *p){
int fel;
if(!p){ /* j pont kszl. */
if(p=(struct BinFa *)malloc(sizeof(struct BinFa))){
p->adat=a;
p->bal=p->jobb=NULL; }
else printf("Elfogyott a memria!\n"); }
else if((fel=Hasonlit(a, p->adat))==0)
/* Volt mr ilyen ADAT, s itt ez a kd van. */
else if(fel<0) /* A bal oldali rszfba val. */
p->bal=BeSzurBF(a, p->bal);
else /* A jobb oldali rszfba val. */
p->jobb=BeSzurBF(a, p->jobb);
return(p); }
A kvetkez rekurzv fggvny nvekvleg rendezett sorrendben vgez
el minden ponton valamilyen tevkenysget:
void Tevekeny(struct BinFa *p){
if(p){
Tevekeny(p->bal);
/* Itt van a tevkenysg kdja. */
Tevekeny(p->jobb); } }
238 STRUKTRK S UNIK
++sorszam; }
Kiir(KezdoPont);
return 0; }
A fgets fggvny a getlinehoz nagyon hasonlan dolgozik. Karak-
terlncot olvas be a szabvny bemenetrl (stdin), melyet az els param-
ter cmtl kezdve letrol a memriban. Az olvass lell, ha a fggvny a
msodik paramternl eggyel kevesebb (MAXSOR 1), vagy \n ka-
raktert olvasott. A getlinetl eltren azonban a rutin a \nt is elhelyezi
a lncban, s a lnc vghez mg egy \0t is hozzilleszt. Sikeres eset-
ben az fgets az els paramter mutatval tr vissza. Fjlvgen, vagy hiba
esetn viszont NULLt kapunk tle.
Ha a sor tmb utols pozcijn van a lnczr zrus, de eltte
nincs ott a soremels karakter, akkor az aktulisan olvasott sor nem frt el
egy menetben a bemeneti pufferben, s ebbl kvetkezleg elsorszmozs
trtnik.
Az strtok lersa megtallhat a MUTATK szakasz Karakter-
lnc kezel fggvnyek fejezetben!
struct BinFa *BeSzurBF(char *a,int sorszam,struct BinFa *p)
{ int fel;
if(!p){ /* j sz rkezett */
p=(struct BinFa *)malloc(sizeof(struct BinFa));
if(p&&(p->szo=(char *)malloc(strlen(a)+1))){
strcpy(p->szo, a);
if(p->sorok=(struct List1 *)malloc(
sizeof(struct List1))){
p->sorok->sorsz=sorszam;
p->sorok->kov=NULL; }
p->bal=p->jobb=NULL; }
if(!p||!p->szo||!p->sorok){
printf("Elfogyott a memria!\n");
exit(1); } }
else if((fel=strcmp(a, p->szo))==0)
SorMeg(p, sorszam);
else if(fel<0)
p->bal=BeSzurBF(a, sorszam, p->bal);
else p->jobb=BeSzurBF(a, sorszam, p->jobb);
return(p); }
/* Sorszm hozzadsa az egyirny lista vghez: */
void SorMeg(struct BinFa *p, int sorszam){
struct List1 *seged=p->sorok;
while(seged->kov!=NULL && seged->sorsz!=sorszam)
seged=seged->kov;
if(seged->sorsz!=sorszam){
if(seged->kov=(struct List1 *)malloc(
sizeof(struct List1))){
seged->kov->sorsz=sorszam;
seged->kov->kov=NULL; }
240 STRUKTRK S UNIK
else{
printf("Elfogyott a memria!\n");
exit(1); } } }
/* A fa kirsa: */
void Kiir(struct BinFa *p){
struct List1 *seged;
int i;
if(p){
Kiir(p->bal);
printf("%s:\n", p->szo);
for(seged=p->sorok, i=0; seged; seged=seged->kov,
++i)
printf("%7d|", seged->sorsz);
if(i%10!=9) printf("\n");
Kiir(p->jobb); } }
Megoldand feladatok:
Fejlessze tovbb a PELDA30.Cben megoldott feladatot a kvetkez-
kpp, s persze prblja is ki!
C parancssori paramterrel indtva a program ne gyjtse a szabv-
nyos C kulcsszavak elfordulsait.
Ha a szabvny kimenet (stdout) nem fjl, akkor bontsa lapokra a
listt a szoftver.
N parancssori paramterrel startolva jelentesse meg a program
megsorszmozva, de egybknt vltozatlanul a bemenetet.
10.8 UNIK
Az uni tpus a struktrbl szrmazik, de a tagok kztt zrus a cmel-
tols. Az uni azt biztostja, hogy ugyanazon a memria terleten tbb,
klnfle tpus adatot trolhassunk. Az
union unio{
int i;
double d;
char t[5]; } u, *pu = &u, tu[23];
definciban az u union unio tpus objektum, a pu ilyen tpus objek-
tumra mutat mutat, s a tu egy 23 ilyen tpus elembl ll tmb azo-
nostja. Az u objektum - pldul - egyazon memria terleten biztostja
az i nev int, a d azonostj double s a t nev karaktertmb tpus tag-
jainak elhelyezst, azaz:
&u &u.i &u.d ...
Ennek szellemben aztn igaz, hogy az uni objektumra mutat mutat
annak egyben minden tagjra is mutat.
(pu=&u) &u.i &u.d ...
Termszetesen a dolog csak a mutatk rtkre igaz, mert az &u
(union unio *), az &u.i (int *) s az &u.d (double *), azaz tpusban el-
trnek. Ha azonban unit megcmz mutatt explicit tpusmdostssal
tagjra irnyul mutatv alaktjuk, akkor az eredmny mutat magra a
tagra mutat:
u.d=3.14;
printf(*(&u.d) = %f\n, *(double *)pu);
Az uni helyfoglalsa a trban akkora, hogy benne a legnagyobb bjtig-
ny tagja is elfr, azaz:
sizeof(union unio) sizeof(u) 8.
Teht 4 bjt felhasznlatlan, ha int adatot tartunk benne, ill. 3 bjt elrhe-
tetlen, ha karaktertmbt rakunk bele. Az uni egy idben csak egyetlen
tagjt tartalmazhatja.
C programnyelv 243
10.8.1 Unideklarcik
Az ltalnos deklarcis szably azonos a struktrval. Az eltrsek a
kvetkezk:
Az unik tartalmazhatnak bitmezket. Mindegyik bitmez azonban
az uni kezdettl indul, s gy kzlk csak egy lehet aktv.
244 STRUKTRK S UNIK
int : 4, k: 1;
unsigned m: 4; } b, *pb = &b;
ltal elfoglalt sz bittrkpe a kvetkez:
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
m k j i
Ha az m bitmez tag szlessge 4-nl nagyobb lett volna, akkor j szt
kezdett volna a fordt, s az elz sz fels ngy bitje kihasznlatlan ma-
radt volna. ltalnossgban: a (dupla)szn tllg bitmez j (dupla)szt
kezd, s az elz (dupla)szban a fels bitek kihasznlatlanok maradnak.
Ha a deklarciban valamely (nvtelen) bitmeznl zrus szless-
get adunk meg, akkor mestersgesen knyszertjk ki ezt a kvetkez
(dupla) szhatrra llst.
A bitmeznek elg szlesnek kell lennie ahhoz, hogy a rgztett
bitminta elfrjen benne! Pldul a kvetkez tagdeklarcik illeglisak:
int alfa : 17;
unsigned beta : 32
A bitmezk ugyanazokkal a tagszelektor opertorokkal (. s ->) rhetk
el, mint a nem bitmez tagok:
b.i vagy pb->k
A bitmezk kis signed vagy unsigned egsz rtkekknt viselkednek
(rgtn tesnek az egszellptetsen), azaz kifejezsekben ott fordul-
hatnak el, ahol egybknt aritmetikai (egsz) rtkek lehetnek. signed
esetben a legmagasabb helyirtk bit (MSB - most significant bit) eljel-
bitknt viselkedik, azaz az int i : 2 lehetsges rtkei pldul:
00: 0, 01: +1, 10: -2, 11: -1
Az unsigned m : 4 lehetsges rtkei:
0000: 0, 0001: 1, . . ., 1111: 15
ltalnossgban:
unsigned x : szlessg; /* 0 <= x <= 2szlessg-1 */
signed y : szlessg; /* -2szlessg-1<= y <=+2szlessg-1-1 */
A nyelvben nincs sem egsz alul, sem tlcsorduls. Ha gy a bitme-
znek brzolsi hatrain kvli rtket adunk, akkor abbl is lesz vala-
mi. Mghozz az rtk annyi als bitje, mint amilyen szles a bitmez.
Pldul:
b.i = 6; /* 110 10, azaz -2 lesz az rtke! */
C programnyelv 247
10.10Balrtk jobbrtk
Most mr tkletesen pontosthatjuk a balrtk kifejezst a Cben,
mely:
Egsz, lebegpontos, mutat, struktra vagy uni tpus azonost.
Indexes kifejezs, mely nem tmbb (hanem elemm) rtkelhet
ki.
248 STRUKTRK S UNIK
10.11Nvterletek
A nvterlet az a hatskr, melyen bell egy azonostnak egyedinek
kell lennie, azaz msms nvterleten konfliktus nlkl hasznlhat
ugyanaz az azonost, s a fordt meg tudja klnbztetni ket. A nvte-
rleteknek a kvetkez fajti vannak:
C programnyelv 249
nvterletn tallhat. */
struct t{
int s; /* OK: hiszen megint jabb tag nvterlet
kezddtt. */
/* . . . */
} s; /* HIBA: s azonost most mr minden
nvterleten van. */
goto s; /* OK: az utasts cmke s a struktracmke
ms-ms nvterleten vannak. */
/* . . . */
s: ; /* Utasts cmke. */
C programnyelv 251
_fgetc(f))
int ungetc(int c, FILE *stream);
A fggvny visszateszi a stream bemeneti folyamba a c paramter un-
signed char tpusv konvertlt rtkt gy, hogy a kvetkez olvasssal
ez legyen az els elrhet karakter. A szablyos mkds csak egyetlen
karakter visszahelyezse esetn garantlt, de a visszatett karakter nem le-
het az EOF.
Kt egymst kvet ungetc hvs hatsra mr csak a msodiknak
visszatett karakter rhet el, mondjuk, a kvetkez getcvel, azaz az els
elveszik. Gondoljuk csak meg, hogyha nincs puffer, akkor a visszattelhez
a FILE struktra egyetlen hold tagja ll rendelkezsre!
Az fflush, az fseek, az fsetpos, vagy a rewind trli a bemenetre vissza-
tett karaktert.
Sikeres hvskor az ungetc a visszatett karaktert adja vissza. Hiba ese-
tn viszont EOFot kapunk tle. Az
char *fgets(char *s, int n, FILE *stream);
karakterlncot hoz be a stream folyambl, melyet az s cmtl kezdve he-
lyez el a memriban. Az tvitel lell, ha a fggvny n - 1 karaktert, vagy
\nt olvasott. A rutin a \n karaktert is kiteszi a lncba, s a vghez
mg zr \0t is illeszt.
Sikeres esetben az fgets az s karakterlncra mutat mutatval tr vissza.
Fjlvgen, vagy hiba esetn viszont NULLt szolgltat.
Vegyk szre, hogy a jegyzet eleje ta hasznlt getline fggvny
csak annyiban tr el az fgetstl, hogy:
A beolvasott karakterlnc mrett adja vissza.
A szabvny bemenetrl (stdin) olvas, s nem ms folyambl, gy
eggyel kevesebb a paramtere.
n karaktert hoz be legfeljebb, vagy \nig, de magt a soremels ka-
raktert nem teszi be az eredmny karakterlncba.
size_t fread(void *ptr, size_t size, size_t n, FILE *stream);
A fggvny n * size bjtot olvas a stream folyambl, melyet a ptr para-
mterrel mutatott cmen helyez el. Visszaadott rtke nem a beolvasott
bjtok szma, hanem a
beolvasott bjtok szma / size
C programnyelv 259
sikeres esetben. Hiba, vagy fjlvg esetn ez persze nem egyezik nnel.
Az eddig ismertetett bemeneti fggvnyek nem konvertltk a beolva-
sott karakter(lnco)t. Az
int fscanf(FILE *stream, const char *format<, cim, ...>);
viszont a stream folyambl karakterenknt olvasva egy sor bemeneti me-
zt vizsgl. Aztn minden mezt a format karakterlncnak megfelelen
konvertl, s letrol rendre a paramter cimeken. A format karakterlnc-
ban ugyanannyi konverzit okoz formtumspecifikcinak kell lennie,
mint ahny bemeneti mez van.
A jellsben a <> az elhagyhatsgot, a ... a megelz paramter
tetszleges szm ismtelhetsgt jelenti. A bemeneti mez defincija,
a formzs s a konvertls rszletei a scanf fggvny lersban tallha-
tk meg!
Az fscanf a sikeresen vizsglt, konvertlt s letrolt bemeneti mezk
szmval tr vissza. Ha a fggvny az olvasst a fjl vgn ksreln meg,
vagy valamilyen hiba trtnne, akkor EOF-ot kapunk tle vissza. A rutin
zrussal is visszatrhet, ami azt jelenti, hogy egyetlen vizsglt mezt sem
trolt le.
11.7 Hibakezels
Tudjuk, hogy a szabvny knyvtri fggvnyek gy a magas szint be-
menetet, kimenetet kezelk is a hibt, a kivteles esetet gy jelzik, hogy
valamilyen specilis rtket (EOF, NULL mutat, HUGE_VAL stb.) ad-
nak vissza, s az errno globlis hibavltozba belltjk a hiba kdjt. A
hibakdok az ERRNO.H fejfjlban definilt, egsz, nem zrusrtk
szimbolikus llandk.
Programunk indulsakor a szabvny bemeneten (stdin) s kimeneten
(stdout) tl a hibakimenet (stderr) is rendelkezsre ll, s a hibazeneteket
ez utbbin clszer megjelentetni. Az stderr a kperny (karakteres ab-
C programnyelv 261
Megoldand feladatok:
Fokozzuk kicsit a PELDA31.Cben megvalstott feladatot! A fjlba
rs norml esetben akkor nem megy, ha betelik a lemez. Ezen prbljunk
meg gy segteni, hogy a forrsfjl megnyitsa utn llaptsuk meg a m-
rett! A clfjlnak is foglaljunk helyet (fseek) ugyanekkora mretben,
majd feljtva rjuk ki r a forrs tartalmt!
Ksztsen szoftvert, mely eldnti az indt parancssorban megadott azo-
nostj fjl tpust, azaz hogy szveges, vagy binris! Ha parancssori pa-
ramter nlkl futtatjk a programot, akkor ismertesse a hasznlatt!
rjon szoftvert, mely az indt parancssorban megadott szvegfjlokat
egyesti a megads sorrendjben a parancssorban utolsknt elrt azono-
stj szvegfjlba! Ha parancssori paramter nlkl indtjk a programot,
akkor ismertesse a kpernyn, hogyan kell hasznlni! Ha csak egy fjlazo-
nost van a parancssorban, akkor a szabvny bemenet msoland bele. A
fjlok egyestse sorn a folyamat elrehaladsrl tjkoztatni kell a kp-
ernyn! A szabvny bemenet msolsa esetn vgl kzlend mg az
eredmnyfjl mrete! {EGYESIT.C}
else perror(argv[1]);
return 1; } }
return 0; }
Az STDLIB.H bekapcsolsval rendelkezsre ll
int system(const char *parancs);
rutin parancs paramtert tadja vgrehajtsra az opercis rendszernek
(a parancsrtelmeznek), azaz vgrehajtatja a rendszerrel a parancsot. A
fggvny visszatrsi rtke a programfejleszt rendszertl fgg, de tbb-
nyire a parancsrtelmez ltal szolgltatott rtk az.
Ha a parancs NULL, akkor a rutin a parancsrtelmez ltezsrl sz-
mol be, azaz ha van, nem zrussal tr vissza, s zrust szolgltat, ha nincs.
A
int puts(const char *s);
fggvny a \0 lezrs s karakterlncot az stdout folyamba rja a \0
nlkl, mely helyett viszont kitesz mg egy \n karaktert.
Sikeres esetben nem negatv rtkkel tr vissza. Hiba bekvetkeztekor
viszont EOF-ot kapunk tle.
A konverzit is vgz
int printf(const char *format<, parameter, ...>);
rutin fogad egy sor parametert, melyek mindegyikhez hozzrendel egy, a
format karakterlncban lv formtumspecifikcit, s az ezek szerint for-
mzott (konvertlt) adatokat kiviszi az stdout folyamba.
A jellsben a <> az elhagyhatsgot, a ... a megelz paramter
tetszleges szm ismtelhetsgt jelenti.
7 A format karakterlncban ugyanannyi formtumspecifikcinak kell
lennie, mint ahny parameter van. Ha kevesebb a paramter, mint a for-
mtumspecifikci, akkor ez elre megjsolhatatlan hibhoz vezet. Ha
tbb a paramter, mint a formtumspecifikci, akkor a felesleges para-
mtereket egyszeren elhagyja a printf.
A rutin a folyamba kivitt bjtok szmval tr vissza sikeres esetben, ill.
EOFot kapunk tle hiba bekvetkeztekor.
A format karakterlnc ktfle objektumot tartalmaz:
sima karaktereket s
formtumspecifikcikat.
A sima karaktereket vltozatlanul kiviszi az stdout-ra a printf. A for-
mtumspecifikcihoz veszi a kvetkez parameter rtkt, konvertlja,
s csak ezutn teszi ki az stdout-ra.
A formtumspecifikci ltalnos alakja a kvetkez:
% <jelzk> <szlessg> <.pontossg> <h|l|L> tpuskarakter
Minden formtumspecifikci % karakterrel kezddik, s tpuska-
rakterrel vgzdik.
Ha a % karaktert szeretnnk az stdoutra vinni, akkor meg kell
duplzni (%%).
272 SZABVNY, MAGAS SZINT BEMENET, KIMENET
hvs paramter listjban kt int tpus paramter elzi meg (az els a
szlessg, a msodik a pontossg) azt a paramtert, amire az egsz form-
tumspecifikci vonatkozik. Lssunk egy pldt!
printf("%*.*f", 6, 2, 6.2);
A 6.2et f tpuskarakterrel kvnjuk konvertltatni gy, hogy a mezsz-
lessg 6 s a pontossg 2 legyen.
A pontossg specifikcik a kvetkezk:
Pontossg Hatsa a kimenetre
.* Lsd elbbre!
nincs rvnybe lpnek a tpuskaraktertl fgg alaprtelmezs
megadva szerinti rtkek. Ezek:
1 : d, i, o, u, x, X esetn,
6 : e, E, f tpuskaraktereknl,
minden szignifikns szmjegy g s Gnl,
s tpuskarakternl a teljes karakterlnc megy a kime-
netre s
a c tpuskarakterre nincs hatssal.
.0 Az e, E, f tpuskaraktereknl nem jelenik meg a tizedes
pont.
A d, i, o, u, x, X esetn pedig az alaprtelmezs szerin-
ti pontossg lp rvnybe (1). Ha ilyenkor a kirand
paramter rtke radsul zrus is, akkor csak egyetlen
szkz jelenik meg.
276 SZABVNY, MAGAS SZINT BEMENET, KIMENET
12 IRODALOMJEGYZK
[1] Kiss J. Raffai M. Szijrt M. Szrnyi M.: A szmtstechnika
alapjai
NOVADAT Bt., Gyr, 2001
[2] Marton L. Pukler A. Pusztai P.: Bevezets a programozsba
NOVADAT Bt., Gyr, 1993
[3] Marton Lszl: Bevezets a Pascal nyelv programozsba
NOVADAT Bt., Gyr, 1998
[4] B. W. Kernighan D. M. Ritchie: A C programozsi nyelv
Mszaki Knyvkiad, Budapest, 1985
[5] B. W. Kernighan D. M. Ritchie: A C programozsi nyelv, az ANSI
szerint szabvnyostott vltozat
Mszaki Knyvkiad, Budapest, 1996
[6] Benk Tiborn Benk Lszl Tth Bertalan: Programozzunk C
nyelven
ComputerBooks, Budapest, 1999
[7] Benk Tiborn Urbn Zoltn: IBM PC programozsa TURBO C
nyelven 2.0
BME Mrnktovbbkpz Intzet, Budapest, 1989
C programnyelv 281
13 FGGELK
A fggelkben nhny megoldand feladat programlistjt kzljk.
13.1 CHDEL.C
/* CHDEL.C: Az 'a' karakter trlse a sorokbl. */
#include <stdio.h>
#define MAX 128
#define KAR 'a' /* Itt az 'a' karakter. */
fprintf(stderr,
"Az input szvegfjlok egyestse az utols "
"paramter szvegfjlba:\n\r"
"Indts: EGYESIT inputfjl inputfjl ... "
"outputfjl\n\r");
return 1; }
/* Az output fjl megnyitsa: */
if(!(ofp=fopen(argv[argc-1],"wt"))){
fprintf(stderr, "%s outputfjl nem nyithat meg!\n\r",
argv[argc-1]);
return 1; }
/* Egy paramter esetn, a szabvny bemenet msoland: */
if(argc==2) filecopy(stdin);
/* Tbb paramternl a fjlok rendre msolandk: */
else for(i=1; i < argc-1; ++i){
if(!(fp=fopen(argv[i],"rt"))) /* Inp.fjl nyitsa: */
fprintf(stderr,"%s inputfjl nem nyithat meg!\n\r",
argv[i]);
else {
printf("\n%*s -> %-*s: ", SZELES, argv[i], SZELES,
argv[argc-1]);
filecopy(fp); /* Inp.fjl msolsa az outputba.*/
fclose(fp); } } /* Az input fjl bezrsa. */
fclose(ofp); /* Az output fjl bezrsa. */
printf("\n");
return(0);}
s[i]='\0';
while(c!=EOF&&c!='\n') c=getchar();
return(i); }
void main(void){
char sor[MAX+1]; /* Az input puffer. */
printf("\n\n\n\n\n\nHexadecimlis konverzi:\n");
printf("Adjon meg soronknt egy-egy hexadec. szmot!\n");
printf("Utoljra adjon meg egy res sort is!\n\n");
/* Sor olvassa, ellenrzse, konverzija res sorig: */
while(getline(sor, MAX)>0)
if(hexae(sor)) printf("Konvertlva: %ld\n\n",
atoh(sor));
else printf("Formailag hibs hexadec. szm!\n\n"); }
13.4 IKSZ.C
/* IKSZ.C: 21x21-es X csillag karakterrel. */
#include <stdio.h>
void main(void){
int i, j; /* Ciklusvltozk deklarcija. */
for(i=0; i<21; i=i+1){/* 21 sor lesz. */
for(j=0; j<21; j=j+1)/* Soron bell 21 pozci van. */
/* A ftl (j==i) s a mellktl (j==20-i) mentn
csillagot, a tbbi pozcin viszont szkzt kell
megjelentetni. */
284 FGGELK
void main(void){
int n; /* Az index. */
char sor[MAX+1]; /* A beolvasott sor. */
C programnyelv 285
int main(void){
char *p;
int i;
printf("%s krnyezeti vltoz rtk-lekrdezse:\n\n",
jani);
/* Vgigjrjuk a "vltoz=rtk" alak karaktertncokra
mutat mutattmbt. */
while(*environ!=NULL){
/* Ha a vltoz jani lenne, akkor p az '='-re mutatna
az aktulis "vltoz=rtk" alak kar.lncban. */
p=*environ+strlen(jani);
if(strstr(*environ, jani)==*environ&& *p=='='){
++p;
/* Ha megvan a jani vltoz, akkor p az "rtk"-re
mutat. Vgigjrva a lehetsges rtkeket,
megtalljuk jani krnyezeti vltoz rtkt is, */
for(i=0; i<IG; ++i)
if(strcmp(p, ertek[i])==0){
printf("A(z) %s %s!\n", jani, ertek[i]);
return 0; }
/* vagy sem: */
printf("A(z) %s ms!\n",jani);
return(0);}
++environ;}
/* Ide akkor kerl a vezrls, ha nincs jani a vltozk
kztt. */
printf("Nincs is %s!\n",jani);
return(1);}
13.7 KOZEPRE.C
#include <stdio.h>
286 FGGELK
#include <conio.h>
#include <string.h>
#include <ctype.h>
char *kozepre(char *, int);
13.9 NEVREND.C
/* NEVREND.C: Beolvasott, dinamikusan mutattmbben trolt
nevek rendezse. */
#include <stdio.h>
#include <string.h> /* A karakterlnc-kezels miatt! */
#include <stdlib.h> /* A dinamikus trols miatt! */
#include <ctype.h> /* A karaktervizsglatok miatt! */
#define SOROK 100 /* A trolhat nevek max.szma. */
#define LAPSOR 20 /* Egy lapra rhat nevek szma. */
int nevekbe(char *nevmutomb[], int maxnevdb);
void rendez(char *t[], int n);
void main(void){
char *nevmutomb[SOROK]; /* Neveket megcmz mutattmb.*/
int nevdb; /* A beolvasott nevek szma. */
printf("A beolvasott nevek rendezse:\n");
printf("A neveket Enter-rel kell lezrni!\n");
printf("A bemenet vgt res sor jelzi!\n\n");
if((nevdb=nevekbe(nevmutomb, SOROK))>=0){/* Beolvass. */
int i;
rendez(nevmutomb, nevdb); /* Rendezs. */
printf("\n");
for(i=0; i<nevdb; ++i){ /* Kirs lapozva. */
if(i%LAPSOR==0&&i!=0){
printf("A tovbblistzshoz ssn Enter-t! ");
while(getchar()!='\n');
printf("\n\n"); }
printf("%s\n", nevmutomb[i]); } }
else printf("\nTl sok nv, vagy elfogyott a "
"memria!\n"); }
nevmutomb[nevdb++]=p; } }
else printf("rvnytelen nv!\n"); }
return(nevdb); }
else return 1; }
void main(void){
int n=0; /* A rendezend elemek szma 0-rl indul. */
char sor[INP+1]; /* Az input puffer. */
int a[MAX]; /* A egszeket trol tmb. */
int min, max; /* Minimum, maximum. */
double osszeg=0.; /* Az sszeg */
int i;
printf("\n\n\n\n\nKrem a rendezend szmokat %d s +%d"
" kztt!\n", INT_MIN, INT_MAX);
printf( "A befejezs res sorral trtnik!\n");
while(n<MAX){ /* Bekrs a tmb uts elemig tarthat. */
printf("%3d: ",n+1);
/* Ha megadnak sort, s az egsz szm, akkor ez lesz
a tmb kvetkez eleme, s nveljk az elemszmot. */
if(getline(sor,INP)>0)
{ if(egesze(sor)) a[n++]=atoi(sor); }
/* Ha res sort adnak meg, s van mr rendezend elem,
akkor befejezdtt a bekrs. */
else if(n) break; }
min=max=a[0];
for(i=0;i<n;osszeg+=a[i],++i)
if(a[i]<min) min=a[i];
else if(a[i]>max) max=a[i];
printf("\nA szmsorozat\tminimuma:%14d.\n"
"\t\tmaximuma:%14d.\n"
"\t\ttlaga: %17.2f\n",
min, max, osszeg/n);
printf("\nA rendezett szmok:\n");
rendez(a, n);
for(i=0; i<n; i++){
printf("%13d",a[i]);
if(!((i+1)%6)) putchar('\n'); }
putchar('\n'); }
13.11PELDA18Y.C
/* PELDA18Y.C: Egsz szmok tlaga, minimuma, maximuma s
rendezse. A mdosult programsorokat megcsillagoztuk:
********* */
#include <stdio.h>
#include <stdlib.h> /* Az atoi miatt! */
#include <limits.h> /* INT_MIN s INT_MAX vgett! */
#define MAX 100 /* A tmb max. elemszma. */
#define INP 20 /* Az input puffer mrete. */
for(i=0;i<lim&&(c=getchar())!=EOF&&c!='\n';++i)s[i]=c;
s[i]='\0';
while(c!=EOF && c!='\n') c=getchar();
return(i); }
void main(void){
int n=0; /* A rendezend elemek szma. */
char sor[INP+1]; /* Az input puffer. */
int a[MAX]; /* A egszeket trol tmb. */
int min, max; /* Minimum, maximum. */
double osszeg=0.; /* Az sszeg */
int i;
while(n<1||n>MAX){
printf("\nHny egsz szmot rendeznk(1-%d)? ",MAX);
getline(sor,INP);
egesze(sor, &n);} /* ********* */
printf("\n\n\n\n\nKrem a rendezend szmokat %d s +%d"
" kztt!\n", INT_MIN, INT_MAX);
for(i=0;i<n;++i){
printf("%3d: ", i+1); /* ********* */
if(!getline(sor,INP)||!egesze(sor,&a[i])) --i; }
min=max=a[0];
for(i=0;i<n;osszeg+=a[i],++i)
if(a[i]<min) min=a[i];
else if(a[i]>max) max=a[i];
printf("\nA szmsorozat\tminimuma:%14d.\n"
"\t\tmaximuma:%14d.\n"
"\t\ttlaga: %17.2f\n",
min, max, osszeg/n);
printf("\nA rendezett szmok:\n");
rendez(a, n);
C programnyelv 291
/* Vge: */
if(isspace(*i)||!*i) return 1;
else return 0; }
int main(void){
char sor[INP+1]; /* Input puffer. */
struct Pont p[N], /* Struktratmb. */
cs; /* Rendezsnl a cserhez. */
int n=0; /* Pontok szma. */
double max=-1., d; /* Pillanatnyi maximum s */
int i, j, tavi, tavj; /* segdvltozk. */
printf("A kt egymstl legtvolabbi pont a skban, "
"majd a\npontok listja origtl mrt tvolsguk "
"sorrendjben.\n\n"
"Adja meg a pontok koordintaprjait rendre!\n"
"Vge: res sor az X koordinta megadsnl.\n\n");
for(n=0;n<N;++n){
printf("A(z) %d pont koordinti:\n",n+1);
if(printf("X: "), getline(sor, INP)<=0)break;
if(lebege(sor)) p[n].x=atof(sor);
else { --n; continue;}
while(printf("Y: "), getline(sor,INP),
!lebege(sor));
p[n].y=atof(sor); /* A tvolsg! */
p[n].tav=sqrt(p[n].x*p[n].x + p[n].y*p[n].y); }
if(n<2){
printf("Legalbb kt pontot meg kne adni!\n");
return(1);}
/* A maximlis tvolsg kt pont megkeresse: */
for(i=0;i<n-1;++i)
for(j=i+1;j<n;++j)
if((d=sqrt((p[j].x-p[i].x)*(p[j].x-p[i].x)+
(p[j].y-p[i].y)*(p[j].y-p[i].y))) > max){
max=d;
tavi=i;
tavj=j; }
printf("A maximlis tvolsg kt pont:\n"
"P[%d]: (%10.1f, %10.1f) s\n"
"P[%d]: (%10.1f, %10.1f),\n"
"s a tvolsg: %15.2f\n",
tavi+1, p[tavi].x, p[tavi].y,
tavj+1, p[tavj].x, p[tavj].y, max);
/* Rendezs az origtl mrt tvolsg szerint
cskkenleg: */
for(i=0; i<n-1; ++i){
for(j=i+1, tavi=i; j<n; ++j) if(p[j].tav>p[tavi].tav)
tavi=j;
if(i!=tavi){ cs=p[i]; p[i]=p[tavi]; p[tavi]=cs;} }
/* Listzs: */
printf("\nA listz indtshoz ssn Enter-t! ");
while(getchar()!='\n');
for(i=0; i<n; ++i){
if(i%LAPSOR==0){ /* Lapvlts? */
if(i){ /* Vrakozs a lapvgen. */
C programnyelv 293
void main(void){
unsigned long x=0X4C59E9FAul;
int i=20;
printf("Balra forgats:\n\nAz eredeti rtk: ");
binaris(x);
while(i--){
printf("\nForgatva egyet: ");
x=rotl(x);
binaris(x); }
putchar('\n'); }
13.15STRMAKRO.C
/* STRMAKRO.C: Az STRMIN.C, azaz a legrvidebb szvegsor
kivlasztsa, trsa strcopy makrval. */
#include <stdio.h>
#define MAX 128
294 FGGELK
void main(void){
char sor[MAX+1]; /* Az aktu lis sor. */
printf("\n\n\nSz"vegsor megfordt sa a saj t helyn:\n");
printf("Utolj ra adjon meg egy res sort is!\n\n");
/* Sor olvas sa, megfordt sa s kijelzse res sorig: */
while(getline(sor, MAX)>0){
strrv(sor);
printf("%s\n\n", sor); } }
13.18STRSTRXT.C
/* STRSTRXT.C: Sorban adott szveg minden elfordulsnak
megkeresse. Lsd mg az INDEXEU.C pldaprogramot is! */
#include <stdio.h>
#define INP 2 /* Az input puffer mrete. */
#define KERSZOV "az" /* A keresett karakterlnc. */
int getline(char *, int);
char *strstr(const char *, const char *);
char *strstrnext(const char *, const char *);
void main(void){
char *n; /* Az elforduls cme. */
char sor[INP+1]; /* A beolvasott sor. */
printf("Gpeljen be egy sort, melyben a(z) \'%s\' "
"szveg\nelfordulsait keressk. Vge: EOF vagy"
" res sor.\n\n", KERSZOV);
while(getline(sor, INP)>0)
if(n=strstrnext(sor, KERSZOV)){
printf("Elfordulsi indexek: ");
/* Ha az elforduls cmbl kivonjuk a tmb
kezdcmt, az elforduls indext kapjuk. */
while(printf("%d ", n-sor),
(n=strstrnext(sor, KERSZOV)));
putchar('\n'); }
else printf("Nincs benn!\n"); }
void main(void){
int i,j, /* Indexek. */
m,n, /* Sorok, oszlopok szma. */
A[SIZE][SIZE],B[SIZE][SIZE];/* A mtrixok. */
long C[SIZE][SIZE];
printf("\nKt mtrix sszeadsa s szorzsa:\n");
298 FGGELK
m=meret("Sorok ",SIZE);
n=meret("Oszlopok",SIZE);
matrixbe(m,n,A,"az els ");
matrixbe(m,n,B,"a msodik");
printf("\nAz sszegmtrix:\n\n");
for(i=0;i<m;++i){
for(j=0;j<n;++j) printf("[%2d][%2d]:%6ld ",
i+1, j+1, (long)A[i][j]+B[i][j]);
printf("\n");}
if(m==n){ /* Ha a mrixok ngyzetesek! */
szorzas(m,m,m,A,B,C);
printf("\nA szorzatmtrix:\n\n");
for(i=0;i<m;++i){
for(j=0;j<n;++j) printf("[%2d][%2d]:%10ld ",
i+1, j+1, C[i][j]);
printf("\n"); } } }
#include <conio.h>
#include <limits.h>
#if SHRT_MAX == INT_MAX
#define HOSSZ 4
#else
#define HOSSZ 9
#endif
#define F6 64
#define CTRLZ 26
#define MAX INT_MAX/10
C programnyelv 299