Bodlaki Tamás. Programozás C nyelven. Távoktatási segédlet

Hasonló dokumentumok
Járműfedélzeti rendszerek II. 1. előadás Dr. Bécsi Tamás

A C programozási nyelv I. Bevezetés

A C programozási nyelv I. Bevezetés

Programozás alapjai C nyelv 4. gyakorlat. Mit tudunk már? Feltételes operátor (?:) Típus fogalma char, int, float, double

Programozás BMEKOKAA146. Dr. Bécsi Tamás 2. előadás

Mit tudunk már? Programozás alapjai C nyelv 4. gyakorlat. Legnagyobb elem keresése. Feltételes operátor (?:) Legnagyobb elem keresése (3)

1.1. A forrásprogramok felépítése Nevek és kulcsszavak Alapvető típusok. C programozás 3

1. Olvassuk be két pont koordinátáit: (x1, y1) és (x2, y2). Határozzuk meg a két pont távolságát és nyomtassuk ki.

Számítástechnika I. BMEKOKAA152 BMEKOKAA119 Infokommunikáció I. BMEKOKAA606. Dr. Bécsi Tamás 2. előadás

Vezérlési szerkezetek

Készítette: Nagy Tibor István

3 A C programozási nyelv szintaktikai egységei

Programozás 1. Dr. Iványi Péter

1. Egyszerű (primitív) típusok. 2. Referencia típusok

Java II. I A Java programozási nyelv alapelemei

C programozás. 1 óra Bevezetés

Programozás I. 3. gyakorlat. Szegedi Tudományegyetem Természettudományi és Informatikai Kar

Készítette: Nagy Tibor István

Programozás alapjai gyakorlat. 4. gyakorlat Konstansok, tömbök, stringek

Programozás alapjai. (GKxB_INTM023) Dr. Hatwágner F. Miklós augusztus 29. Széchenyi István Egyetem, Gy r

C programozási nyelv Pointerek, tömbök, pointer aritmetika

Operációs rendszerek. 11. gyakorlat. AWK - szintaxis, vezérlési szerkezetek UNIVERSITAS SCIENTIARUM SZEGEDIENSIS UNIVERSITY OF SZEGED

1. Gyakorlat. Rövid elméleti összefoglaló. <tárolási osztály>típus <típus > változónév <= kezdőérték><, >;

Java programozási nyelv

Megoldott programozási feladatok standard C-ben

Vezérlési szerkezetek. Szelekció Ciklusok

Programozás 3. Dr. Iványi Péter

Programozás C- és Matlab nyelven C programozás kurzus BMEKOKAM603 Előfeldolgozó rendszer Tömbök. Dr. Bécsi Tamás 4. Előadás

1. Alapok. #!/bin/bash

Programozás alapjai 3.Gy: C elágazások, ciklusok P R O

Tömbök kezelése. Példa: Vonalkód ellenőrzőjegyének kiszámítása

Programozás alapjai gyakorlat. 2. gyakorlat C alapok

A programozás alapjai előadás. A C nyelv típusai. Egész típusok. C típusok. Előjeles egészek kettes komplemens kódú ábrázolása

Mintavételes szabályozás mikrovezérlő segítségével

A C# programozási nyelv alapjai

Függvények. Programozás alapjai C nyelv 7. gyakorlat. LNKO függvény. Függvények(2) LNKO függvény (2) LNKO függvény (3)

Programozás alapjai C nyelv 7. gyakorlat. Függvények. Függvények(2)

Occam 1. Készítette: Szabó Éva

Programozás alapjai 2.Gy: A C nyelv alapjai P R O

Járműfedélzeti rendszerek II. 3. előadás Dr. Bécsi Tamás

11. gyakorlat Sturktúrák használata. 1. Definiáljon dátum típust. Olvasson be két dátumot, és határozza meg melyik a régebbi.

/* Az iter függvény meghívása és a visszatérő érték átadása a gyok változóba */ gyok = iter( n, a, e ) ;

1. Feladat: beolvas két számot úgy, hogy a-ba kerüljön a nagyobb

Szoftvertervezés és -fejlesztés I.

Java II. I A Java programozási nyelv alapelemei

Programozás I gyakorlat

Algoritmusok pszeudókód... 1

Programozás alapjai 5. gyakorlat Vezérlési szerkezetek egymásba ágyazása

Programozás II. 2. Dr. Iványi Péter

Programozás I. Matematikai lehetőségek Műveletek tömbökkel Egyszerű programozási tételek & gyakorlás V 1.0 OE-NIK,

6. gyakorlat Egydimenziós numerikus tömbök kezelése, tömbi algoritmusok

Algoritmusok pszeudókód... 1

A C programozási nyelv III. Pointerek és tömbök.

Objektumorientált Programozás III.

Programozás. (GKxB_INTM021) Dr. Hatwágner F. Miklós február 18. Széchenyi István Egyetem, Gy r

Programozás I. gyakorlat

Webprogramozás szakkör

Programozás alapjai. (GKxB_INTM023) Dr. Hatwágner F. Miklós szeptember 27. Széchenyi István Egyetem, Gy r

Programozas 1. Strukturak, mutatok

Kifejezések. Kozsik Tamás. December 11, 2016

A C programozási nyelv III. Pointerek és tömbök.

Felvételi tematika INFORMATIKA

Változók. Mennyiség, érték (v. objektum) szimbolikus jelölése, jelentése Tulajdonságai (attribútumai):

Tartalomjegyzék Algoritmusok - pszeudókód

S z á m í t ó g é p e s a l a p i s m e r e t e k

BASH script programozás II. Vezérlési szerkezetek

INFORMATIKA javítókulcs 2016

Mechatronika és mikroszámítógépek 2017/2018 I. félév. Bevezetés a C nyelvbe

C programozási nyelv

INFORMATIKA tétel 2019

7. gyakorlat. Fájlkezelés IO haladó Függvények haladó

1. Bevezetés szeptember 9. BME Fizika Intézet. Szám. szim. labor ea. Tőke Csaba. Tudnivalók. feladat. Tematika. Moodle Házi feladatok

Óbudai Egyetem. C programozási nyelv

Programozási nyelvek I. 5. előadás (Gregorics Tibor anyagának felhasználásával)

Programozás C++ -ban 2007/1

Kifejezések. Kozsik Tamás. December 11, 2016

Bevezetés a C programozási nyelvbe. Az Általános Informatikai Tanszék C nyelvi kódolási szabványa

5. gyakorlat. Konstansok Tömbök Stringek

Járműfedélzeti rendszerek II. 4. előadás Dr. Bécsi Tamás

Karakterkészlet. A kis- és nagybetűk nem különböznek, a sztringliterálok belsejét leszámítva!

Karakter- és sztringkezelő függvények, matematikai függvények

Informatika terméktervezőknek

Kifejezések. A programozás alapjai előadás. Operátorok. Kifejezések. Operátorok precedenciája. Operátorok precedenciája

Programozás alapjai. 5. előadás

7. Laboratóriumi gyakorlat: Vezérlési szerkezetek II.

Programozás C nyelven FELÜLNÉZETBŐL elhullatott MORZSÁK. Sapientia EMTE

Programozás I gyakorlat

8. gyakorlat Pointerek, dinamikus memóriakezelés

Programozás C- és Matlab nyelven C programozás kurzus BMEKOKAM603 Mutatók. Dr. Bécsi Tamás 7. Előadás

Programozás alapjai 9.Gy: Struktúra 2.

Segédlet az Informatika alapjai I. című tárgy számrendszerek fejezetéhez

Forráskód formázási szabályok

5. Gyakorlat. struct diak {

Programozás 6. Dr. Iványi Péter

1. Írjunk programot mely beolvas két számot és ellenőrzi hogy mindkét szám zérus-e:

Bevezetés a C++ programozási nyelvbe

10. gyakorlat Struktúrák, uniók, típusdefiníciók

Járműfedélzeti rendszerek II. 2. előadás Dr. Bécsi Tamás

Függvény pointer. Feladat: Egy tömbben soroljunk fel függvényeket, és hívjuk meg valahányszor.

Programozás alapjai 8.Gy: Program struktúra

Átírás:

Bodlaki Tamás Programozás C nyelven Távoktatási segédlet

TARTALOMJEGYZÉK 1. Bevezetés... 7 2. A C nyelv egyszerû adattípusai... 8 2.1 Az elsô C program beírása és futtatása... 8 2.2 Az alapvetô egyszerû adattípusok felsorolása... 8 2.3 A printf() függvény leírása... 10 2.4 A scanf() függvény leírása... 11 2.5 Konstansok definiálása... 12 2.6 Változók inicializálása... 13 2.7 Megjegyzések a programon belül... 13 3. Mûveletek és operátorok... 14 3.1 Aritmetikai operátorok... 14 3.2 Relációs operátorok... 15 3.3 Logikai operátorok... 15 3.4 Értékadó kifejezések és operátorok... 15 3.5 Inkrementáló és dekrementáló operátorok... 15 3.6 Méret operátor... 16 3.7 Bitenkénti operátorok... 16 3.8 Típuskonverzió... 19 Automatikus... 19 Kikényszerített... 20 3.9 Precedencia táblázat... 20 3.10 Fontosabb matematikai függvények leírása... 21 4. Vezérlési szerkezetek... 22 4.1 Szelekció... 22 Az if - else utasítás... 22 A? operátor... 23 Az else - if szerkezet... 24 A switch utasítás... 25 4.2 Ciklusok... 26 A while utasítás... 26 A do - while utasítás... 27 A for utasítás... 29 A break utasítás... 31 A continue utasítás... 31 4.3 A goto utasítás, cimkék... 31 Feladatok a 2. - 3. - 4. fejezetek anyagából... 32

5. Tömbök - I. rész... 33 5.1 Egydimenziós tömbök... 34 5.2 Kétdimenziós tömbök... 35 Feladatok az 5. fejezet anyagából... 37 6. Karaktertömbök és karaktermüveletek... 38 6.1 Karaktertömbök... 38 6.2 Karaktermûveletek... 39 A getchar() függvény... 39 A putchar() függvény... 39 A getch() ill. getche() függvények... 40 A scanf() függvény... 41 6.3 Stringkonverziós mûveletek... 43 Numerikus értékek stringgé alakítása... 43 String numerikus értékekké alakítása... 44 Feladatok a 6. fejezet anyagából... 45 7. Függvények - I. rész... 46 7.1 A függvények általános jellemzôi... 46 7.2 Változók érvényességi köre... 48 7.3 Paraméterátadás kérdése... 49 Feladatok a 7. fejezet anyagából... 49 8. Mutatók ( Pointerek ) - I. rész... 50 8.1 Általános rész... 50 8.1 Változó címének átadása... 50 8.2 Indirekció... 50 Feladatok a 8. fejezet anyagából... 54 9. Függvények - II. rész... 55 9.1 Tárolási osztályok... 57 Automatikus... 57 Extern... 57 Statikus... 58 Regiszter... 58 Feladatok a 9. fejezet anyagából... 59 10. Tömbök - II. rész... 60 10.1 Egydimenziós tömbök és pointerek... 60 10.2 Címaritmetika... 61 10.3 Kétdimenziós tömbök és pointerek... 62

10.4 Memória kezelés... 64 Feladatok a 10. fejezet anyagából... 67 11. Mutatók ( Pointerek ) - II. rész... 68 11.1 Pointertömbök... 68 11.2 Függvényre mutató pointer... 70 11.3 Függvényekre mutató pointertömbök... 71 12. Struktúrák... 73 12.1 A struktúra fogalma, deklarálása, definíciója... 73 12.2 Struktúrák és függvények... 75 Struktúra címének elôállítása... 75 Struktúra taghoz való hozáférés a "->" operátorral... 75 12.3 Struktúratömbök... 77 Feladatok a 11. - 12. fejezet anyagából... 79 13. Parancssor argumentumok használata... 80 14. Típusnév definíciók... 82 15. File kezelés - I. rész... 83 15.1 Szabványos be és kimenet átirányítása... 83 15.2 File deklaráció... 83 15.3 File megnyitása... 84 15.4 File írása... 85 Egy karakter kiírása... 85 Formátumozott változólista kiírása... 85 15.5 File olvasása... 85 Egy karakter beolvasása... 85 Formátumozott változólista beolvasása... 86 15.6 File lezárása... 86 Feladatok a 13. - 14. - 15. fejezet anyagából... 88 16. File kezelés - II. rész... 89 16.1 File elejére történô pozicionálás... 89 16.2 Adategység formátum nélküli kiiratása... 89 16.3 Adategység formátum nélküli beolvasása... 89 16.4 File vége ( EOF) vizsgálat... 90 Feladatok a 16. fejezet anyagából... 95 Függelék : A Borland C++ 2.0 alapvetô grafikai függvényei... 96 Kidolgozott feladatok...102

1. Bevezetés A C nyelv megalkotója Dennis Ritchie, aki egy PDP gépen készitette el a fordítót. A nyelv hatékonyságára jellemzô, hogy a UNIX operációs rendszer túlnyomó része C nyelven íródott. Csak a legalapvetôbb rutinokat írták gépi nyelven. A C nyelv alapvetô tulajdonságai közé tartozik a tömörség, a függvénycentrikusság és a pointerek elterjedt használata, valamint az, hogy a függvényhívásnál a paraméterátadás érték szerinti. Egy egyszerû C program általában a következôképpen néz ki : #include <stdio.h> /* Header file ; lehet több is! */ main() /* F ô p r o g r a m */ függvény_01() /* A függvények használata esetleges, */ /* az adott feladattól függ */ függvény_02() függvény_03() Egy C program tehát nem más, mint C függvények diszjunkt halmaza. A segédletben szereplô példaprogramokat a BORLAND C++ 2.0 verziójú fordítójával fordítottuk. Felhasznált irodalom : B.W. Kernighan - D.M. Ritchie : A C programozási nyelv Mûszaki Könyvkiadó, Budapest, 1988 Thomas Plum : Tanuljuk meg a C nyelvet. Novotrade Rt, Budapest 1987

2. A C nyelv egyszerû adattípusai 2.1 Az elsô C program beírása és futtatása #include <stdio.h> /* A printf függvény használata miatt szükséges */ void main() printf("kupacsapataink szereplése elkeserítô!\n"); A szövegben szereplô '\n' az új sor jele. Az <stdio.h> a szabványos I/O mûveletekkel kapcsolatos definíciókat tartalmazza. A C utasításokat a ';' zárja! 1. sz. példaprogram : #include <stdio.h> void main() // A void jelzi, hogy a main nem ad // vissza értéket int x,y; printf("\nkérem az elsô számot : ");scanf("%d",&x); printf("\nkérem a második számot : ");scanf("%d",&y); printf("\nx + Y = %d\n",x+y); 2.2 Az alapvetô egyszerû adattípusok felsorolása Minden adatot definiálni kell, azok használata elôtt. Az alapvetô adattípusok a következôk : Típus Értelmezés Byte Definíció karakter Az érvényes karakterkészlet egy eleme. 1 char integer Bináris egész szám. 2 int 0

float Egyszeres pontosságú lebegôpontos szám. 4 float double Kétszeres pontosságú lebegôpontos szám. 8 double A definíció a tárolási osztálynak, változó típusának majd - egy vagy több szóköz után - a változó nevének megadásából áll. Ezt egy ; ( pontosvesszô ) karakter követi. A változó neve tartalmazhat betûket, számokat és az _ ( aláhúzás ) karaktert, de mindenképpen betûvel vagy aláhúzással kel kezdôdnie. A Borland C++ 2.0 a változó nevének elsô 32 karakterét különbözteti meg! ( Az elsô 32 karakter szignifikáns! ) A kis és nagybetûk között a fordító különbséget tesz! A változó nevét célszerû "beszédesre" választani, azaz jó ha elárulja azt, hogy mire akarjuk használni! A C nyelvben azonban nemcsak a felsorolt alapvetô adattípusok használhatók, ugyanis létezik néhány minôsítô szimbólum, melyek egész jellegü mennyiségek esetén használhatók, ill.egy esetben a double alaptípusra is. A minôsítô szimbólumok a következôk : short long unsigned "rövid" "hosszú" "elôjel nélküli" A short az int típust minôsítheti, a long szintén az int-et, valamint a BORLAND C++ 2.0-ban a double típust is. Az unsigned minôsítô a char, ill. az int típusok e- lôtt állhat, beleértve a már - short-tal vagy long-gal - minôsített int típust. Típus Értelmezés Méret (byte) Minôsítô short integer "Rövid" bináris egész szám. 2 short long integer "Hosszú" egész szám. 4 long long double "Hosszú" double szám 10 long double Megjegyzés : A long double típus nem eleme az alap C változótípusainak, késôbbi C fordítókban hozták létre. A számábrázolási tartományok a következôk, az összes lehetséges esetet figyelembe véve : Változótípus Alsó határ Felsô határ char : -128 127 unsigned char : 0 255 int : -32 768 32 767 unsigned int : 0 65 535 1

long int : -2 147 483 648 2 147 483 647 unsigned long : 0 4 294 967 295 float : 3.4E - 38 3.4E + 38 double : 1.7E - 308 1.7E + 308 long double : 1.2E - 4932 1.2E + 4932 A short ill. int más gépeken ( pl. IBM 370 ) különbözô méretü : a short 16, az int 32 bit hosszú. Jelen esetben mindkettô 16 bit hosszú! Példa a definícióra : char c; int i,j; unsigned k; long l; float f; double d; Konstansok : Egész típusú : -123, 12 Oktális : 034 / Mindig a 0 (nulla) karakterrel kezdôdik! / Hexadecimális : 0x1f Long : 123L Lebegôpontos : 123.45, -23.56, 0.12345E3 Karakteres : 'A' Láthatjuk tehát, hogy mind tízes, mind nyolcas ill. tizenhatos számrendszerben megadhatunk konstansokat. Figyelembe kell venni azt a tényt, hogy oktális számok esetén a 08 szintaktikus hibát eredményez, hiszen nyolcas számrendszerben a legnagyobb számjegy a 7-es! Minden konstansnál figyelembe kell venni az illetô típus számábrázolási határát. Minden lebegôpontos konstans double típusként vesz részt a mûveletekben. 2.3 A printf() függvény leírása Általános alak : printf("<formátum vezérlô mezô>"[,<változólista>]); Példa : printf("\n I értéke = %d",i); 2

Leírás : A formátum vezérlô mezô állhat szövegbôl, karakteres állandókból ill. formátum vezérlô karakterekbôl. A karakteres állandók a '\' ( back slash ) - sel kezdôdnek. Alapvetô karakteres állandók : '\n' = Új sor '\t' = Tabulátor '\f' = Lapdobás A formátum vezérlô karaktereket mindig a % jel elôzi meg, utána következhet több karakter, ami utal a kiiratni kívánt változó típusára, és a kiiratás formátumára. A függvény mûködése során a formátumvezérlô karakterek helyére rendre behelyettesíti a változólista elemeit. Fontos : Ha több formátumvezérlô karakter van, mint ahány változót megadtunk a listában, akkor azon vezérlôkarakterek helyén, amelyekhez nem tartozik változó, véletlen érték fog megjelenni. Ha hosszabb, mint ahány formátumvezérlô karakter van, akkor a lista végén szereplô változók értékei nem jelennek meg a kiiratásnál! Alapvetô formátum vezérlô karakterek : %d = Integer %ld = Long integer %x = Hexadecimális egész %o = Oktális egész %f = Float %lf = Double %c = Egy karakter %s = Karakterlánc (string) A változólista a kiiratni kívánt változók neveit tartalmazza, vesszôvel elválasztva egymástól. Mód van a kiiratni kívánt érték mezôszélességének megadására is. Amennyiben egy integert n számjegy szélességben akarunk kiiratni, akkor a megfelelô formátumvezérlés a következô : "%nd". Ebben az esetben az n számjegynél kisebb egészek balról szóközökkel lesznek feltöltve. Például : a "%6d" formátumvezérlés a 123-at a következôképpen írja ki : 123. Lebegô pontos számok esetén a szélesség megadása a következô : "%x.yf", ahol x a teljes számhosszúságot jelenti - a tizedespontot is beleszámítva -, y pedig a tizedesjegyek számát. Például : a "%8.2" formátumvezérlés a 123.45-öt a következôképpen írja ki : 123.45. 3

2.4 A scanf() függvény leírása Általános alak : scanf("<formátum vezérlô mezô>",<változócim lista>); Példa : scanf("%f",&f); Leírás : A formátum vezérlô mezô formátum vezérlô karakterekbôl állhat. Ld.: a printf() függvény leírásánál. Mivel a scanf függvény a változó(k)-ban el akarja helyezeni a beolvasott értéket, ezért a változó(k) címeit kell átadni. Ennek a ténynek a részletes magyarázatára késôbbiekben térünk ki! A változó címét a változó neve elé írt & karakter segítségével tudjuk elôállítani. Amennyiben egyszerre több változóba akarunk értékeket beolvasni, úgy kétféle módszert alkalmazhatunk : 1.) A programban a formátumvezérlô karaktereket vesszôvel választjuk el egymástól, és a program futása során a bebillentyûzött értékeket is vesszôvel választjuk el. Példa : int x, y, z ; scanf("%d,%d,%d",&x,&y,&z); esetén a beolvasás a következôképpen történik : 2,3,4 <ENTER>. 2.) A programban a formátumvezérlô karaktereket nem választjuk el egymástól, és a program futása során az egyes bebillentyûzött értékek után lenyomjuk az <ENTER> billentyût. Példa : int x, y, z ; scanf("%d%d%d",&x,&y,&z); esetén a beolvasás a következôképpen történik : 2 <ENTER>, 3 <ENTER> 4 <ENTER> 4

2.5 Konstansok definiálása A konstansok definiálása a main() elôtt történik a következô alakban: #define <KONSTANS NEVE> <konstans értéke> pld.: #define MAXELEM 1000 vagy : #define PI 3.1415 MAXELEM és PI úgynevezett szimbolikus állandók, melyeket nagybetûvel szokás írni. Az állandókat egy úgynevezett elôfordító a fordításkor behelyettesíti a programba. A konstans definíciók után tilos pontosvesszôt tenni, ugyanis az elôfordító nemcsak a konstans értékét, hanem a pontosvesszôt is behelyettesítené a hivatkozás helyére. A szimbolikus állandók használata egyrészt áttekinthetôbbé teszi a programot, másrészt, ha a konstans értéke megváltozik, akkor a módosítást csak egyszer kell végrehajtani. Példa a szimbolikus állandó használatára : Megjegyzés : ker = 2*r*PI ; /* A kör kerülete */ vagy : x = MAXELEM - 100 ; A BORLAND C++ 2.0 fordító lehetôséget nyújt arra, hogy másképpen is tudjunk konstansokat definálni. Ez a lehetôség a const kulcsszó, melynek használata a következô : const [<típus>] <konstans név> = <kezdôérték>; Például : const int i = 123; vagy const float f = 123.4; A konstans típusát áttekinthetôségi okokból is célszerû jelezni. A két konstans definálási lehetôség megegyezik abban, hogy egy definiált konstansnak már nem adhatunk új értéket a program futása során. A különbség pedig abban áll, hogy a const a BORLAND C++ fordító egyik kulcsszava és az általa definiált konstans neve és értéke része lesz a fordítás során keletkezô tárgykódnak. Ezzel ellentétben a #define direktíva a fordító elôfeldolgozó részére bír csak jelentéssel, ugyanis az általa definiált konstans nevével a C fordító már nem találkozik, hanem csak az értékével. Ilymódon a tárgykódban a konstans neve nem szerepel, hanem csak az értéke. 5

2.6 Változók inicializálása A változó definiálásakor megadhatunk egy konstans értéket, például : int i=0; float f=67.25; Az értékadást az '=' jellel hajtjuk végre és minden utasítást a ';' zár le! A változó inicializálás és a konstans definiálás között az alapvetô különbség az, hogy inicializálás esetén a változó értéke módosítható, konstans definíció esetén pedig nem! 2.7 Megjegyzések a programon belül C programokhoz megjegyzést a /* ill. */ közé lehet elhelyezni. A megjegyzések nem ágyazhatók egymásba! Tetszôleges sorban, oszlopban kezdôdhetnek és végzôdhetnek. Például : /* Itt kezdôdik a bemenô adat vizsgálata! */ jó, de /* Kiiratás /* A,B,C és D */ a képernyôre */ alak hibás! A megjegyzés másik lehetôsége a // (két per jel) alkalmazása. Csak arra a sorra vonatkozik, ahol áll! 6

3. Mûveletek és operátorok 3.1 Aritmetikai operátorok Öt fajta létezik a C nyelvben : +, -, *, /, %. Ha két egész számot osztunk, akkor az eredmény a hányados egész része lesz. A % operátor két egész osztása esetén a maradékot adja eredményül, float ill. double típusra nem alkalmazható! Pld.: 5/3 = 1 és 5%3 = 2. Ezen operátorok közül az elôjel (-) precedenciája a legmagasabb, utána következik a /, *, % majd a +, -. Az aritmetikai operátorok balról jobbra kötnek. Ennek a ténynek fôleg azonos precedenciájú mûveleteknél van jelentôsége. Pl.: 4/2*2 = 4 és nem 1. A mûveletek végrehajtási sorrendjét zárójelezéssel befolyásolhatjuk : '(' ill. ')'. Ebben az esetben : 4/(2*2) = 1. A zárójelezés precedenciája ugyanis megelôzi a többi operátorét! Fontos : Ha valamely összetett mûvelet eredménye int típusú és a mûveletben résztvevô változók is int típusúak, ettôl függetlenül valamely részmûvelet eredménye túllépheti az int ábrázolási tartományát ( túlcsordulás! ). Ebben az esetben célszerû típusmódosítást elôírni. 2. sz. példaprogram : #include <stdio.h> main() int i,j,k,q; printf("\nkérem J értékét : ") ; scanf("%d",&j); printf("\nkérem K értékét : ") ; scanf("%d",&k); printf("\nkérem Q értékét : ") ; scanf("%d",&q); i = (j*k)/q ; printf("\nsimán -> I = %d",i); // Típusmódosítással : i = (long) (j)*k/q ; printf("\n(long) -> I = %d",i);

A típusmódosításról még lesz szó! 3.2 Relációs operátorok Azonos precedenciájúak : >, >=, <, <=. Eggyel alacsonyabb szinten azonos precedenciájúak :,!=. Az operátor két operandus egyenlôségét vizsgálja és ezzel a jelölésmóddal különböztetjük meg az értékadástól. A!= operátor a "nem egyenlô" reláció jelölésére szolgál. A relációs operátorok precedenciája alacsonyabb mint az aritmetikai operátoro ké. Bármely relációs kifejezés igaz vagy hamis értéke integerré (1 vagy 0) konvertálódik, amint azt a 3.8.1 pontban látni fogjuk! 3.3 Logikai operátorok && : Logikai ÉS, : Logikai VAGY,! : Logikai NEM. A && és a szimbólumokkal összekapcsolt kifejezések kiértékelése balról jobbra történik, és a kiértékelés azonnal megáll, amint az eredmény igaz vagy hamis volta kiderül! A && precedenciája magasabb mint az -é, de mindkettôé alacsonyabb mint az elôbbieké! A NEM precedenciája a () után következik. 3.4 Értékadó kifejezések és operátorok Az olyan típusú kifejezések mint pld. osszeg = osszeg + forint a += értékadó operátorral úgy írhatjuk, hogy osszeg += forint. Ez igaz az eddig tanultak közül a +, -, *, /, % operátorokra. Ez az írásmód tömörebb, jobban kifejezi a lényeget és a végrehajtása is gyorsabb. Figyeljünk arra, hogy az ilyen kifejezések mint pld. y* = x+1 ; azt jelentik, hogy y = y*(x+1); és nem azt, hogy y = y*x+1 ; 3.5 Inkrementáló és dekrementáló operátorok Az inkrementáló operátor jele : ++, a dekrementálóé --. Mindkét operátor lehet prefix vagy postfix operátor. A ++ operátor 1-gyel növeli azt a változót amely elôtt, vagy amely után áll, mig a -- operátor 1-gyel csökkenti a változó tartalmát. Ha értékadásban, vagy más mûveletben vesznek részt, akkor a következôre kell nagyon vigyázni :

3. sz. példaprogram (részlet) : x = 5; // A ++ prefix-ként y = ++x; // x értéke elôszôr 6 lesz és ez adódik át y-ba // x = 6 és y = 6. x = 5; // A ++ postfix-ként y = x++; // x értéke elôszôr átadódik y-ba, utána lesz 6 // x = 6 és y = 5. Ugyanez vonatkozik a -- operátorra. A ++ és a -- nem használható kifejezésekre, például : x = (i+j)++ nem megengedett! 3.6 Méret operátor A méret operátor - sizeof - valamely objektum méretét adja vissza byte-okban. Például : sizeof(long) = 4. 3.7 Bitenkénti logikai operátorok A bitenkénti operátorok jelölésmódja és értelmezése a következô : & : bitenkénti ÉS : bitenkénti VAGY ^ : bitenkénti KIZÅRÓ VAGY <<: bitléptetés balra (SHIFT LEFT) >>: bitléptetés jobbra (SHIFT RIGHT) ~ : egyes komplemens képzés ( egyoperandusú! ) Az operátorok mûködésének magyarázata a következô : - Az & kétoperandusú mûvelet eredménye csak akkor 1, ha mindkét operandus ugyanazon bitpozíciójában elhelyezkedô bitek értéke egyaránt 1. Minden más esetben az eredmény 0. Az & operátort valamely bithalmaz maszkolására használhatjuk. - Az kétoperandusú mûvelet eredménye csak akkor nulla, ha mindkét operandus ugyanazon bitpozíciójában elhelyezkedô bitek értéke egyaránt 0. Minden más esetben az eredmény 1. A operátort bit(ek) 1-re állítására használhatjuk.

- Az & ill. nem tévesztendô össze a && ill. operátorokkal. Például : ha x értéke 2 és y értéke 4, akkor x & y = 0 ill. x && y = 1 : x = 00000010 = 2 y = 00000100 = 4 ---------------------- x&y = 00000000 = 0 ill. x && y értéke nyilván 1 lesz mert x is igaz és y is igaz. ( Értékük nullától különbözô! ) - A ^ kétoperandusú mûvelet eredménye csak akkor 1, ha mindkét operandus ugyanazon bitpozíciójában elhelyezkedô bitek értéke egymással ellentétes. Ellenkezô esetben az eredmény 0. - A << kétoperandusú mûvelet során a baloldali operandus minden bitje, annyiszor mozdul el balra 1 pozicióval, ahányszor azt a jobb oldali operandussal megadjuk. - A >> kétoperandusú mûvelet során a baloldali operandus minden bitje, annyiszor mozdul el jobbra 1 pozicióval, ahányszor azt a jobb oldali operandussal megadjuk. - A ~ egyoperandusú mûvelet a mögötte álló operátor 1-es komplemensét állítja elô, azaz minden 1-es bitet nullára állít és viszont. Fontos : A bitmûveletek kizárólag egész jellegü mennyiségekre értelmezettek (példánkban a char típusra), float és double típusú változókra nem alkalmazhatók! 4. sz. példaprogram : // Példa a bitmûveletekre #include <stdio.h> #include <conio.h> // A getch() függvény miatt szükséges void main() char x, y, es, vagy, kizaro_vagy; char bitlep_bal, bitlep_jobb; unsigned char egyes_kompl;

x = 0x06 ; y = 0x03 ; es = x & y ; vagy = x y ; kizaro_vagy = x ^ y ; bitlep_bal = x << 3 ; bitlep_jobb = bitlep_bal >> 3 ; egyes_kompl = ~x ; clrscr(); printf("\nx = %x Y = %x\n",x,y); printf("\nx & Y = %d\n",es); printf("\nx Y = %d\n",vagy); printf("\nx ^ Y = %d\n",kizaro_vagy); printf("\nx << 3 = %d\n",bitlep_bal); printf("\nx >> 3 = %d\n",bitlep_jobb); printf("\n~x = %d\n",egyes_kompl); getch(); A program eredményül a következô értékeket szolgáltatja : Az es értéke 2, a vagy értéke 7, a kizaro_vagy-é 5. A bitlep_bal értéke 48 lesz, míg a bitlep_jobb-é 6. Végezetül az egyes_kompl értéke 249 lesz. Az eredmények alakulását a következô táblázat magyarázza : 128 64 32 16 8 4 2 1 Eredmény =============================== X 0 0 0 0 0 1 1 0 6 Y 0 0 0 0 0 0 1 1 3 =============================== X & Y 0 0 0 0 0 0 1 0 2 X Y 0 0 0 0 0 1 1 1 7 X ^ Y 0 0 0 0 0 1 0 1 5 X << 3 0 0 1 1 0 0 0 0 48 BITLEP_JOBB>>3 0 0 0 0 0 1 1 0 6 ~X 1 1 1 1 1 0 0 1 249

3.8 Típuskonverziók Amennyiben egy kifejezésben különbözô típusú operandusok fordulnak elô, úgy a kiértékeléshez az operandusokat azonos típusúakká kell alakítani. A típuskonverziónak két fajtája van : automatikus és kikényszeritett. Automatikus típuskonverzió Általános szabály : Ha az operandusok különbözô típusúak, akkor az alacsonyabbik típusú alakul át magasabb típusúvá, a mûveletek elvégzése elôtt. Az eredmény magasabb típusú lesz. 5. sz. példaprogram (részlet) : int i; float z,y;... z = y + i; /* i -bôl elôször float-ot csinál a program */ Konkrétan : - char és short mennyiségek int típusúvá alakulnak át, a float mennyiségek double típusúvá. Ezért van értelme pl. annak, hogy : q = '1' ; k = q - '0' ; /* k értéke 1 lesz a 49-48 mûvelet miatt */ - relációs ill. logikai kifejezések értéke 1, ha a kifejezés értéke igaz, és 0 ha hamis. Például : a=2 ; b=2 ; c = (a == b) ; /* c értéke 1 lesz */ c = (a!= b) ; /* c értéke 0 lesz */ - ezután ha az egyik operandus long double, akkor a másik is az lesz és az eredmény is. - ezután ha az egyik operandus double, akkor a másik is az lesz és az eredmény is.

- egyébként ha az egyik operandus long, akkor a másik is az lesz és az eredmény is. - egyébként ha az egyik operandus unsigned, akkor a másik is az lesz és az eredmény is. - egyébként az operandusoknak int típusúaknak kell lenniük és az eredmény is az lesz. - az értékadás szintén típuskonverzióval jár : a jobboldal értéke átalakul a baloldal típusának megfelelõen. A float-ból int-be történô konverzió a törtrész levágását eredményezi. A double-bôl float-tá történô konverzió kerekítéssel történik. - függvényeknek történô argumentumátadás esetén a char és a short típusok int-té válnak, a float típus double típusúvá! Kikényszerített típuskonverzió - cast operátor Alakja : (típusnév) kifejezés. Szükséges lehet a 7. oldalon található 2. sz. példaprogramban említett példán kívül, hasonló esetben is : A könyvtári gyökvonó függvény ( sqrt ) bemenô paraméterül double típusú változót vár. Ha int típusból akarunk gyököt vonni, úgy típuskonverziót kell alkalmazni : int n = 9; double eredm; eredm = sqrt( (double) n ) ; /* eredm értéke 3.000000 lesz */ 3.9 Az eddig tanult operátorok precedencia táblázata Operátor Asszociativitás () balról jobbra!, ~, ++, --, -, (tipus), sizeof jobbról balra *, /, % balról jobbra +, - balról jobbra <<, >> balról jobbra <, <=, >, >= balról jobbra ==,!= balról jobbra & balról jobbra ^ balról jobbra balról jobbra && balról jobbra

balról jobbra =, +=, -=, *=, /=, %= jobbról balra Fontos : Az olyan típusú kifejezések esetén mint az x = f() + g();, ahol f és g két függvény nem tudjuk, hogy a fordító elôször f-et és utána g-t számítja ki, vagy fordítva. Igy, ha akár f akár g olyan változót módosít, amelytôl a másik függ, x értéke függhet a kiértékelési sorrendtôl. ( Mellékhatás jelensége! ) Megoldás : Åtmeneti változók használata. z = f() ; /* Elôször f() -et számoljuk */ w = g() ; /* Utána g() -t számoljuk */ x = z + w ; /* Meghatározzuk a mûveletvégzés sorrendjét */ 3.10 Fontosabb matematikai függvények leírása A Borland C++ 2.0 többek között a következô könyvtári függvényeket tartalmazza : Szintakika Leírás ---------------------------------------------------------------------------------------------- int abs( int x ) x egész szám abszolútértéke long labs( long y ) y long szám abszolútértéke double fabs( double z ) z double szám abszolútértéke double sqrt( double w ) w double szám négyzetgyöke double pow( double p, double q ) p a q - adikon hatvány értéke double sin( double b ) b szög szinusza, b radiánban értendô double cos( double c ) c szög koszinusza, c radiánban értendô double tan( double d ) d szög tangense, d radiánban értendô A matematikai függvények használatához a #include <math.h> szükséges! A matematikai függvények használatát - többek között - a 11. sz. példaprogram mutatja be.

4.1 Szelekció 4. Vezérlési szerkezetek 4.1 Szelekció Az utasításokat a '' (begin) ill. '' (end) zárójelek használatával egyetlen összetett utasításba, más néven blokkba foghatjuk össze. A '' után nincs pontosvesszô! Az if - else utasítás Az if - else utasítás alakja : if( kifejezés ) 1. utasítás(blokk) else 2. utasítás(blokk) Amennyiben a kifejezés igaz - azaz értéke nem nulla - akkor az 1. utasitás(blokk), ha a kifejezés hamis - azaz értéke nulla - akkor a 2. utasítás(blokk) kerül végrehajtásra. Az else használata nem kötelezô! Ha az if ill. else kulcsszót csak egy utasítás követi, akkor nem kötelezô a '' ill. '' jelek használata, egyébként igen! 6. sz. példaprogram (részlet) : if( a%2 == 0 ) a = a/2; else a = 3*a + 1; if( a>max ) max = a; Fontos : Mivel az else használata nem kötelezô, ezért elôfordulhat, hogy összetettebb alakokban nem egyezik meg az if-ek és az else - k szá- 15

4. Vezérlési szerkezetek ma. Annak eldöntésére, hogy melyik else melyik if - hez tartozik a következô szabály érvényes : Az else a hozzá legközelebb esô else nélküli if-hez tartozik! Ajánlatos a '' ill. a '' zárójelek alkalmazása, így egyértelmûvé tehetjük a szerkezetet! 7. sz. példaprogram (részlet) : if( n == 0 ) if( a>b ) x = a; else y = b; Az elsô if után azért nem kell '' ill. '' mert az azt követô if egy utasításnak felel meg. Jelen konstrukcióban az else ág az if( a>b ) - hez tartozik. Ha eredetileg nem ezt akartuk akkor a '' ill. '' használatával tudunk változtatni: 8. sz. példaprogram (részlet) : if( n == 0 ) if( a>b ) x = a; else y = b; A? operátor Az if - else kifejezés egy speciális rövidítése : az ilyen típusú alakot, mint az if( a>b ) z = a; else z = b; a '?' operátor használatával rövidíthetünk. Általános alak : 16

4.1 Szelekció kif1? kif2 : kif3 ; Ha kif1 értéke igaz akkor kif2, egyébként kif3 lesz ennek a kifejezésnek az értéke: z = (a>b)? a : b; /* z = max(a,b) */ Az else - if szerkezet - többszörös elágazás I. Általános alakja : if( kifejezés ) utasítás(blokk) else if( kifejezés ) utasítás(blokk) else if( kifejezés ) utasítás(blokk) else utasítás(blokk) Itt meg kell jegyezni, hogy gyakorlatilag nem külön utasításról van szó, hiszen egymásba ágyazott kétágú szelekciókkal van dolgunk. Mivel gyakran elôfordul ilyen döntési szerkezet, ezért az áttekinthetô programozási alak miatt külön tárgyaljuk. A kifejezések - egymás után történô - kiértékelése után az az utasítás kerül végrehajtásra, amelyhez tartozó kifejezés igaznak bizonyult. Ezután a program kilép az else-if szerkezetbôl. Az utasítások helyén egy utasítás vagy '' ill. '' között utasításblokk állhat. Az utolsó else a "fentiek közül egy sem" szituációt kezeli. A hozzá tartozó utasítás csak akkor kerül végrehajtásra, ha elôtte mindegyik kifejezés hamisnak bizonyult. 9. sz. példaprogram (részlet) : 17

4. Vezérlési szerkezetek k = (x-u)*(x-u) + (y-v)*(y-v); if( k == r*r ) printf("\nrajta van a körön!"); else if( k > r*r ) printf("\nkivül van a körön!"); else printf("\nbelül van a körön!"); A switch utasítás - többszörös elágazás II. Åltalános alakja : switch( kifejezés ) case konstans_1: utasítás(blokk) break; case konstans_2: utasítás(blokk) break;... case konstans_i: utasítás(blokk) break; default: utasítás(blokk) break; A kifejezés csak egész típusú lehet! Kiértékelése után azzal az utasítás- (blokk)-kal folytatódik a program amelyhez tartozó case konstans megegyezett a kifejezés értékével. A break hatására befejezôdik a switch végrehajtása. A default utáni utasítás(blokk) - ra akkor adódik a vezérlés, ha egyik case-re sem teljesült az egyenlôség. A case után csak a kifejezés típusának megfelelô állandót lehet megadni! A case utáni kifejezés típusa csak 18

egész jellegû lehet, tehát char, int vagy long. Egymás után több case-t is fel sorolhatunk. 10. sz. példaprogram (részlet) : switch(c) /* c - ben egy karakter értéke található */ case '2': case '4': case '6': case '8': printf("\npáros!"); break; case '1': case '3': case '5': case '7': case '9': case '0': default: printf("\npáratlan!"); break; printf("\nulla!"); break; if( c >= 'A' && c <= 'Z' ) printf("\nnagybetû!"); else if( c >= 'a' && c <= 'z' ) printf("\nkisbetû!"); else printf("\negyéb!"); break; Fontos : Ha egyszer beléptünk egy switch utasítás valamelyik case ágába, akkor az utasítások mindaddig végrehajtódnak amíg egy break utasításra nem jut a vezérlés! Két case-nek nem lehet ugyanaz az értéke! 4.2 Ciklusok 19

4. Vezérlési szerkezetek Elôltesztelô ciklus : A while utasítás. A while utasítás alakja : while( kifejezés ) utasítás(blokk) A program mindaddig végrehajtja az utasítás(blokk)-ot amíg a while-t követô kifejezés értéke IGAZ, azaz 0-tól különbözik. 11. sz. példaprogram : // Az 1-1/2 + 1/4-1/8... váltakozó elôjelü sor // összegének kiszámítása a billentyûzetrôl megadott // pontossággal. A sor a (-1) (n-1) *(1/2 (n-1) ) zárt // alakban írható fel és összege : 2/3. // Vezérlési szerkezet : a WHILE utasítás #include <stdio.h> #include <conio.h> #include <math.h> // Az fabs() és a pow() függvé- // nyek miatt szükséges void main() double n, e, s, os; printf("\nkérem a pontosságot : "); scanf("%lf",&e) ; s = 1 ; os = 0 ; n = 1 ; // Amíg az új és a régi összeg különbségének // abszolút értéke nagyobbb mint a hibahatár, // addig, folytatódjon a sorösszeg képzés. while( fabs( s - os ) > e ) os = s ; n += 1 ; s += pow( -1, n-1 ) * (1.0/pow(2,n-1)) ; 20

4.2 Ciklusok printf("\naz összeg : %lf",s); getch(); Hátultesztelô ciklus : A do - while utasítás A do - while utasítás alakja : do utasítás(blokk) while( kifejezés ); A program elôször végrehajtja az utasítás(blokk)-ot, majd kiértékeli a kifejezést. Ez a ciklikus tevékenység folyik mindaddig, amíg a kifejezés értéke IGAZ, azaz 0-tól különbözik. Mint látható, a C nyelv hátultesztelô ciklusa eltér a - több programnyelvnél - megszokott UNTIL típusú hátultesztelô ciklustól, amelynél a ciklus addig mûködik, amíg az UNTIL-t követô feltétel hamis. Amennyiben valaki az UNTIL alakot tartja "igazi" hátultesztelô ciklusnak, úgy a #define direktíva segítségével, bármikor elôállíthatja az UNTIL alakot, amint azt a 13. sz példaprogram mutatja. 12. sz. példaprogram : // A 11. sz. példaprogramban szereplô feladat megol- // dása a DO WHILE utasítás alkalmazásával. #include <stdio.h> #include <conio.h> #include <math.h> void main() double n, e, s, os; printf("\nkérem a pontosságot : ") ; scanf("%lf",&e) ; 21

4. Vezérlési szerkezetek s = 0 ; os = 0 ; n = 1 ; do os = s; s += pow( -1, n-1 ) * (1.0/pow(2,n-1)) ; n += 1 ; while( fabs( s - os ) > e ) ; printf("\naz összeg : %lf",s); getch(); 13. sz. példaprogram : // A 11. sz. példaprogramban szereplô feladat megol- // dása az általunk definiált UNTIL utasítás alkal // mazásával. #include <stdio.h> #include <conio.h> #include <math.h> #define UNTIL(condition) while(!(condition)) void main() double n, e, s, os; printf("\nkérem a pontosságot : ") ; scanf("%lf",&e) ; s = 0 ; os = 0 ; n = 1 ; do os = s; s += pow( -1, n-1 ) * (1.0/pow(2,n-1)) ; 22

4.2 Ciklusok n += 1 ; UNTIL( fabs( s - os ) <= e ) ; printf("\naz összeg : %lf",s); getch(); Taxatív ciklusszervezés : A for utasítás A for utasítás alakja : for( kifejezés1; kifejezés2; kifejezés3 ) utasítás(blokk) A kifejezések általában a következôket jelentik : kifejezés1 : Kezdeti értékadás a ciklusváltozónak. kifejezés2 : A lefutási feltétel(ek) megfogalmazása. Lefutási feltételként nem csak a ciklusváltozóval kapcsolatos feltételt lehet megadni, hanem bármilyen más feltételt is. kifejezés3 : A ciklusváltozó növelése vagy csökkentése. Bármelyik kifejezés hiányozhat! Példák : 1./ for( i=1; i<=100; i++) printf("\n A(z) %d négyzete = %d",i,i*i); // Kinyomtatja a természetes számok négyzetét 1-100 - ig. 2./ A for ciklusok egymásba ágyazhatóak : int i, j, prim, n;... for( i=5; i<=n; i=i+2 ) // Páratlan számok képzése 5-tôl n-ig prim = 1; for( j=3; j<=i-1 && prim == 1; j++) // Természetes számok képzése // 3-tól i-1 ig. if( i%j == 0 ) prim = 0; // Ha j osztója i-nek akkor i 23

4. Vezérlési szerkezetek // nem prímszám if( prim == 1 ) printf("\n%3d",i); A belsô for ciklus akkor is befejezôdik, ha a prim változó értéke 0 lesz így nem biztos, hogy lefut (i - 1) - ig. A külsô for ciklus i változójának egy értékéhez a belsô for ciklus a feltételében meghatározottak szerint kerül végrehajtásra. Ezután i értéke kettôvel növelôdik, és újra a belsô ciklus fut le. Ez így megy mindaddig, amíg i el nem éri n értékét. A for ciklus több ciklusváltozót is tartalmazhat, ezeket a ',' operátorral kell elválasztani egymástól. 14. sz. példaprogram (részlet) : for( i=1, j=2; i<=100; i+=2, j+=2) printf("\n Páratlan = %d < - > Páros = %d",i,j); Bizonyos esetekben nagyon kényelmes a használata! Fontos : Ez a konstrukció nem tévesztendô össze az egymásba ágyazott for ciklussal. Megjegyzés : A for utasítás egyenértékü a kifejezés1; while( kifejezés2 ) utasítás(blokk) kifejezés3; alakkal. Kilépés ciklusból ill. a switch-bôl : A break utasítás. A break hatására a vezérlés azonnal kilép a for, while, do-while ill. switch konstrukciókból, és a konstrukciót követô elsô utasítással folytatódik a program végrehajtása. Egymásba ágyazott szerkezetek esetén mindig abból a legbelsô ciklusból lép ki a break, amelyik azt tartalmazza. 24

4.3 A goto utasítás, címkék Következô iteráció kezdeményezése : A continue utasítás. A continue utasítás csak ciklusokban használható. A while ill. do-while ciklus belsejében az azonnali feltételvizsgálat végrehajtását eredményezi, for ciklus esetén pedig a ciklusváltozó módosítását. A switch utasításban hatástalan, ill. ha a switch egy ciklusban szerepel, akkor erre a ciklusra érvényesek a fent leírtak. Az utóbbi két utasítást nem használjuk gyakran! 4.3 A goto utasítás, címkék A goto utasítás használatától általában elzárkóznak a programozók. Elvileg a C-ben a goto-ra soha sincs szükség, és a gyakorlatban programozhatunk goto nélkül.mégis elôfordulhatnak olyan esetek, amikor a goto használata a legcélszerûbb. Ilyen például az a helyzet, amikor valamilyen hibakezelés során, egy kétszeresen - vagy többszörösen - egymásba ágyazott ciklus legbelsejébôl akarunk kilépni. Ilyenkor a break utasítást nem tudjuk használni. 15. sz. példaprogram (részlet ) : for(... )... for(... ) if( hiba) goto hiba_jav;... hiba_jav : hiba lekezelése Feladatok a 2. - 3. - 4. fejezetek anyagából 25

4. Vezérlési szerkezetek 1.) Olvassunk be két egész számot, és irassuk ki összegüket, különbségüket, szorzatukat, valamint az elsônek a másodikkal való egész osztásának hányadosát és maradékát! 2.) Olvassunk be két valós számot, és irassuk ki a négyzetösszegüket valamint mértani közepüket! 3.) Számítsuk ki egy henger felszínét és térfogatát, ha adott az alapkörének sugara és a magassága! 4.) Olvassunk be két valós számot, és álapítsuk meg, hogy elôjelük megegyezik-e, különbözik-e, esetleg valamelyik szám nulla! 5.) Olvassunk be egy egész számot, és döntsük el, hogy háromjegyû-e! 6.) Olvassuk be egy intervallum két végpontját és egy értéket. Döntsük el, hogy az érték az intevallumba esik, ill. attól jobbra vagy balra! 7.) Olvassunk be egy egyjegyû számot és irassuk ki szövegesen ( egy, kettô... )! 8.) Olvassunk be egy egész szögértéket (fokban), és irassuk ki a típusát! (hegyes, derék, tompa, egyenes, homorú, teljes ) 9.) Olvassuk be egy pont ( x,y ) koordinátáit, és irassuk ki, hogy hol helyezkedik el a pont! (Valamelyik síknegyedbe esik, vagy az origóra, vagy valamelyik tengelyre) 10.) Hány kockából építhetô fel egy n emeletes gúla, ha minden emelet négyzet alakú, és az oldalhossza kettôvel nagyobb a fölötte lévônél? A legfelsô ( n. ) emelet egy kockából áll. 11.) Hány emeletes gúla építhetô fel m db kockából? Irjuk ki, hogy mennyi kocka marad esetleg ki! 12.) Irjunk programot a következô - váltakozó elôjelü - sor összegének adott pontosságú kiszámítására. A pontosság mértékét a program a billentyûzetrôl olvassa be: 1-1/2 + 1/3-1/4 +... 26

5. Tömbök - I rész Eddig olyan esetekkel foglalkoztunk, ahol egy változónévhez egy értéket tudtunk hozzárendelni. ( Skalár változó ). A tömb azonos típusú, véges számú elemből épül fel. Olyan közvetlen elérésû adatstruktúra, amelynek egy elemét a tömb nevével és az utána következô index-szel tudjuk elérni - alapesetben. Milyen jellemzôi vannak egy tömbnek C-ben? A tömbnek öt jellemzôje van : Típus : - Tárolási osztály specifikátor ( Ld.: 57. oldal) - Típus - Név - Méret - Dimenzió Az eddig megismert változó típusok valamelyike lehet. Név : A tömb nevének megválasztásával kapcsolatban a 2.2 pontban leírtak érvényesek. Méret : A tömb definícíónál a tömb típusa után a nevét adjuk meg és utána az elemek számát - "[" ill. "]" között. C -ben a tömb indexelése szigorúan a 0 - dik elemtôl kezdôdik. Indexelésnek nevezzük azt a mûveletet, amikor a tömb neve után "[" és "]" között direkt módon - egy számmal - megadjuk, hogy az illetô tömb hányadik elemét kívánjuk elérni. Igy például, az : int elemek[10] ; módon definiált tömbnek 10 eleme van : elemek[0], elemek[1],..., elemek[9] ; de nincs 10-es indexü eleme. Példa az indexelésre : elemek[3] = 20; vagy : for(i=0; i<10; i++) elemek[i] = 0; Dimenzió : Az elôbb bemutatott egydimenziós tömbön kívül kétdimenziós tömböt is használhatunk. Az egydimenziós tömböt a matematikában megismert egy dimenziós vektorhoz hasonlíthatjuk, a kétdimenziós tömböt pedig a mátrixhoz.

- Ezekután az egydimenziós tömb definiálása úgy történik, hogy megadjuk a típusát, ezután - egy vagy több szóközt követôen - a nevét, majd szögletes zárójelek között, az elemek számát. A deklarálást követheti - kapcsos zárójelek között a tömb elemeinek felsorolása, vesszôvel elválasztva. Ezt nevezzük a tömb inicializálásának! Amennyiben a felsorolt elemek száma kevesebb a tömb méreténél, úgy a maradék elemek értéke nulla lesz! Példa : int vv[10] ; // Egy integer típusú, vv nevû, 10 elemû tömb. vagy : int zz[10] = 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 ; // Egy integer típusú, zz nevû, 10 elemû tömb, inicializálással. A példákban szereplô deklarációk egyben definíciók is, mert a tömbméretnek megfelelô memóriaterület lefoglalódik! 5.1 Egydimenziós tömbök 16. sz. példaprogram : /* ============ Legkisebb elem kiválasztása =========== */ #include <stdio.h> void main() //a egy 10 elemû,integer tömb,inicializálva. int a[10] = 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 ; int i, min; min = a[0]; for(i=0; i<10; i++) // Ha az aktuális minimum nagyobb a // tömbelemnél if( min > a[i] ) min = a[i] ;

printf("\na legkisebb elem = %2d",min); Egydimenziós tömbbe történô adatbeolvasás a scanf() függvény segítségével oldható meg, a következô módon : #include <stdio.h> void main() int beolv[10], i; for(i=0; i<10; i++) scanf("%d",&beolv[i]);... Az "&" jel ( cím operátor ) ugyanúgy szükséges a tömbelem elôtt, mint egyszerû változó esetén! ( Lásd késôbb részletesen! ) 5.2 Két dimenziós tömbök A kétdimenziós tömb definiálása a típust és a nevet tekintve megegyezik az egydimenziós tömb definiálásával. A különbség a méretek számában van. A név után azt kell megadni, hogy a tömbnek hány sora van, utána pedig azt, hogy hány oszlopa. A kétdimenziós tömb tehát egy olyan vektor, amely azonos típusú és azonos elemszámú vektorokból áll! Az indexelés itt is 0-tól kezdôdik! Példa : A double x[4][5]; egy olyan kétdimenziós tömböt jelent amelynek 4 sora van (0...3) és 5 oszlopa ( 0...4 ). Az x mátrix egy elemére kettôs indexeléssel hivatkozhatunk : x[2][3] = 5.67;. Az x mátrix 2-es indexü ( azaz 3-ik ) sora ill. 3-as indexü (azaz 4-ik) oszlopbeli eleme vegye fel az 5.67-es értéket. A mátrix tárolása a memóriában sorfolytonosan történik, azaz a 0. sor után az 1. sor következik stb. Az általunk hivatkozott x[2][3] tehát a memóriában a 2*5+3 = 13. elem. Az indexelés 0-tól indult! A kétdimenziós tömbök inicializálása is megoldható : a tömb elemeit - kapcsos zárójelek között - soronként kell feltüntetni, vesszôvel elválasztva : int mx[3][3] = 1, 2, 3, // Egy integer típusú, mx nevû mátrix, 4, 5, 6, // 3 sorral és 3 oszloppal, a megfelelô 7, 8, 9 // elemekkel inicializálva.

; 17. sz. példaprogram : /* ======== Két double típusú mátrix összege ======= */ #include <stdio.h> #include <conio.h> main() double a[3][3], b[3][3], c[3][3]; int i, j; for(i=0; i<3; i++) // Beolvasás az a mátrixba for(j=0; j<3; j++) printf("a[%d][%d] = ",i,j) ; scanf("%lf",&a[i][j]) ; printf("\n-------------------------------\n\n"); for(i=0; i<3; i++) // Beolvasás a b mátrixba for(j=0; j<3; j++) printf("b[%d][%d] = ",i,j) ; scanf("%lf",&b[i][j]) ; printf("\n-------------------------------\n\n"); for(i=0; i<3; i++) // A c = a + b képzése for(j=0; j<3; j++) c[i][j] = a[i][j] + b[i][j]; for(i=0; i<3; i++) // A c mátrix kiiratása for(j=0; j<3; j++) printf("%8.2lf%c", c[i][j],( ((j+1)%3 == 0) '\n' : ' ') ); getch();

Feladatok az 5. fejezet anyagából 1.) Töltsünk fel egy 10 elemû integer vektort! Ezután számítsuk ki a vektor elemek átlagát! 2.) Határozzuk meg ugyanennek a vektornak a legnagyobb elemét! 3.) Töltsünk fel két 10 elemû integer vektort! Ezután határozzuk meg a két vektor összeg ill. különbség vektorát! 4.) Számítsuk ki az elôbbi két vektor skalárszorzatát! 5.) Egy 20 fôs csoport zárthelyi eredményeit kell kiértékelni. A pontszámhatárok a következôk : 0-15 elégtelen 16-25 elégséges 26-35 közepes 36-45 jó 46-50 jeles Az egyes zh. pontszámokat egy vektorba kell beolvasni, ki kell iratni az egyes zh-k osztályzatát, és meg kell állapítani, hogy hány elégtelen, elégséges... volt a csoportban! 6.) Töltsünk fel egy 5x5-ös integer mátrixot! Ezután határozzuk meg mindegyik sorának legnagyobb ill. legkisebb elemét! 7.) Töltsünk fel egy 5x5-ös double mátrixot! ( Inicializálással is megoldható! ) Ezután határozzuk meg sor ill. oszlop összegeit. Az összegeket megfelelô méretü és típusú tömbökben tároljuk és irassuk is ki! 8.) Töltsünk fel két 5x5-ös double mátrixot! ( Inicializálással is megoldható! ) Ezután képezzük a. különbség mátrixot és irassuk ki! 9.) Olvassunk be egy nxn - es mátrixot! Készítsünk programot amely egy menü rendszerbôl történô választás alapján a következô értékeket számítja ki : 1. egy tetszôleges sor átlaga 2. egy tetszôleges oszlop átlaga 3. valamennyi sor átlaga 4. valamennyi oszlop átlaga 5. az összes elem átlaga

6.1 Karaktertömbök 6. Karaktertömbök és karaktermûveletek 6.1 Karaktertömbök A C nyelvben nincsenek hagyományos értelemben vett string (karakterlánc) típusú változók, mint például a BASIC-ban az A$. A C nyelvben a karakterláncok ábrázolása karaktertömbökkel történik úgy, hogy a tömbelemek a karakterlánc egy-egy karakterének felelnek meg és a karakterlánc végét a '\0' ( bináris nulla ) karakter jelzi. Ezért a tömb méretet mindig eggyel nagyobbra kell választani a karakterlánc tényleges hosszánál. Például, ha a "NOVEMBER" szót el akarjuk helyezni a c nevû karaktertömbben akkor a következôt kell tennünk : char c[9]; // A méretet [] zárójelek között adjuk meg. strcpy(c,"november"); Az STRCPY függvény az elsônek megadott változóba másolja a második paramétert amely lehet konstans vagy változó. Változó esetén a tömb nevét kell átadni, konstans esetén az " " jelek közé kell írni a szöveget! A string végét jelzô \0 is átmásolódik. Az strcpy() használatához a <string.h>-t be kell include-olni! Ezek után nézzük meg, hogy helyezkedik el a "NOVEMBER" a c tömbben. ASCII kódok -> 78 79 86 69 77 66 69 82 0 ( decimális értékek ) Karakter -> 'N' 'O' 'V' 'E' 'M' 'B' 'E' 'R' '\0' Tömb index -> 0 1 2 3 4 5 6 7 8 A C nyelvben minden tömb indexelése szigorúan 0-tól kezdôdik! A karakter vektor egyes elemeinek önállóan is lehet értéket adni : Például a : c[0] = 'D' ; c[1] = 'E' ; c[2] = 'C' ; hatására a c értéke "DECEMBER" lesz. Mivel itt egy karakteres értékadás történik, ezért az aposztrófokat ( ' ) használjuk. A karaktertömb neve nem más mint a karaktertömb kezdôcíme, azaz a 0-dik elemre mutató cím. Jelen esetben tehát a DECEMBER szó 'D' betûjére mutató cím. ( Lásd késôbb bôvebben! ). Fontos stringkezelô függvény még az strcat(), amely két string összefûzését végzi olymódon, hogy az elsônek megadott stringhez hozzáfûzi a másodikat. 1

6.2 Karakter mûveletek Példa :... strcpy(c1,"borland") ; strcpy(c2," C++") ; strcat(c1,c2) ;... hatására a c1-ben a "BORLAND C++" szöveg található. c1 méretének elegendôen nagynak kell lennie ahhoz, hogy c2-t befogadja, különben a memória - nem c1-hez tartozó része - felülíródik! c1 lezárása a '\0'-val történik és a <string.h> használata itt is kötelezô! Kétdimenziós karaktertömbök deklarálása a következôképpen történik : char cmx[5][10] ; Ezalatt egy olyan karaktertömböt ( mátrixot ) kell érteni, amelynek 5 sora van, ( indexelés : 0... 4 ), és soronként max. 9 értékes karaktert tartalmaz. (Gondoljunk a karakterlánc végét jelzô '\0' - ra! ) 6.2 Karakter mûveletek Egy karakter beolvasása puffereléssel : int getchar() tárolja. A getchar() függvény a leütött karaktert nem olvassa be mindjárt a megadott változóba, hanem egy átmeneti tároló területen ( billentyûzet puffer ) A karakter beolvasás addig tart, ameddig a puffer be nem telik ( kb. másfél képernyô sor ), vagy ameddig az <ENTER> billentyût le nem nyomjuk. A getchar mûködését a <CTRL> <Z> billentyûkkel tudjuk megszakítani. Ilyenkor a getchar() az EOF-ot (End Of File) adja vissza, aminek az értéke -1. Ez a magyarázata annak, hogy a getchar() miért int-et ad vissza és miért nem char-t. Egy karakter kiírása pufferbôl : int putchar( int ) A putchar() a getchar()-ral ellentétes mûveletet végez, a pufferbôl ír ki egy karaktert a képernyôre. Ha a puffer kiürült akkor az EOF-ot adja vissza. 2

6.2 Karakter mûveletek 18. sz. példaprogram : /* Példa a getchar() ill. putchar() függvények mûködésére */ #include <stdio.h> void main() int c; c = getchar(); while( c!= EOF ) putchar(c) ; printf("*"); c = getchar(); /**********************************************************/ // // Az elsô getchar() hívás a klaviatúra pufferbe ír. Addig // olvas a klaviatúráról amíg <ENTER>-t nem nyomunk. Ennek // hatására a puffer elsô pozícióján lévô karakter c-be ke- // rül, majd EOF vizsgálat következik. Ha c értéke nem EOF // akkor belépünk a while ciklusba. A karakter kiíródik a // display-ra, és az utána következô getchar() beolvassa a // puffer második pozícióján lévô karaktert c-be. Ezután me- // gint vizsgálat és egy karakter kiiratása következik. A // program CTRL+Z hatására fejezi be mûködését! // /**********************************************************/ Egy karakter beolvasása közvetlenül : int getch(), int getche() Mindkét függvény közvetlenül a baloldalon álló változóba olvassa be a leütött karaktert, az átmeneti tárolás mellôzésével. A különbség az, hogy a getch() alkalmazásánál a leütött karakter nem jelenik meg a képernyôn, a getche()-nél viszont megjelenik. Az EOF vizsgálat egyik függvény esetén 3

6.2 Karakter mûveletek sem oldható meg, mivel a <CTRL> <Z> -re nem adják vissza az EOF kódot. Használatukhoz a <conio.h> include-olása szükséges. Mûködésüket a következô példaprogram mutatja be egyszerû változók esetén: 19. sz. példaprogram : /* Karakterolvasó mûveletek egyszerû változók esetén. */ #include <stdio.h> #include <conio.h> void main() int c, gc, gce; // A getchar() a klaviatúra pufferbe olvas ; // <ENTER>-re áll le! printf("\nez egy GETCHAR() hívás : ") ; c = getchar(); printf("\n C = %d C = %c\n", c, c); // A getch() közvetlenül a klaviatúráról olvas // echózás nélkül! printf("\nez egy GETCH() hívás : ") ; gc = getch(); printf("\n GC = %d GC = %c\n",gc,gc); // A getche() közvetlenül a klaviaturáról olvas // echózással! printf("\nez egy GETCHE() hívás : ") ; gce=getche(); printf("\ngce = %d GCE = %c\n",gce,gce); Egy karakterlánc beolvasása puffereléssel : int scanf() 4

6.2 Karakter mûveletek A scanf() használatával több karaktert tudunk beolvasni pld. egy karaktertömbbe. Ehhez a "%s" formátumvezérlô karaktert kell használnunk, és változóként a karaktertömb nevét kell megadnunk. A beolvasás az <ENTER> vagy a szóköz megnyomásáig tart. 20. sz. példaprogram : /* === Karakterolvasó mûveletek tömbök esetén. === */ #include <stdio.h> #include <conio.h> void main() char c[11], gc[11], gce[11], sc[11]; int igce[11], i; c[10]='\0'; gc[10]='\0'; gce[10]='\0'; sc[10]='\0'; igce[10]='\0' ; // Elôször a pufferba olvas utána az elsô // 10 karaktert a tömbbe! printf("\nez egy GETCHAR() hívás : "); for(i=0; i<10 ; i++) c[i] = getchar() ; printf("\n C = %s\n",c); // Közvetlenül a tömbbe olvas, i=10 - re leáll; a // karakter nem látszik! printf("\nez egy GETCH()hívás : ") ; for(i=0; i<10; i++) gc[i] = getch() ; printf("\n GC = %s\n",gc); // Közvetlenül a tömbbe olvas, i=10 - re leáll; a // karakter látszik! printf("\nez egy GETCHE() hívás : ") ; for(i=0; i<10; i++) gce[i] = getche() ; printf("\ngce = %s\n",gce); // Közvetlenül az (int) tömbbe olvas, i=10-re // leáll ; a karakter látszik! printf("\nez egy GETCHE() hívás integer tömbre : "); for(i=0; i<10; i++) igce[i] = getche() ; 5

6.3. Stringkonverziós mûveletek : int sprintf(), int sscanf() printf("\nigce = "); for(i=0; i<10; i++) printf("%c",igce[i]); printf("\n"); // Pufferbôl olvas <ENTER>-ig! Ha a program ele- // jén a getchar() hívásakor több mint 10 karaktert // ütöttünk be, akkor a maradékot a scanf() // automatikusan beolvassa! printf("\nez egy SCANF() hívás : ") ; scanf("%s",sc) ; printf("\n SC = %s\n",sc); Megjegyzés : Amennyiben mindenképpen a scanf() függvénnyel akarunk egy karaktert beolvasni, úgy a karakter beolvasása után ki kell "söpörni" a klaviatúra buffert az fflush() függvény segítségével : printf("\nkérek egy karaktert : ") ; scanf("%c",&a) ; fflush(stdin) ; printf("\nkérek egy karaktert : ") ; scanf("%c",&b) ; fflush(stdin) ; Az fflush() függvény argumentumában szereplô stdin a standard input ( azaz a klaviatúra buffer ) rövidítése. 6.3. Stringkonverziós mûveletek : int sprintf(), int sscanf() Numerikus értékek stringgé alakítása : int sprintf() A sprintf() függvény általános alakja : sprintf(puffer,formátum,változólista); A változólistában megadott numerikus értékeket, a formátum szerint a pufferben tárolja stringként. Példa: Numerikus alakban megadott dátum átalakítása stringgé. char datum[11]; int ev,ho,nap; 6