A kiválasztott változat és az aktuális verzió közötti különbségek a következők.
Előző változat mindkét oldalon Előző változat | Előző változat Következő változat Következő változat mindkét oldalon | ||
oktatas:programozas:c:c_nyelv [2015/02/06 10:44] |
oktatas:programozas:c:c_nyelv [2020/04/14 19:28] admin [Nevesített állandó] |
||
---|---|---|---|
Sor 1: | Sor 1: | ||
+ | [[oktatas:programozás:C|< C]] | ||
+ | |||
+ | |||
+ | ====== C programozási nyelv ====== | ||
+ | |||
+ | * **Szerző:** Sallai András | ||
+ | * Copyright (c) Sallai András, 2011, 2013, 2014, 2015, 2020 | ||
+ | * Licenc: GNU Free Documentation License 1.3 | ||
+ | * Web: http://szit.hu | ||
+ | |||
+ | ===== Bevezetés ===== | ||
+ | A C nyelv egy általános célú programozási nyelv. Rendszerprogramozási nyelvként is emlegetik, | ||
+ | mivel hatékonyan használható operációs rendszerek írására. Természetesen használható más | ||
+ | alkalmazói programok írására is. A nyelvet a BCPL és B nyelvből eredeztetik: | ||
+ | |||
+ | | BCPL | -> | B | -> | C | | ||
+ | |||
+ | |||
+ | A C nyelvet **Dennis Ritchie** az 1970-es évek elején fejlesztette ki **Ken Thompson** segítségével. A | ||
+ | nyelvet UNIX operációs rendszerre tervezte, amely egy DEC PDF-7 rendszeren futott. Volt egy B nevű | ||
+ | nyelv, amely nem lett ismert. A C sok tekintetben örökölte a B nyelv tulajdonságait, azért is lett | ||
+ | a neve az ábécé következő betűje. Az 1970es években a személyi számítógépeken BASIC nyelvet lassan | ||
+ | felváltja a C nyelv. 1978-ban **Dennis Ritchie** és **Brian Kerninghan** nevével fémjelzett | ||
+ | „//**A C programozási nyelv**//” című könyv első kiadása megjelenik. 1983 -- 1989 az Amerikai | ||
+ | Nemzeti Szabványügyi Hivatal (angolul: American National Standards Institute, röviden ANSI) | ||
+ | szabványnak fogadják el. 1990-ben megjelenik a szabványnak egy átdolgozott kiadása C99 névvel. | ||
+ | |||
+ | {{:oktatas:programozás:c:c_nyelvek_halmaza.png|}} | ||
+ | |||
+ | Az ANSI C az eredeti K&R nyelvnek egy kibővített változata. A megvalósítások | ||
+ | ehhez még plusz kiterjesztéseket tesznek hozzá. | ||
+ | |||
+ | ===== Helló Világ ===== | ||
+ | |||
+ | <code c> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | int main() { | ||
+ | printf("Helló Világ\n"); | ||
+ | } | ||
+ | |||
+ | </code> | ||
+ | |||
+ | A C nyelv több előre megírt függvénnyel rendelkezik, amit csak meg kell hívni. Ezen előre megírt | ||
+ | függvénygyűjteményeket hívjuk sztenderd könyvtáraknak. A sztenderd könyvtárak is több csoportja | ||
+ | ismert, amelyeket elneveztünk a rájuk jellemző névvel. Ilyenek a stdio, stdlib, math, stb. | ||
+ | |||
+ | A fenti program első sora amely #include-al kezdődik egy szabványos könyvtár használatát | ||
+ | teszi lehetővé, amelynek neve stdio. Az stdio programozói könyvtárnevet kötelező kisebb mint és | ||
+ | nagyobb mint karakterek közé tenni: | ||
+ | #include <stdio.h> | ||
+ | |||
+ | A programban szereplő printf() utasítás a stdio.h programozói könyvtárban található. | ||
+ | Ha használni akarjuk a printf() függvényt, mindig szükség van a #include <stdio.h> sorra. | ||
+ | |||
+ | A C nyelvben, minden utasítást függvényekbe rendezünk. Egy C programban mindig lenni kell egy | ||
+ | main nevű függvénynek, a programnak ugyanis ez lesz a belépési pontja. A függvények neve után | ||
+ | egy nyitó és egy bezáró zárójelet teszünk. Ezzel is jelezzük, hogy a main valójában függvény: | ||
+ | main() | ||
+ | A main() tehát egy függvény fejrésze, amely egy névből (esetünkben a "main") és az azt követő | ||
+ | zárójelekből áll. | ||
+ | |||
+ | Egy függvénynek mindig van törzs része is. A függvény törzsét kapcsos zárójelek írjuk. | ||
+ | A függvény törzsében írjuk le mit történjen a programban. A mi programunkban egyeteln | ||
+ | utasítás van: | ||
+ | printf("Helló Világ\n"); | ||
+ | |||
+ | A printf() függvény, illetve utasítás a képernyőre írja a paraméterként megkapott értékeket. | ||
+ | Esetünkben ez a "Helló Világ" szöveg. A szöveg végén a "\n" gondoskodik a sortörésről. | ||
+ | |||
+ | {{:oktatas:programozas:c:c_fuggveny_reszei.png?400|}} | ||
+ | |||
+ | |||
+ | ===== Kivitel ===== | ||
+ | |||
+ | Ha leírok egy karaktersorozatot, például alma, a printf() függvény a képernyőre írja: | ||
+ | <code c Program01.c> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | int main() { | ||
+ | printf("alma"); | ||
+ | } | ||
+ | |||
+ | </code> | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | <code c Program01.c> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | int main() { | ||
+ | puts("alma"); | ||
+ | } | ||
+ | |||
+ | </code> | ||
+ | |||
+ | |||
+ | A karaktersorozat persze lehet számok vagy akár más karakterek sorozata is: | ||
+ | printf("35"); | ||
+ | |||
+ | |||
+ | A számokat csak a formátumuk meghatározásával lehet kiíratni. | ||
+ | <code c> | ||
+ | printf("%d", 35); | ||
+ | </code> | ||
+ | |||
+ | Előbb írok egy formázó szöveget, majd jöhet a szám. | ||
+ | Egész számok esetén a formázó szöveg: "%d". | ||
+ | |||
+ | |||
+ | A printf() kiíratandó paramétere, lehet akár egy kifejezés is: | ||
+ | printf("%d", 35*2); | ||
+ | A kifejezés kiértékelődik, és az eredményt kapjuk vissza. | ||
+ | |||
+ | |||
+ | ===== Escape szekvenciák ===== | ||
+ | |||
+ | Fentebb láttuk, ha egy karaktersorozatot a képernyőre iratok, annak minden karaktere | ||
+ | változtatás nélkül megjelenik a képernyőn. Egyes karaktereknek azonban lehet speciális | ||
+ | jelentése is. | ||
+ | |||
+ | Fentebb már láttuk, ha az "n" betű elé egy visszaperjelet (\) írunk, akkor annak különleges | ||
+ | jelentése lesz. Ahelyett, hogy magát a karaktert kapnánk a képernyőn egy sortörést | ||
+ | küld a képernyőre. | ||
+ | |||
+ | Ehhez hasonló, például a <nowiki>"\t"</nowiki>, amely egy tabulátorjelet küld a képernyőre. | ||
+ | |||
+ | Az ilyen karaktereket hívjuk Escape szekvenciáknak. | ||
+ | |||
+ | Mivel az idézőjelnek <nowiki>(")</nowiki> is speciális jelentése van, ezért azt is csak | ||
+ | escape szekvenciaként tudjuk megjeleníteni: | ||
+ | \" | ||
+ | |||
+ | A következő táblázat az escape szekvenciák listáját tartalmazza: | ||
+ | |||
+ | ^ Escape szekvencia ^ Leírás ^ | ||
+ | | \n | Sortörés | | ||
+ | | \t | Tabulátor | | ||
+ | | <nowiki>\"</nowiki> | Idézőjel | | ||
+ | |||
+ | |||
+ | ===== Változók és adattípusok ===== | ||
+ | A C nyelvbe változókat hozhatunk létre, értékek tárolására. | ||
+ | A változó deklarálása során meg kell adni milyen típus fogunk benne tárlni, | ||
+ | majd megadom a változó nevét. Például egy egész típusú változót szeretnék | ||
+ | tárolni, egy szam nevű változóban, akkor: | ||
+ | int szam = 25; | ||
+ | |||
+ | Ebben a példában rögtön definiáltam a szam nevű változó értékét. | ||
+ | |||
+ | |||
+ | A típusok előtt különféle módosítókat adhatunk meg. Ilyen módosító a signed vagy az unsigned. | ||
+ | Magyarul előjeles vagy előjel nélküli. A típusok alapértelmezetten előjelesek. Ha nem szeretnék | ||
+ | negatív számokat használni, akkor használhatom az unsigned módosítót, így a pozitív számokból | ||
+ | nagyobb intervallummal dolgozhatok. | ||
+ | |||
+ | |||
+ | Példaként, adjuk meg az int számára unsigned módosítót. Ez azt jelenti, | ||
+ | hogy csak előjel nélküli, pozitív számokat adhatunk meg. | ||
+ | unsigned int szam = 25; | ||
+ | |||
+ | Egy int típusban, a géptől függően 2 vagy 4 bájt nagyságú számot tárolhatunk. | ||
+ | Az int számra megadhatunk egy short módosítót. Ekkor maximum 32767 a legnagyobb | ||
+ | megadható szám. A legkisebb -32768. | ||
+ | short int szam = 25; | ||
+ | |||
+ | A legnagyobb megadható szám tárolása: | ||
+ | short int szam = 32767; | ||
+ | |||
+ | |||
+ | Használhatjuk egyszerre a unsigned és a short módosítót is. Ekkor a legkisebb tárolható szám 0, | ||
+ | a legnagyobb, 65535. Például: | ||
+ | |||
+ | unsigned short int szam = 63000; | ||
+ | |||
+ | |||
+ | {{:oktatas:programozas:c:tipusokmodositok.png?400|}} | ||
+ | |||
+ | |||
+ | A következő táblázat tovább módosítókat tartalmaz, és méreteket tartalmaz. | ||
+ | |||
+ | |||
+ | ^ Típus ^ Bájt ^ Minimális érték ^ Maximális érték ^ | ||
+ | | char, signed char | 1 | -128 | 127 | | ||
+ | | unsigned char | 1 | 0 | 255 | | ||
+ | | short, short int, \\ signed short int | 2 | -32768 | +32767 | | ||
+ | | unsigned short, \\ unsigned short int | 2 | 0 | 65535 | | ||
+ | | int, signed int | 2 vagy 4 | short vagy long | short vagy long | | ||
+ | | unsigned \\ unsigned int | ugyanígy, de \\ unsigned | ugyanígy, de \\ unsigned | | ||
+ | | long, long int, \\ signed long int | 4 | -2147483648 | +2147483647 | | ||
+ | | unsigned long, \\ unsigned long int | 4 | 0 | 4294967295 | | ||
+ | | char, \\ unsigned char | 1 | 0 | 255 | | ||
+ | | signed char | 1 | -128 | 127 | | ||
+ | |||
+ | |||
+ | A szabványos limits.h fejállományban megtalálhatók a maximum és minimum értékek. | ||
+ | |||
+ | | CHAR_MIN | | ||
+ | | CHAR_MAX | | ||
+ | | UCHAR_MAX | | ||
+ | | SHRT_MIN | | ||
+ | | SHRT_MAX | | ||
+ | | USHRT_MAX | | ||
+ | | INT_MAX | | ||
+ | | INT_MIN | | ||
+ | | UINT_MAX | | ||
+ | | LONG_MAX | | ||
+ | | LONG_MIN | | ||
+ | | ULONG_MAX | | ||
+ | |||
+ | |||
+ | Ha szeretnénk kiíratni a legnagyobb tárolható int típust, írjuk meg a következő programot: | ||
+ | <code c nagyegesz.c> | ||
+ | #include <stdio.h> | ||
+ | #include <limits.h> | ||
+ | |||
+ | int main() { | ||
+ | printf("%d\n", INT_MAX); | ||
+ | } | ||
+ | |||
+ | </code> | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ===== Állandók vagy konstansok ===== | ||
+ | |||
+ | Az állandó olyan érték, amelyet a továbbiak során nem akarunk megváltoztatni. A program futási ideje alatt ezek az állandók nem változtathatók. Kétfajta állandót használunk: literális és nevesített. | ||
+ | |||
+ | {{:oktatas:programozas:c:allandok.png?400|}} | ||
+ | ==== Literális állandó ==== | ||
+ | |||
+ | |||
+ | Lehet szám, karakter, karaktersorozat, stb. | ||
+ | |||
+ | === Számállandó === | ||
+ | |||
+ | |||
+ | 1234 formában leírt szám egész szám. Ha long típusú állandót akarok leírni akkor utána kell tennem | ||
+ | egy kis l vagy L betűt: 123456789L | ||
+ | |||
+ | === Karakteres állandó === | ||
+ | |||
+ | |||
+ | Egy vagy több aposztrófok (') közzé írt karakter. | ||
+ | Pl.: 'a' vagy 'b' | ||
+ | Karakterként nem szerepelhet a ' vagy az újsor. Ezért ezek helyettesítésére ún. escapesorozatokat | ||
+ | (escape szekvencia) használunk: | ||
+ | új sor NL \n | ||
+ | vízszintes tabulátor HT \t | ||
+ | függőleges tabulátor VT \v | ||
+ | visszalépés (backspace) BS \b | ||
+ | kocsivissza CR \r | ||
+ | lapemelés (formfeed) FF \f | ||
+ | hangjelzés (bell) BEL \a | ||
+ | backslash \ \\ | ||
+ | kérdőjel ? \? | ||
+ | aposztróf ' \' | ||
+ | idézőjel " \" | ||
+ | oktális szám ooo \ooo | ||
+ | hexadecimális szám hh \xhh | ||
+ | |||
+ | === Szöveges állandó === | ||
+ | |||
+ | |||
+ | Szokásos elnevezése: „karaktersorozat”. A szöveget úgy adjuk meg, hogy maga a program azon | ||
+ | változtatni nem tud a végrehajtás során, vagyis állandó. A C nyelvben a szöveges állandót | ||
+ | idézőjelek között adjuk meg. Pl.: | ||
+ | |||
+ | "Alma a fa alatt" | ||
+ | Vegyük észre! A magyar nyelvtől eltérően a C nyelvben a nyitóidézőjel felül van. | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ==== Nevesített állandó ==== | ||
+ | |||
+ | === #define === | ||
+ | |||
+ | Az állandó számára egy azonosító nevet adunk meg. Egy szövegkonstans pl. a „Nagy Péter”. Ennek | ||
+ | a konstansnak nevet is adhatunk, pl.: TELJESNEV. Innentől kezdve a TELJESNEVet bárhova írom | ||
+ | oda behelyettesítődik a „Nagy Péter”. C nyelvben ez a következő módon adható meg: | ||
+ | #define TELJESNEV ”Nagy Peter” | ||
+ | A C nyelvben lehetőség van még egy módon állandó megadására a const módosítóval. Pl.: | ||
+ | const int a; | ||
+ | Azt vállaljuk,hogy a változó tartalmát sosem változtatjuk meg. | ||
+ | |||
+ | Általánosan: | ||
+ | <code c> | ||
+ | #define azonosító helyettesítő–szöveg | ||
+ | </code> | ||
+ | |||
+ | Egy konkrét példa: | ||
+ | <code c> | ||
+ | #define MAX 5 | ||
+ | #define FELSOHATAR 100 | ||
+ | #define ALSOHATAR 50 | ||
+ | </code> | ||
+ | |||
+ | === const === | ||
+ | Egy nem módosítható objektumot deklarál. Az azonosítót nem használhatjuk | ||
+ | egy egyenlőségjel baloldalán. | ||
+ | |||
+ | <code c> | ||
+ | const int a = 5; | ||
+ | </code> | ||
+ | |||
+ | |||
+ | <code c konst.c> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | main() | ||
+ | { | ||
+ | const int a = 5; | ||
+ | printf("%d\n", a); | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | |||
+ | |||
+ | <code c konst2.c> | ||
+ | #include <stdio.h> | ||
+ | #define MERET 3 | ||
+ | typedef double Ttomb[MERET]; | ||
+ | main() | ||
+ | { | ||
+ | Ttomb tomb = {3.7, 5.2, 2.8}; | ||
+ | printf("%f\n", tomb[0]); | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | Láthattuk, hogy nevesített állandót két módon hozhatok létre. | ||
+ | A define előfordítói utasítással, és a const módosítóval. | ||
+ | |||
+ | {{:oktatas:programozas:c:nevesitett_literalis_allando.png?300|}} | ||
+ | |||
+ | A const egy módosító. A módosító után áll az állandó típusa. | ||
+ | A típus lehet char*, ezzel szöveges állandó adható meg. | ||
+ | |||
+ | {{:oktatas:programozas:c:szoveges_allando.png?400|}} | ||
+ | |||
+ | ===== Deklarációk ===== | ||
+ | |||
+ | |||
+ | A felhasználása előtt minden változót deklarálni kell, bár bizonyos deklarációk a programkörnyezet | ||
+ | alapján is létrejöhetnek. A deklaráció egy típust határoz meg, és utána egy vagy több adott típusú | ||
+ | változó felsorolása (listája) áll. | ||
+ | |||
+ | <code c> | ||
+ | int also, felso, lepes; | ||
+ | char c, sor[1000]; | ||
+ | </code> | ||
+ | |||
+ | A változók a deklarációk közt tetszőleges módon szétoszthatók, pl. a bal oldali deklarációs listákkal teljesen egyenértékű az | ||
+ | |||
+ | |||
+ | <code c> | ||
+ | int also; | ||
+ | int felso; | ||
+ | int lepes; | ||
+ | char c; | ||
+ | char sor[1000]; | ||
+ | </code> | ||
+ | |||
+ | A változók a deklaráció során kezdeti értéket is kaphatnak: | ||
+ | <code c> | ||
+ | int i = 0; | ||
+ | char esc = '\\'; | ||
+ | int hatar = MAXSOR+1; | ||
+ | float eps = 1.0e-5 | ||
+ | </code> | ||
+ | Bármely változó deklarációjában alkalmazható a const minősítő. Pl.: | ||
+ | <code c> | ||
+ | const double e = 2.71828182845905; | ||
+ | const char uzenet [ ] = ”figyelem:”; | ||
+ | int strlen(const char[ ]); | ||
+ | </code> | ||
+ | ===== Ellenőrző kérdések ===== | ||
+ | |||
+ | * Milyen nyelvet tanulunk most? | ||
+ | * Ki találta ki ezt a nyelvet amit tanulunk? | ||
+ | * Mikor let a nyelv kifejlesztve? | ||
+ | * Mire használjuk? | ||
+ | * Van-e szabványosított verziója? | ||
+ | * Mi az az előfordítás? | ||
+ | * Mivel kezdjük az előfordítói utasításokat? | ||
+ | * Mi az a konstans? | ||
+ | * Hogyan hozunk létre C nyelvben konstanst? | ||
+ | * Milyen az írásmódja a változóknak és a konstansoknak? | ||
+ | * A C nyelv kis és nagybetű érzékeny? | ||
+ | * A C nyelv kiírató utasítása? | ||
+ | * Hol nem szükséges a C nyelvben az utasítás végére (;) pontosvessző? | ||
+ | |||
+ | |||
+ | ===== Operátorok ===== | ||
+ | |||
+ | Kétfajta operátort különböztetünk meg: | ||
+ | |||
+ | * egy operandusú | ||
+ | * két operandusú | ||
+ | |||
+ | Egy operandus esetén az operátor lehet prefix és postfix: | ||
+ | operátor operandus | ||
+ | operandus operátor | ||
+ | |||
+ | Két operandusú operátor esetén: | ||
+ | operandus1 operátor operandus2 | ||
+ | |||
+ | | ||
+ | |||
+ | |||
+ | ==== Aritmetikai műveletek ==== | ||
+ | |||
+ | + összeadás | ||
+ | - kivonás | ||
+ | * szorzás | ||
+ | / osztás | ||
+ | % maradék képzés | ||
+ | | ||
+ | Példák: | ||
+ | <code c> | ||
+ | int c = 3 + 5; | ||
+ | </code> | ||
+ | | ||
+ | |||
+ | <code c> | ||
+ | int a = 3; | ||
+ | int b = 5; | ||
+ | int osszeg = a + b; | ||
+ | </code> | ||
+ | |||
+ | Maradékképzés: | ||
+ | <code c> | ||
+ | int maradek = 9 % 2; | ||
+ | </code> | ||
+ | |||
+ | A maradékot a "maradek" nevű változóban tároljuk. | ||
+ | |||
+ | |||
+ | |||
+ | ==== Relációs műveletek ==== | ||
+ | > | ||
+ | < | ||
+ | >= | ||
+ | <= | ||
+ | == Egyenlő | ||
+ | != Nem egyenlő | ||
+ | Az eredményük vagy 0 (hamis) vagy 1 (igaz) | ||
+ | |||
+ | |||
+ | <code c main.c> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | main() | ||
+ | { | ||
+ | int a = 3; | ||
+ | int b = 5; | ||
+ | int e = a < b; | ||
+ | printf("%d\n", e); | ||
+ | } | ||
+ | |||
+ | </code> | ||
+ | |||
+ | ==== Logikai műveletek ==== | ||
+ | |||
+ | && ÉS | ||
+ | || VAGY | ||
+ | ! NEM | ||
+ | |||
+ | Kiértékelés balról jobbra. Ha a kifejezés értéke meghatározható, akkor a kiértékelés leáll. | ||
+ | |||
+ | Például: | ||
+ | (a < 10) && (b > 5) | ||
+ | |||
+ | |||
+ | ==== Értékadás másként ==== | ||
+ | |||
+ | <code c> | ||
+ | a = a + 1 -> a += 1 | ||
+ | a = a - 1 -> a -= 1 | ||
+ | a = a * 1 -> a *= 1 | ||
+ | a = a / 1 -> a /= 1 | ||
+ | </code> | ||
+ | |||
+ | <code c> | ||
+ | a = a * (b + 1) -> a *= b + 1 | ||
+ | </code> | ||
+ | |||
+ | ==== Növelő és csökkentő operátorok ==== | ||
+ | |||
+ | ++ | ||
+ | -- | ||
+ | |||
+ | Az operátorok lehetnek prefix vagy postfix. | ||
+ | a++ -> a = a + 1; | ||
+ | ++a -> a = a + 1; | ||
+ | |||
+ | Ha postfixként használjuk: | ||
+ | a = 15; | ||
+ | b = a++; // -> b = a; a = a + 1; | ||
+ | |||
+ | Ha prefixként használjuk: | ||
+ | a = 15; | ||
+ | b = ++a; // -> a = a + 1; a = b; | ||
+ | |||
+ | ==== Bitenkénti logikai operátorok ==== | ||
+ | |||
+ | |||
+ | | & | bitenkénti ÉS | | ||
+ | | <nowiki>|</nowiki> | bitenkénti VAGY | | ||
+ | | <nowiki>^</nowiki> | bitenkénti kizáró vagy | | ||
+ | | <nowiki><<</nowiki> | bitléptetés balra | | ||
+ | | <nowiki>>></nowiki> | bitléptetés jobbra | | ||
+ | | ~ | egyeskomplemens | | ||
+ | |||
+ | Csak egész számokra alkalmazhatók | ||
+ | |||
+ | === Példa a bitenkénti balra léptetésre === | ||
+ | |||
+ | | 000011 | nem számít mennyit jelent | | ||
+ | | 000010 | 3-at jelent, ennyivel léptetünk | | ||
+ | | 001100 | eredmény | | ||
+ | |||
+ | |||
+ | === Komplemens képzés === | ||
+ | |||
+ | | a = 6 | 0000 0110 | | ||
+ | | ~a | 1111 1001 | 249 | | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ==== Precedencia ==== | ||
+ | |||
+ | | () | zárójel | | ||
+ | | ! ++ -- - | negálás, növelés, csökkentés, előjel | | ||
+ | | * / % | szorzás, osztás, maradékképzés | | ||
+ | | + - | összeadás, kivonás | | ||
+ | | << >> | bitenkénti eltolás balra és jobbra | | ||
+ | | <nowiki>< <= >= ></nowiki> | kisebb mint, kisebb vagy egyenlő, nagyobb vagy egyenlő, nagyobb mint | | ||
+ | | == =! | egyenlő, nem egyenlő | | ||
+ | | & | bitenkénti megengedő (inkluzív) és | | ||
+ | | <nowiki>^</nowiki> | kizáró (exkluzív) vagy | | ||
+ | | <nowiki>|</nowiki> | bitenkénti vagy | | ||
+ | | && | és | | ||
+ | | <nowiki>||</nowiki> | vagy | | ||
+ | |||
+ | Ha a egy művelet azonos szinten van, akkor az operátorok balról jobbra lesznek kiértékelve. | ||
+ | |||
+ | Példa a balról jobbra kiértékelésre: | ||
+ | <code c> | ||
+ | 12/2*3 = 18 | ||
+ | </code> | ||
+ | |||
+ | A zárójel mindig módosítja a kiértékelés sorrendjét. | ||
+ | |||
+ | ===== Formátumozott kivitel ===== | ||
+ | |||
+ | A printf() függvény formátumozott kivitelt tesz lehetővé számunkra. | ||
+ | A formátum kétféle karaktert tartalmazhat: amely kiíródik | ||
+ | változás nélkül a kimenetre, és amely a soron következő argumentum | ||
+ | konverzióját írja elő. Minden konverziós szakasz a % jellel kezdődik. | ||
+ | |||
+ | |||
+ | A % jel és a konverziós karakter között a sorrendben a következők lehetnek: | ||
+ | * mínusz jel, ami konvertált argumentumot balra igazítja | ||
+ | * egy szám, ami megadja a minimális mezőszélességet | ||
+ | * egy pont, ami elválasztja a mezőszélességet a pontosságot megadó számtól | ||
+ | * egy szám (pontosság) | ||
+ | * karaktersorozatnál a kiírandó karakterek maximális számát | ||
+ | * lebegőpontos számok esetén a tizedespont után kiírt számjegyek számát | ||
+ | * egész karakterek esetén a kiírt számjegyek maximális számát | ||
+ | * egy h betű, ha egy egész számot short típusként vagy egy l betű, ha long típusként írun ki | ||
+ | |||
+ | |||
+ | Kiíratás 2 tizedesjegy pontossággal: | ||
+ | <code c main.c> | ||
+ | #include <stdio.h> | ||
+ | main() | ||
+ | { | ||
+ | double a = 31.123456; | ||
+ | printf("%.2f\n", a); | ||
+ | |||
+ | } | ||
+ | |||
+ | </code> | ||
+ | |||
+ | Kiíratás 20 szélesen: | ||
+ | <code c main.c> | ||
+ | #include <stdio.h> | ||
+ | main() | ||
+ | { | ||
+ | double a = 31.123456; | ||
+ | printf("%20.2f\n", a); | ||
+ | |||
+ | } | ||
+ | |||
+ | </code> | ||
+ | |||
+ | Balra igazítás: | ||
+ | <code c main.c> | ||
+ | #include <stdio.h> | ||
+ | main() | ||
+ | { | ||
+ | double a = 31.123456; | ||
+ | printf("|%-20.2f|\n", a); | ||
+ | |||
+ | } | ||
+ | |||
+ | </code> | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ^ formátum karakter ^ típus ^ | ||
+ | | ld | long | | ||
+ | | d | int, short, char | | ||
+ | | f | float | | ||
+ | | c | char, int | | ||
+ | | Lg | long double | | ||
+ | |||
+ | ===== Matematikai függvények ===== | ||
+ | |||
+ | A matematikai függvények a math.h nevű fejállományban vannak. | ||
+ | |||
+ | |||
+ | |||
+ | ==== Állandók ==== | ||
+ | PI értéke | ||
+ | |||
+ | M_PI 3.14159265358979323846 | ||
+ | |||
+ | |||
+ | <code c main.c> | ||
+ | #include <stdio.h> | ||
+ | #include <math.h> | ||
+ | main() | ||
+ | { | ||
+ | printf("%f\n", M_PI); | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ==== Szinusz ==== | ||
+ | |||
+ | <code c main.c> | ||
+ | #include <stdio.h> | ||
+ | #include <math.h> | ||
+ | main() | ||
+ | { | ||
+ | printf("%f\n", sin(1 * M_PI / 180)); | ||
+ | |||
+ | } | ||
+ | |||
+ | </code> | ||
+ | |||
+ | ==== Függvények ==== | ||
+ | |||
+ | double sin (double); | ||
+ | double cos (double); | ||
+ | double tan (double); | ||
+ | double sinh (double); | ||
+ | double cosh (double); | ||
+ | double tanh (double); | ||
+ | double asin (double); | ||
+ | double acos (double); | ||
+ | double atan (double); | ||
+ | double atan2 (double, double); | ||
+ | double exp (double); | ||
+ | double log (double); | ||
+ | double log10 (double); | ||
+ | double pow (double, double); | ||
+ | double sqrt (double); | ||
+ | double ceil (double); // Felfele kerekít | ||
+ | double floor (double); // Felfele kerekít | ||
+ | double fabs (double); // Abszolút érték | ||
+ | double ldexp (double, int); | ||
+ | double frexp (double, int*); | ||
+ | double modf (double, double*); | ||
+ | double fmod (double, double); | ||
+ | |||
+ | int abs(int) //Abszolút érték | ||
+ | |||
+ | <code c main.c> | ||
+ | #include <stdio.h> | ||
+ | #include <math.h> | ||
+ | main() | ||
+ | { | ||
+ | printf("%f\n", sqrt(9.5)); | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | |||
+ | <code c trig.c> | ||
+ | #include <stdio.h> | ||
+ | #include <math.h> | ||
+ | main() | ||
+ | { | ||
+ | printf("%f\n", pow(2,8)); | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ===== Ellenőrző kérdések 2 ===== | ||
+ | |||
+ | * Mi az az math.h? | ||
+ | * A maradék képzést milyen operátorral valósítjuk meg? | ||
+ | * Mondjon két egy operandusú operátort. | ||
+ | * Mondjon négy bitenkénti operátort. | ||
+ | * Milyen utasítással írathatunk ki formázott kivitelt. | ||
+ | * Formázott kivitel esetén, valós számot milyen formátumkarakterrel tudunk kiíratni? | ||
+ | |||
+ | ===== Véletlen szám ===== | ||
+ | |||
+ | |||
+ | ==== Függvények ==== | ||
+ | |||
+ | Az stdlib.h fájlban találhatók a következő függvények. | ||
+ | |||
+ | int rand(void) | ||
+ | void srand(unsigned int) | ||
+ | |||
+ | A két függvény az ANSI szabvány része. | ||
+ | ==== Példa 1 ==== | ||
+ | |||
+ | <code c veletlen.c> | ||
+ | |||
+ | #include <stdio.h> | ||
+ | #include <stdlib.h> | ||
+ | #include <time.h> | ||
+ | |||
+ | int main() | ||
+ | { | ||
+ | printf("Véletlen\n"); | ||
+ | srand(time(NULL)); | ||
+ | printf("0 és 4 között: %d\n", rand() % 5); | ||
+ | printf("20 és 29 között: %d\n", rand() % 10 +20); | ||
+ | return 0; | ||
+ | } | ||
+ | |||
+ | </code> | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ==== Újabb példa ==== | ||
+ | |||
+ | <code c veletlen.c> | ||
+ | #include <stdio.h> | ||
+ | #include <stdlib.h> | ||
+ | #include <time.h> | ||
+ | main() | ||
+ | { | ||
+ | srand(time(NULL)); | ||
+ | |||
+ | int a = rand() % 2; | ||
+ | int b = rand() % 2; | ||
+ | |||
+ | printf("Elso : %d\n", a); | ||
+ | printf("Masodik: %d\n", b); | ||
+ | |||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ==== Valódi véletlen szám ==== | ||
+ | Ha több véletlen számot kell generálnunk egymás után, | ||
+ | a rand() függvény nem ad mindig megfelelő eredményt. | ||
+ | BSD és Linux rendszereken a valódi véletlenszámhoz | ||
+ | használjuk a /dev/urandom állományt. | ||
+ | |||
+ | <code c valid.c> | ||
+ | #include <stdio.h> | ||
+ | #include <stdlib.h> | ||
+ | |||
+ | int sajatVeletlen(int n) { | ||
+ | unsigned int vel; | ||
+ | FILE *f; | ||
+ | |||
+ | f = fopen("/dev/urandom", "r"); | ||
+ | fread(&vel, sizeof(vel), 1, f); | ||
+ | fclose(f); | ||
+ | | ||
+ | return vel % n; | ||
+ | } | ||
+ | |||
+ | int main() { | ||
+ | printf("%d\n", sajatVeletlen(6)); | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ===== Konverzió ===== | ||
+ | |||
+ | ==== Konvertáláshoz használt függvények ==== | ||
+ | |||
+ | <code c> | ||
+ | double atof(const char*) | ||
+ | int atoi(const char*) | ||
+ | long atol(const char*) | ||
+ | |||
+ | int ltoa(int, char*, int) | ||
+ | </code> | ||
+ | |||
+ | |||
+ | ==== String egész számmá ==== | ||
+ | |||
+ | <code c> | ||
+ | char *s = (char*) malloc(5 * sizeof(char)); | ||
+ | strcpy(s, "15"); | ||
+ | int a = atoi(s); | ||
+ | </code> | ||
+ | |||
+ | Az atoi() függvény a stdlib.h fejállományból érhető el. | ||
+ | |||
+ | ==== String hosszú egész számmá ==== | ||
+ | |||
+ | <code c> | ||
+ | char *s = (char*) malloc(5 * sizeof(char)); | ||
+ | strcpy(s, "15"); | ||
+ | long a = atol(s); | ||
+ | </code> | ||
+ | |||
+ | Az atol() függvény a stdlib.h fejállományból érhető el. | ||
+ | |||
+ | |||
+ | ==== String valós számmá ==== | ||
+ | |||
+ | <code c> | ||
+ | char *s = (char*) malloc(5 * sizeof(char)); | ||
+ | strcpy(s, "15"); | ||
+ | float a = atof(s); | ||
+ | </code> | ||
+ | |||
+ | Az atof() függvény a stdlib.h fejállományból érhető el. | ||
+ | ==== Egész stringgé ==== | ||
+ | |||
+ | |||
+ | <code c> | ||
+ | char *s = (char*) malloc(10 * sizeof(char)); | ||
+ | int a = 15; | ||
+ | sprintf(s, "%d", a); | ||
+ | </code> | ||
+ | |||
+ | |||
+ | ==== Egész stringgé ==== | ||
+ | |||
+ | |||
+ | <code c> | ||
+ | char *s = (char*) malloc(10 * sizeof(char)); | ||
+ | float a = 15.7; | ||
+ | sprintf(s, "%f", a); | ||
+ | </code> | ||
+ | |||
+ | ==== Karakter stringgé ==== | ||
+ | |||
+ | |||
+ | <code c> | ||
+ | char *s = (char*) malloc(10 * sizeof(char)); | ||
+ | char ch = 'a'; | ||
+ | sprintf(s, "%c", ch); | ||
+ | </code> | ||
+ | |||
+ | |||
+ | ==== String karakterré ==== | ||
+ | |||
+ | <code c> | ||
+ | char *s = (char*) malloc(10 * sizeof(char)); | ||
+ | strcpy(s, "a"); | ||
+ | char ch = s[0]; | ||
+ | </code> | ||
+ | |||
+ | ===== Bevitel ===== | ||
+ | |||
+ | ==== Szám bekérése ==== | ||
+ | |||
+ | |||
+ | <code c Program01.c> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | main() | ||
+ | { | ||
+ | int a; | ||
+ | printf("Szam: "); | ||
+ | scanf("%d", &a); | ||
+ | printf("Ezt írtad: %d\n", a); | ||
+ | } | ||
+ | |||
+ | </code> | ||
+ | |||
+ | ==== Szöveg bekérése ==== | ||
+ | |||
+ | Az fgets állományok olvasására való, azonban az stdio.h fejlécállományban | ||
+ | deklarálva van egy stdin nevű fájl, amely billentyűzetet szimbolizálja. | ||
+ | Így egy valódi állomány helyett a billentyűzetet is olvashatjuk. | ||
+ | |||
+ | <code c Prgram01.c> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | main() | ||
+ | { | ||
+ | char nev[100]; | ||
+ | |||
+ | printf("Név: "); | ||
+ | fgets(nev, 100, stdin); | ||
+ | printf("Ezt írtad: %s\n", nev); | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | |||
+ | Az fgets() függvény csak adott számú karaktert kér be, amit a második | ||
+ | paraméterben adhatunk meg. Az fgets() függvény beolvassa az Enter billentyűt is. | ||
+ | |||
+ | Ha szeretnénk sortörés elhagyni, akkor a | ||
+ | következő egyszerű példa erre mutat egy lehetőséget. | ||
+ | A karaktersorozat első elemének címét az „s” | ||
+ | mutató tartalmazza: | ||
+ | |||
+ | <code c> | ||
+ | if (s[strlen(s)-1]=='\n') s[strlen(s)-1] = '\0'; | ||
+ | </code> | ||
+ | |||
+ | A fenti utasítás csak akkor tünteti el az utolsó | ||
+ | karaktert, ha az valóban egy sortörés. Működése: | ||
+ | megnézzük , hogy az utolsó karakter sortörése. | ||
+ | Ha igen, akkor lecseréljük karakter sorozat végét | ||
+ | jelölő null karakterre. | ||
+ | |||
+ | |||
+ | |||
+ | <code c Program01.c> | ||
+ | #include <stdio.h> | ||
+ | #include <stdlib.h> | ||
+ | main() | ||
+ | { | ||
+ | char *nev; | ||
+ | nev = (char*) malloc(100 * sizeof(char)); | ||
+ | printf("Név: "); | ||
+ | fgets(nev, 100, stdin); | ||
+ | printf("Ezt írtad: %s\n", nev); | ||
+ | } | ||
+ | |||
+ | </code> | ||
+ | |||
+ | |||
+ | |||
+ | <code c Program01.c> | ||
+ | #include <stdio.h> | ||
+ | #include <stdlib.h> | ||
+ | main() | ||
+ | { | ||
+ | char *nev; | ||
+ | nev = (char*) malloc(100 * sizeof(char)); | ||
+ | printf("Név: "); | ||
+ | scanf("%s", nev); | ||
+ | printf("Ezt írtad: %s\n", nev); | ||
+ | } | ||
+ | |||
+ | </code> | ||
+ | |||
+ | |||
+ | ===== Szelekció ===== | ||
+ | |||
+ | ==== if ==== | ||
+ | |||
+ | |||
+ | <code c> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | main() | ||
+ | { | ||
+ | int a = 5; | ||
+ | if(a > 0) | ||
+ | printf("Pozitív szám\n"); | ||
+ | |||
+ | } | ||
+ | |||
+ | </code> | ||
+ | |||
+ | |||
+ | ==== if-else ==== | ||
+ | |||
+ | <code c> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | main() | ||
+ | { | ||
+ | int a = 5; | ||
+ | if(a > 0) | ||
+ | printf("Pozitív szám\n"); | ||
+ | else | ||
+ | printf("Nulla vagy negatív\n"); | ||
+ | |||
+ | } | ||
+ | |||
+ | </code> | ||
+ | |||
+ | |||
+ | ==== switch ==== | ||
+ | |||
+ | A switch() utasítás paramétereként a C nyelvben csak egész számokat | ||
+ | megvalósító típusok adhatok meg. Például int, char. | ||
+ | |||
+ | <code c Program01.c> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | main() | ||
+ | { | ||
+ | int szam; | ||
+ | |||
+ | printf("Szám: "); | ||
+ | scanf("%d", &szam); | ||
+ | |||
+ | switch(szam) | ||
+ | { | ||
+ | case 1 : | ||
+ | printf("Egy\n"); break; | ||
+ | case 2 : | ||
+ | printf("Kettő\n"); break; | ||
+ | default: | ||
+ | printf("Más szám\n"); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </code> | ||
+ | |||
+ | Minden case részt meg kell szakítani egy break utasítással, ha nem szeretnénk | ||
+ | a következő case utáni rész is végrehajtani. | ||
+ | ===== Iteráció ===== | ||
+ | |||
+ | ==== for ==== | ||
+ | |||
+ | <code c> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | main() | ||
+ | { | ||
+ | int i; | ||
+ | for(i=0; i<10;i++) | ||
+ | printf("%d\n", i); | ||
+ | } | ||
+ | |||
+ | </code> | ||
+ | |||
+ | ==== while ==== | ||
+ | |||
+ | <code c> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | main() | ||
+ | { | ||
+ | int i=0; | ||
+ | while(i<10) | ||
+ | { | ||
+ | printf("%d\n", i); | ||
+ | i++; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </code> | ||
+ | |||
+ | ==== do-while ==== | ||
+ | |||
+ | <code c> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | main() | ||
+ | { | ||
+ | int i=0; | ||
+ | do { | ||
+ | printf("%d\n", i); | ||
+ | i++; | ||
+ | }while(i<10); | ||
+ | } | ||
+ | |||
+ | </code> | ||
+ | |||
+ | |||
+ | |||
+ | ===== Összetett típusok ===== | ||
+ | |||
+ | ==== enum ==== | ||
+ | Felsorolt vagy enum típus. Az enum a felsorolt értékeket egészként tárolja. | ||
+ | |||
+ | <code c> | ||
+ | enum {hetfo, kedd, szerda, csutortok pentek}; | ||
+ | </code> | ||
+ | A hetfo 0 értékkel egyenlő, a kedd 1 értékkel, a szerda 2, stb. | ||
+ | |||
+ | <code c enum.c> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | main() | ||
+ | { | ||
+ | enum het {hetfo, kedd, szerda, csutortok, pentek, szombat, vasarnap}; | ||
+ | |||
+ | enum het a; | ||
+ | a = hetfo; | ||
+ | if(a==hetfo) | ||
+ | printf("hétfő\n"); | ||
+ | |||
+ | } | ||
+ | </code> | ||
+ | A fenti példában deklarálunk egy a változót, amely a het napjai értéket veheti | ||
+ | fel: | ||
+ | <code c> | ||
+ | enum het a; | ||
+ | </code> | ||
+ | |||
+ | Az a változóban ez után értékként megadhatjuk a hetfo, kedd, szerda, stb. értékeket. | ||
+ | A példában a hetfo értéket adjuk meg: | ||
+ | <code c> | ||
+ | a = hetfo; | ||
+ | </code> | ||
+ | Ezek után megvizsgálhatjuk, hogy az a változó milyen értéket tartalmaz. | ||
+ | A példában az vizsgáljuk értéke egyenlő-e hetfo-vel: | ||
+ | <code c> | ||
+ | if(a==hetfo) | ||
+ | </code> | ||
+ | |||
+ | Az a változóval persze többet is tehetünk. Például növelhetjük az értéket: | ||
+ | <code c> | ||
+ | a++ | ||
+ | </code> | ||
+ | Egy ilyen növelés után a tartalma már kedd lesz. | ||
+ | |||
+ | |||
+ | Megjegyzés: A későbbiekben még veszünk összetett adattípusokat. Ilyen lesz a | ||
+ | tömb meg a struktúra. | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ===== Karaktersorozat ===== | ||
+ | |||
+ | ==== Tárolás ==== | ||
+ | |||
+ | |||
+ | A karaktersorozat (angolul string) típus nem létezik a C nyelvben. | ||
+ | Ha karakter sorozatot szeretnénk tárolni, akkor egy karakteres mutató | ||
+ | típusú változót hozok létre, ahol a mutatótól kezdve a memóriában | ||
+ | több karaktert is tárolhatok. A mutató típusú változó a karaktersorozat | ||
+ | elejére mutat a memóriában. A sorozat végét egy null karakter adja (nem az | ||
+ | ASCII 0-ás karaktere, hanem egy olyan byte aminek az értéke 0. | ||
+ | Escape szekvenciával jelölve: | ||
+ | |||
+ | <code c> | ||
+ | '\0' | ||
+ | </code> | ||
+ | |||
+ | |||
+ | ^ betűk | 'H' | 'e' | 'l' | 'l' | 'o' | 0 | | ||
+ | ^ memóriacím | fe1011 | fe1012 | fe1013 | fe1014 | fe1015 | fe1016 | | ||
+ | |||
+ | Az utolsó tehát nem számjegy, hanem egy 0 értékű bájt. | ||
+ | |||
+ | Ezt persze nem kell nekünk a karakter sorozat végére tenni, mert az | ||
+ | a fordító automatikusan megteszi. Egy ilyen mutató létrehozása | ||
+ | a következő képen néz ki: | ||
+ | |||
+ | |||
+ | <code c> | ||
+ | char *s; | ||
+ | </code> | ||
+ | |||
+ | A működéshez le kell még foglalni annyi karakter helyet a memóriában, amennyit | ||
+ | szeretnénk eltárolni. A helyfoglaláshoz két függvényt szoktunk használni: | ||
+ | * malloc() | ||
+ | * calloc() | ||
+ | Mind a kettő az stdlib.h programozói könyvtárakban van. | ||
+ | Mi most a malloc() használatát nézzük meg. | ||
+ | |||
+ | A malloc() függvénynek egyetlen paramétere van, mégpedig a | ||
+ | lefoglalandó byte-ok száma. Ha például 30 karaktert | ||
+ | akarunk tárolni, akkor így írhatjuk: | ||
+ | <code c> | ||
+ | malloc(30); | ||
+ | </code> | ||
+ | Ezzel még nincs kész. Meg kell adni, hogy melyik mutatóhoz | ||
+ | rendeljük ezt a 30 byte-ot: | ||
+ | |||
+ | <code c> | ||
+ | s = malloc(30); | ||
+ | </code> | ||
+ | |||
+ | A malloc() azonban void típus ad vissza, amit át kell alakítanunk | ||
+ | char* típusúvá: | ||
+ | |||
+ | <code c> | ||
+ | s = (char*) malloc(30); | ||
+ | </code> | ||
+ | |||
+ | Ez már egy működő helyfoglalás. | ||
+ | |||
+ | A deklarálás és a helyfoglalás együtt ezek után: | ||
+ | |||
+ | <code c> | ||
+ | #include <stdlib.h> | ||
+ | |||
+ | main() | ||
+ | { | ||
+ | char *s; | ||
+ | s = (char*) malloc(30); | ||
+ | } | ||
+ | |||
+ | </code> | ||
+ | |||
+ | |||
+ | A C nyelven egy karakter eltárolására nem biztos, hogy 1 byte-ot | ||
+ | használunk. Ez függhet az adott rendszertől. A helyfoglaló | ||
+ | függvényt ezért szokás kibővíteni egy vizsgálattal, amely megmondja | ||
+ | mekkora egy char típus az adott rendszerben. Erre a sizeof() | ||
+ | operátort használhatjuk. Az általa visszaadott értéket | ||
+ | szorozzuk be 30-al: | ||
+ | |||
+ | |||
+ | <code c> | ||
+ | #include <stdlib.h> | ||
+ | main() | ||
+ | { | ||
+ | char *s; | ||
+ | s = (char*) malloc(30 * sizeof(char)); | ||
+ | } | ||
+ | |||
+ | </code> | ||
+ | |||
+ | Ha szeretnénk megváltoztatni a lefoglalt hely mérettét az következő utasítással tehetjük meg: | ||
+ | * realloc() | ||
+ | |||
+ | A lefoglalt hely felszabadítása: | ||
+ | * free() | ||
+ | |||
+ | ==== A változó használata ==== | ||
+ | |||
+ | |||
+ | Most már használhatjuk a "s" változót. A C nyelvben egy | ||
+ | karakter sorozatot nem adhatunk meg egy egyenlőség jel jobboldalán. | ||
+ | Ha egy változóban egy karaktersorozatot szeretnénk elhelyezni, | ||
+ | akkor arra az strcpy() függvény használható, amely a string.h | ||
+ | könyvtárakban találhatók: | ||
+ | |||
+ | <code c> | ||
+ | #include <stdlib> | ||
+ | #include <string.h> | ||
+ | main() | ||
+ | { | ||
+ | char *gyumolcs; | ||
+ | gyumolcs = (char*) malloc(30 * sizeof(char)); | ||
+ | strcpy(gyumolcs, "szilva"); | ||
+ | } | ||
+ | |||
+ | </code> | ||
+ | |||
+ | ==== Kiíratás ==== | ||
+ | |||
+ | |||
+ | |||
+ | Ha egy változóban lévő karaktersorozatot akarunk a képernyőre íratni, akkor | ||
+ | az "s" formátumkódot kell használnunk. A fenti gyumolcs változó tartalmának | ||
+ | képernyőre íratása: | ||
+ | |||
+ | |||
+ | |||
+ | <code c gyumolcs.c> | ||
+ | #include <stdio.h> | ||
+ | #include <stdlib> | ||
+ | #include <string.h> | ||
+ | main() | ||
+ | { | ||
+ | char *gyumolcs; | ||
+ | gyumolcs = (char*) malloc(30 * sizeof(char)); | ||
+ | strcpy(gyumolcs, "szilva"); | ||
+ | printf("%s\n", gyumolcs); | ||
+ | } | ||
+ | |||
+ | </code> | ||
+ | |||
+ | |||
+ | ==== Bekérés ==== | ||
+ | |||
+ | |||
+ | <code c bekerstr.c> | ||
+ | #include <stdio.h> | ||
+ | #include <stdlib> | ||
+ | |||
+ | main() | ||
+ | { | ||
+ | char *gyumolcs; | ||
+ | gyumolcs = (char*) malloc(30 * sizeof(char)); | ||
+ | scanf("%s" gyumolcs); | ||
+ | printf("%s\n", gyumolcs); | ||
+ | } | ||
+ | |||
+ | </code> | ||
+ | |||
+ | Ha egy változóba egy értéket teszünk a scanf() függvénnyel, akkor | ||
+ | sosem magát a mutató, hanem annak címét kell megadnunk. Ezt úgy | ||
+ | érjük el, hogy a változó név elé egy "&" karaktert teszünk. | ||
+ | A gyumolcs változó elé mégsem tettünk, mert az eleve mutató típus, | ||
+ | vagyis itt eleve a változó címét kapjuk meg. | ||
+ | |||
+ | A scanf() függvény azonban csak egyetlen szó bekérésére alkalmas, | ||
+ | mert whitespace karakterig olvas. A szóközök után írt karaktereket | ||
+ | már nem tárolja el. Ezért mondatokat nem tudunk vele beolvasni. | ||
+ | Mondatokat a gets vagy fgets függvények alkalmasak. | ||
+ | |||
+ | ==== Karaktersorozat darabolása ==== | ||
+ | A C nyelvben az strtok() függvényt használhatjuk egy karaktersorozat darabolására. | ||
+ | |||
+ | Szintaktikája: | ||
+ | <code c> | ||
+ | #include <string.h> | ||
+ | char *strtok( char *str1, const char *str2 ); | ||
+ | </code> | ||
+ | |||
+ | |||
+ | Az strtok() függvény visszaad egy következő egységet (tokent), a karaktersorozatból. | ||
+ | A választott karaktersorozat az első paraméter. Második paraméter az elválasztó. | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | <code c> | ||
+ | strcpy(str, "alma:körte:szilva:barack"); | ||
+ | strtok(str, ":"); | ||
+ | </code> | ||
+ | |||
+ | Az strtok() NULL értékkel tér vissza ha nem talál több tokent. | ||
+ | Az strtok() függvényt úgy használjuk, hogy az első részt | ||
+ | kiolvassuk első paraméternek megadva az str változót: | ||
+ | |||
+ | <code c> | ||
+ | strtok(str, ":"); | ||
+ | </code> | ||
+ | |||
+ | Minden további hívást a NULL értékkel kell végrehajtani: | ||
+ | <code c> | ||
+ | strtok(NULL, ":"); | ||
+ | </code> | ||
+ | |||
+ | A teljes megvalósítás így nézhet ki: | ||
+ | |||
+ | <code c kardarab.c> | ||
+ | #include <stdio.h> | ||
+ | #include <stdlib.h> | ||
+ | main() | ||
+ | { | ||
+ | char *str = (char*) malloc(30 * sizeof(char)); | ||
+ | char *token = NULL; | ||
+ | strcpy(str, "alma:körte:szilva:barack"); | ||
+ | |||
+ | token = (char*) strtok(str, ":"); | ||
+ | while(token != NULL) | ||
+ | { | ||
+ | printf("%s\n", token); | ||
+ | token = (char*) strtok(NULL, ":"); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | </code> | ||
+ | |||
+ | Másik példa: | ||
+ | <code c kardarab2.c> | ||
+ | #include <stdio.h> | ||
+ | #include <stdlib.h> | ||
+ | main() | ||
+ | { | ||
+ | char *jarmu = (char*) malloc(30 * sizeof(char)); | ||
+ | char elvalaszto[] = ":"; | ||
+ | char *resz = NULL; | ||
+ | strcpy(jarmu, "opel:ford:citroen:mazda"); | ||
+ | |||
+ | resz = (char*) strtok(jarmu, elvalaszto); | ||
+ | while(resz != NULL) | ||
+ | { | ||
+ | printf("%s\n", resz); | ||
+ | resz = (char*) strtok(NULL, elvalaszto); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | Ugyanaz más szeparátorral: | ||
+ | <code c kardarab3.c> | ||
+ | #include <stdio.h> | ||
+ | #include <stdlib.h> | ||
+ | main() | ||
+ | { | ||
+ | char *jarmu = (char*) malloc(30 * sizeof(char)); | ||
+ | char elvalaszto[] = "#"; | ||
+ | char *resz = NULL; | ||
+ | strcpy(jarmu, "opel#ford#citroen#mazda"); | ||
+ | |||
+ | resz = (char*) strtok(jarmu, elvalaszto); | ||
+ | while(resz != NULL) | ||
+ | { | ||
+ | printf("%s\n", resz); | ||
+ | resz = (char*) strtok(NULL, elvalaszto); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | |||
+ | A szeparátorokaból lehet több is: | ||
+ | <code c kardarab4.c> | ||
+ | #include <stdio.h> | ||
+ | #include <stdlib.h> | ||
+ | main() | ||
+ | { | ||
+ | char *jarmu = (char*) malloc(30 * sizeof(char)); | ||
+ | char elvalaszto[] = "#:;"; | ||
+ | char *resz = NULL; | ||
+ | strcpy(jarmu, "opel#ford:citroen;mazda"); | ||
+ | |||
+ | resz = (char*) strtok(jarmu, elvalaszto); | ||
+ | while(resz != NULL) | ||
+ | { | ||
+ | printf("%s\n", resz); | ||
+ | resz = (char*) strtok(NULL, elvalaszto); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | Lásd még: | ||
+ | |||
+ | * [[oktatas:programozás:c:c_példaprogram#sztring_darabolás]] | ||
+ | ===== Tömb ===== | ||
+ | ==== Vektor ==== | ||
+ | |||
+ | A tömbök azonos típusú elemek tárolása kitalált adatszerkezet. | ||
+ | Például több egész számot is szeretnék eltárolni. | ||
+ | A változó deklaráció során jeleznünk kell, hogy | ||
+ | most nem egy értékű változóról van szó. ezt a | ||
+ | változó neve után tett szögletes zárójelek jelzik. | ||
+ | |||
+ | <code c> | ||
+ | int tomb[4]; | ||
+ | </code> | ||
+ | Meg kell adnunk azt is hány darab értéket szeretnénk tárolni. | ||
+ | A fenti példában négy darab érték tárolásához foglaltunk memóriát, | ||
+ | amely mindegyik "int" azaz egész típusú lehet. | ||
+ | |||
+ | |||
+ | A tömbnek ez után 4 eleme lehet. Minden elemet egy indexel tudunk | ||
+ | azonosítani. Az első index a nulla: 0, majd a többi szám. | ||
+ | Ebből következik, hogy egy négy elemű tömbnél a legfelső index | ||
+ | 3. | ||
+ | |||
+ | A tömb elemeinek úgy adhatunk értéket, hogy leírjuk a tömb nevét, | ||
+ | utána szögletes zárójelben megadom, melyik indexű elemet akarom | ||
+ | beállítani. | ||
+ | |||
+ | <code c> | ||
+ | int tomb[4]; | ||
+ | tomb[0] = 3; | ||
+ | tomb[1] = 8; | ||
+ | tomb[2] = 5; | ||
+ | tomb[3] = 2; | ||
+ | </code> | ||
+ | |||
+ | Felhasználni ugyanígy tudjuk. Ha szeretném például kiíratni a tömb egyik elemét, azt így tehetem meg: | ||
+ | <code c> | ||
+ | printf("%d\n", tomb[0]); | ||
+ | </code> | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ==== Tömb kezdőértékkel ==== | ||
+ | A tömböknek rögtön kezdőértéket adhatunk a deklarációban. Az alábbi példában erre látunk példát. | ||
+ | |||
+ | <code c tomb1.c> | ||
+ | #include <stdio.h> | ||
+ | main() | ||
+ | { | ||
+ | int tomb[] = {3, 5, 6, 7, 8, 9 }; | ||
+ | printf("%d\n", tomb[0]); | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | Megadható a tömb nagysága: | ||
+ | <code c> | ||
+ | int tomb[3] = {3, 5, 6}; | ||
+ | </code> | ||
+ | De ez nem kötelező. Ha viszont megadjuk akkor annak értéke nem lehet | ||
+ | kisebb a tömb kezdőértékeinek a számánál. | ||
+ | |||
+ | Ez még helyes. | ||
+ | <code c> | ||
+ | int tomb[5] = {3, 5, 6}; | ||
+ | </code> | ||
+ | Ez már helytelen: | ||
+ | |||
+ | <del>int tomb[2] = {3, 5, 6};</del> | ||
+ | |||
+ | |||
+ | |||
+ | <code c tomb.c> | ||
+ | #include <stdio.h> | ||
+ | #include <math.h> | ||
+ | #define MAX 2 | ||
+ | typedef int Ttomb[MAX]; | ||
+ | |||
+ | void kiir(int *tomb) | ||
+ | { | ||
+ | tomb[0]=8; | ||
+ | } | ||
+ | main() | ||
+ | { | ||
+ | Ttomb tomb; | ||
+ | |||
+ | tomb[0] = 5; | ||
+ | tomb[5] = 3; | ||
+ | |||
+ | kiir(tomb); | ||
+ | printf("%d\n", tomb[0]); | ||
+ | |||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ==== Mátrix ==== | ||
+ | A tömböknek lehet két kiterjedése is. Ekkor mátrixról beszélünk. | ||
+ | A tömb felépítése ekkor hasonlít a matematikában tanult mátrixhoz, | ||
+ | amelynek kiterjedése kétirányú. | ||
+ | |||
+ | Lássunk egy példát egy mátrixra: | ||
+ | |||
+ | | 3 | 12 | 8 | 9 | | ||
+ | | 2 | 15 | 17 | 7 | | ||
+ | | 11 | 4 | 3 | 18 | | ||
+ | |||
+ | === Mátrix létrehozása C nyelven === | ||
+ | |||
+ | |||
+ | Az alábbi egyszerű mátrixot szeretnénk megvalósítani: | ||
+ | | 3 | 12 | 8 | 9 | | ||
+ | | 2 | 15 | 17 | 7 | | ||
+ | |||
+ | <code c> | ||
+ | int tomb[2][4]; | ||
+ | </code> | ||
+ | Ez két sort és 4 oszlopot jelent. | ||
+ | |||
+ | |||
+ | Értékadás: | ||
+ | <code c> | ||
+ | int tomb[2][4]; | ||
+ | //Első sor: | ||
+ | tomb[0][0] = 3; | ||
+ | tomb[0][1] = 12; | ||
+ | tomb[0][2] = 8; | ||
+ | tomb[0][3] = 9; | ||
+ | //Második sor: | ||
+ | tomb[1][0] = 2; | ||
+ | tomb[1][1] = 15; | ||
+ | tomb[1][2] = 17; | ||
+ | tomb[1][3] = 7; | ||
+ | </code> | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | === Mátrix kezdőértéke === | ||
+ | |||
+ | |||
+ | <code c> | ||
+ | int tomb2[2][4] = { | ||
+ | {3, 13, 8, 9}, | ||
+ | {2, 15, 17, 7} | ||
+ | }; | ||
+ | </code> | ||
+ | |||
+ | ==== Feltöltés ==== | ||
+ | |||
+ | GCC-ben: | ||
+ | <code c> | ||
+ | int tomb[10] = {[0 ... 9] = 5}; | ||
+ | </code> | ||
+ | |||
+ | Egyébként meg egy for ciklussal. | ||
+ | |||
+ | |||
+ | ==== Tömb paraméterként ==== | ||
+ | |||
+ | Tömb átadása paraméterként: | ||
+ | |||
+ | <code c rendez.c> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | void rendez(int *tomb) | ||
+ | { | ||
+ | if(tomb[0] > tomb[1]) | ||
+ | { | ||
+ | int tmp = tomb[0]; | ||
+ | tomb[0] = tomb[1]; | ||
+ | tomb[1] = tmp; | ||
+ | } | ||
+ | } | ||
+ | main() | ||
+ | { | ||
+ | int tomb[2]; | ||
+ | tomb[0] = 3; | ||
+ | tomb[1] = 2; | ||
+ | rendez(tomb); | ||
+ | printf("%d %d\n", tomb[0], tomb[1]); | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | Az átadott tömb cím szerint adódik át. | ||
+ | |||
+ | |||
+ | ===== Saját típus ===== | ||
+ | ==== A saját típusok alapjai ==== | ||
+ | |||
+ | |||
+ | Vannak olyan esetek amelyekben célszerű saját típust létrehozni. | ||
+ | Először nézzük meg, hogyan kell saját típust létrehozni. | ||
+ | |||
+ | |||
+ | Általánosan: | ||
+ | <code c> | ||
+ | typedef típus újtipusnév; | ||
+ | </code> | ||
+ | |||
+ | Legyen a példa kedvéért egy új típus amely megegyezik az egészeket tárolni képes int típussal: | ||
+ | <code c> | ||
+ | typedef int TEgesz; | ||
+ | </code> | ||
+ | |||
+ | Ezek után, például így használhatom: | ||
+ | <code c> | ||
+ | TEgesz szam = 5; | ||
+ | </code> | ||
+ | |||
+ | A "TEgesz" azonosítót mint típust használtam fel. | ||
+ | |||
+ | Ennek persze kevés értelme lehet, de annál több haszna van, | ||
+ | tömbtípusok létrehozásánál, különösen ha a tömböket | ||
+ | paraméterként szeretném átadni. Lássunk egy tömbtípus létrehozását: | ||
+ | |||
+ | <code c> | ||
+ | typedef int TEgeszTomb[100]; | ||
+ | </code> | ||
+ | |||
+ | Ezek után így használhatom: | ||
+ | |||
+ | <code c> | ||
+ | TEgeszTomb tomb; | ||
+ | tomb[0] = 5; | ||
+ | tomb[1] = 8; | ||
+ | //... | ||
+ | </code> | ||
+ | |||
+ | |||
+ | ==== Saját típus a paraméterlistában ==== | ||
+ | |||
+ | Még hasznosabb, amikor a saját típust paraméterlistában használjuk. | ||
+ | |||
+ | |||
+ | |||
+ | <code c main.c> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | typedef TEgeszTomb[100]; | ||
+ | |||
+ | |||
+ | int sum(TEgeszTomb ptomb) | ||
+ | { | ||
+ | int osszeg = 0, i; | ||
+ | for(i=0; i<5; i++) | ||
+ | osszeg = osszeg + ptomb[i]; | ||
+ | return osszeg; | ||
+ | } | ||
+ | |||
+ | main() | ||
+ | { | ||
+ | |||
+ | TEgeszTomb tomb = {3, 5, 8, 2, 7}; | ||
+ | |||
+ | printf("%d\n", sum(tomb)); | ||
+ | |||
+ | } | ||
+ | </code> | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ===== Fájlkezelés ===== | ||
+ | |||
+ | Az állományok írása és olvasása a stdio.h könyvtárak függvényei teszik lehetővé. | ||
+ | A C nyelvben egy a fájlváltozó típusa FILE. Mutatóként kell létrehoznunk, ezért | ||
+ | fájlmutatóról fogunk beszélni. A fájlokat először mindig meg kell nyitni, használat | ||
+ | után pedig bezárni. A megnyitásnak több módja is van, amelyek a következő táblázatban | ||
+ | találhatók. | ||
+ | |||
+ | ^ Mód ^ Leírás ^ | ||
+ | | "r" | Megnyitás olvasásra. | | ||
+ | | "w" | Megnyitás írásra. | | ||
+ | | "a" | Megnyitás hozzáfűzésre. | | ||
+ | | "r+" | Olvasható-írható mód. Írás a fájl elejére. | | ||
+ | | "w+" | Olvasható-írható mód. Az fájl tartalma elvész. | | ||
+ | | "a+" | Olvasható-írhatód mód. Kezdetben a fájlmutató elöl van. Az írás viszont a fájl végére történik | | ||
+ | |||
+ | A megnyitott állományt csatorna névvel is szokás illetni. A megnyitás az fopen() függvénnyel történik. | ||
+ | Az fopen() szintaxisa: | ||
+ | fájlmutató = fopen(char *állománynév, char *mód) | ||
+ | |||
+ | Például: | ||
+ | <code c> | ||
+ | FILE *fp; | ||
+ | fp = fopen("adat.txt", "w"); | ||
+ | </code> | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ==== Írás ==== | ||
+ | |||
+ | |||
+ | <code c main.c> | ||
+ | #include <stdio.h> | ||
+ | main() | ||
+ | { | ||
+ | FILE *f; | ||
+ | f = fopen("adat.txt","w"); | ||
+ | fputs("alma",f); | ||
+ | fputs("szilva",f); | ||
+ | fputs("barack",f); | ||
+ | fclose(f); | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | |||
+ | |||
+ | ==== Hozzáfűzés ==== | ||
+ | |||
+ | |||
+ | <code c main.c> | ||
+ | #include <stdio.h> | ||
+ | main() | ||
+ | { | ||
+ | FILE *f; | ||
+ | f = fopen("adat.txt","a"); | ||
+ | fputs("Valami",f); | ||
+ | fclose(f); | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | |||
+ | |||
+ | ==== Olvasás fájlból ==== | ||
+ | |||
+ | <code txt adat.txt> | ||
+ | alma | ||
+ | szilva | ||
+ | barack | ||
+ | |||
+ | </code> | ||
+ | |||
+ | |||
+ | <code c olvas.h> | ||
+ | #include <stdio.h> | ||
+ | #include <stdlib.h> | ||
+ | |||
+ | main() | ||
+ | { | ||
+ | FILE *fp = fopen("adat.txt", "r"); | ||
+ | char *str = (char*) malloc(30 * sizeof(char)); | ||
+ | |||
+ | while(!feof(fp)) | ||
+ | { | ||
+ | fgets(str, 30, fp); | ||
+ | if(!feof(fp)) | ||
+ | printf("%s", str); | ||
+ | } | ||
+ | fclose(fp); | ||
+ | } | ||
+ | </code> | ||
+ | A fenti program képes az összes sort gond nélkül kiírni, akár van | ||
+ | az utolsó sor végén sortörés, akár nincs. | ||
+ | |||
+ | |||
+ | A következő megoldás működik, de csak akkor, ha az utolsó sor után van sortörés: | ||
+ | |||
+ | <code c olvas.c> | ||
+ | #include <stdio.h> | ||
+ | #include <stdlib.h> | ||
+ | |||
+ | main() | ||
+ | { | ||
+ | FILE *fp = fopen("adat.txt", "r"); | ||
+ | char *str = (char*) malloc(30 * sizeof(char)); | ||
+ | |||
+ | fgets(str, 30, fp); | ||
+ | while(!feof(fp)) | ||
+ | { | ||
+ | printf("%s", str); | ||
+ | fgets(str, 30, fp); | ||
+ | } | ||
+ | fclose(fp); | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | |||
+ | |||
+ | Az adat.txt állományhoz írunk áradatokat. | ||
+ | |||
+ | <code txt adat.txt> | ||
+ | alma 250 | ||
+ | szilva 300 | ||
+ | barack 450 | ||
+ | |||
+ | </code> | ||
+ | |||
+ | |||
+ | <code c olvas.c> | ||
+ | #include <stdio.h> | ||
+ | #include <stdlib.h> | ||
+ | #include <string.h> | ||
+ | main() | ||
+ | { | ||
+ | FILE *fp = fopen("adat2.txt", "r"); | ||
+ | char *str = (char*) malloc(30 * sizeof(char)); | ||
+ | char *nev = (char*) malloc(30 * sizeof(char)); | ||
+ | int ar; | ||
+ | |||
+ | while(!feof(fp)) | ||
+ | { | ||
+ | fgets(str, 30, fp); | ||
+ | if(!feof(fp)) | ||
+ | { | ||
+ | sscanf(str, "%s %d\n", nev,&ar); | ||
+ | printf("%s %d\n", nev, ar); | ||
+ | } | ||
+ | } | ||
+ | fclose(fp); | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | |||
+ | <code c olvas.c> | ||
+ | #include <stdio.h> | ||
+ | #include <stdlib.h> | ||
+ | #include <string.h> | ||
+ | main() | ||
+ | { | ||
+ | FILE *fp = fopen("adat2.txt", "r"); | ||
+ | char *str = (char*) malloc(30 * sizeof(char)); | ||
+ | char *nev = (char*) malloc(30 * sizeof(char)); | ||
+ | int ar; | ||
+ | |||
+ | while(!feof(fp)) | ||
+ | { | ||
+ | fgets(str, 30, fp); | ||
+ | if(!feof(fp)) | ||
+ | { | ||
+ | sscanf(str, "%s", nev); | ||
+ | sscanf(str + strlen(nev), "%d", &ar); | ||
+ | printf("%s %d\n", nev, ar); | ||
+ | } | ||
+ | } | ||
+ | fclose(fp); | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ==== Olvasás karakterenként ==== | ||
+ | |||
+ | <code c olvaskar.c> | ||
+ | #include <stdio.h> | ||
+ | #include <stdlib.h> | ||
+ | main() | ||
+ | { | ||
+ | |||
+ | FILE *fp = fopen("adat.txt", "r"); | ||
+ | char *str = (char*) malloc(30 * sizeof(char)); | ||
+ | |||
+ | char ch; | ||
+ | while((ch = fgetc(fp)) != -1) | ||
+ | printf("%c", ch); | ||
+ | |||
+ | } | ||
+ | </code> | ||
+ | |||
+ | |||
+ | A következő példa megegyezik az előzővel, kivéve, hogy a -1 értéket egy állandóból vesszük, melynek | ||
+ | neve EOF. | ||
+ | |||
+ | |||
+ | |||
+ | <code c olvaseof.c> | ||
+ | #include <stdio.h> | ||
+ | #include <stdlib.h> | ||
+ | main() | ||
+ | { | ||
+ | |||
+ | FILE *fp = fopen("adat.txt", "r"); | ||
+ | char *str = (char*) malloc(30 * sizeof(char)); | ||
+ | |||
+ | char ch; | ||
+ | while((ch = fgetc(fp)) != EOF) | ||
+ | printf("%c", ch); | ||
+ | |||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ==== Hibakezelés ==== | ||
+ | |||
+ | Ha az állomány megnyitása során probléma van, akkor NULL értékkel tér vissza. | ||
+ | Ennek segítségével vizsgálhatjuk, hogy fájl megnyitás sikeres volt-e. | ||
+ | |||
+ | <code c hibakez.c> | ||
+ | #include <stdio.h> | ||
+ | #include <stdlib.h> | ||
+ | #include <errno.h> | ||
+ | main() | ||
+ | { | ||
+ | FILE *fp; | ||
+ | if((fp= fopen("adat.txta", "r"))== NULL) | ||
+ | { | ||
+ | perror("Hiba a fájl megnyitása során\n"); | ||
+ | printf("Hibaszám: %d.\n", errno); | ||
+ | exit(-1); | ||
+ | } | ||
+ | |||
+ | char *str = (char*) malloc(30 * sizeof(char)); | ||
+ | |||
+ | fgets(str, 30, fp); | ||
+ | while(!feof(fp)) | ||
+ | { | ||
+ | printf("%s", str); | ||
+ | fgets(str, 30, fp); | ||
+ | } | ||
+ | fclose(fp); | ||
+ | |||
+ | } | ||
+ | </code> | ||
+ | |||
+ | |||
+ | |||
+ | ===== Függvények ===== | ||
+ | |||
+ | Érték szerint átadott paraméterek: | ||
+ | <code c> | ||
+ | int novel(int szam) | ||
+ | { | ||
+ | return szam + 1; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | Globális paraméterek | ||
+ | |||
+ | <code c> | ||
+ | int szam = 0; | ||
+ | |||
+ | void novel() | ||
+ | { | ||
+ | szam = szam + 1; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | |||
+ | |||
+ | Cím szerint átadott paraméterek | ||
+ | |||
+ | <code c> | ||
+ | void novel(int *szam) | ||
+ | { | ||
+ | *szam = *szam + 1; | ||
+ | } | ||
+ | main() | ||
+ | { | ||
+ | int szam = 0; | ||
+ | novel(&szam); | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ===== stdlib.h ===== | ||
+ | |||
+ | ==== Memóriafoglalás ==== | ||
+ | |||
+ | void* calloc(size_t, size_t) | ||
+ | void* malloc(size_t) | ||
+ | void* realloc(void*, size_t) | ||
+ | void free(void*) | ||
+ | void abor(void) // Program vége | ||
+ | void exit(int) | ||
+ | |||
+ | ==== Egyéb ==== | ||
+ | |||
+ | int system(const char*) // Egy külső program futtatása | ||
+ | char* getenv(const char*) // Környezeti változó lekérdezése | ||
+ | | ||
+ | void _beep(unsigned int, unsigned int) // hang: frekvencia, másodperc | ||
+ | void _sleep(unsigned long) // Várakozás ezredmásodpercig | ||
+ | |||
+ | ===== time.h ===== | ||
+ | |||
+ | |||
+ | ==== localtime() ==== | ||
+ | |||
+ | Szintaxis: | ||
+ | #include <time.h> | ||
+ | struct tm *localtime( const time_t *time ); | ||
+ | |||
+ | |||
+ | |||
+ | Leírás: | ||
+ | A localtime() függvény átkonvertálja a naptári időt helyi időbe. | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ==== time() ==== | ||
+ | |||
+ | Szintaxis | ||
+ | #include <time.h> | ||
+ | time_t time( time_t *time ); | ||
+ | |||
+ | |||
+ | |||
+ | Leírás: | ||
+ | |||
+ | A time() függvény visszatér az aktuális idővel, vagy -1-gyel ha hiba történik. Ha van megadunk egy time paramétert, | ||
+ | akkor az aktuális idő eltárolódik ebben a változóban. | ||
+ | |||
+ | |||
+ | |||
+ | ==== strftime ==== | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | Az strftime() függvény dátum és időt formáz a time kimenetből egy formátum sztring alapján. A visszatérési érték szintén egy sztring. Az egyes formátumokhoz tartozó formátum kódok a következő táblázat mutatja: | ||
+ | |||
+ | |||
+ | ^ Kód ^ Jelentés ^ | ||
+ | | %a | a hét napja, rövidítve | | ||
+ | | %A | a hét napja, kiírva | | ||
+ | | %b | a hónap neve, rövidítve | | ||
+ | | %B | a hónap neve, kiírva | | ||
+ | | %c | az alapértelmezett dátumformátum | | ||
+ | | %d | nap, 2 számjeggyel (01 .. 31) | | ||
+ | | %H | óra, 24-órás formátumban, 2 számjeggyel (00 .. 23) | | ||
+ | | %I | óra, 12-órás formátumban, 2 számjeggyel (01 .. 12) | | ||
+ | | %j | év napja, 3 számjegy (001 .. 366) | | ||
+ | | %m | hónap, számmal (01 .. 12) /van kitöltő szóköz/ | | ||
+ | | %M | perc, 2 számjegy | | ||
+ | | %p | "am" vagy "pm", az adott időpont délelőtt, vagy délután | | ||
+ | | %S | másodperc, 2 számjegy | | ||
+ | | %U | az aktuális év hányadik hetében járunk, a hét vasárnappal kezdődik, vagyis az "01" hét január első vasárnapján kezdődik. /Az első hét előtti napokat "00" hétnek jelzi/ | | ||
+ | | %w | hét napja számmal, a vasárnap a 0 | | ||
+ | | %W | év hete, az év első hétfőjén kezdődik az "01" hét | | ||
+ | | %x | alapértelmezett dátumformátum idő nélkül | | ||
+ | | %X | alapértelmezett időpontformátum dátum nélkül | | ||
+ | | %y | év 2 számjeggyel (00 .. 99) | | ||
+ | | %Y | év, évszázaddal együtt | | ||
+ | | %Z | időzóna neve, 3 betű | | ||
+ | | %% | a "%" karakter | | ||
+ | |||
+ | |||
+ | ==== Példa ==== | ||
+ | |||
+ | time_t datum = time(NULL); | ||
+ | strftime(sz, sizeof(sz), "%c", &datum); | ||
+ | printf("%s\n", sz); | ||
+ | |||
+ | |||
+ | ===== Fogalmak ===== | ||
+ | |||
+ | |||
+ | ==== Függvény ==== | ||
+ | |||
+ | |||
+ | A C nyelvben ha utasításról beszélek, gyakran azt mondjuk helyette, hogy függvény. Ez azért van | ||
+ | mert minden utasítás valójában egy függvényként van megvalósítva. | ||
+ | |||
+ | ==== Kimeneti eszköz ==== | ||
+ | |||
+ | Mivel számítógépről beszélünk, ezért ez monitor, nyomtató vagy más ehhez hasonló eszköz. | ||
+ | |||
+ | ==== Standard Output ==== | ||
+ | |||
+ | A Standard Output az alapértelmezett kimeneti eszközt jelenti. Szokásos módon ez a monitor | ||
+ | képernyője. Tehát ha azt mondom „A Standard Outputra írok”, ez azt jelenti, hogy a képernyőre | ||
+ | írok. | ||
+ | |||
+ | ==== Standard Input ==== | ||
+ | |||
+ | A Standard Input az alapértelmezett bemeneti eszköz. Szokásos módon ez a billentyűzet. | ||
+ | A Standard Inputról olvasás így billentyűzetről bevitt adatokat jelenti. | ||
+ | |||
+ | A Standard Outputot és a Standard Inputot együtt röviden stdio néven rövidítjük. | ||
+ | |||
+ | ==== Paraméter ==== | ||
+ | |||
+ | |||
+ | Amikor írunk egy „saját” függvényt, előfordulhat, hogy a hívó programból adatokat akarunk átadni. | ||
+ | Ezeket az adatokat a függvény neve után zárójelbe írjuk és paramétereknek nevezzük. | ||
+ | |||
+ | ==== Utasítás ==== | ||
+ | |||
+ | |||
+ | Megmondjuk a gépnek mit tegyen. Ezt úgy tesszük, hogy leírjuk a nevét. Valójában ez egy | ||
+ | függvény neve. A C nyelvben ha nincs egy utasításnak paramétere akkor is kötelező a zárójelek | ||
+ | kitétele. Minden utasítást pontosvessző (;) zár le! Létezik üres utasítás is, ami egy pontosvessző | ||
+ | önmagában. | ||
+ | |||
+ | |||
+ | ==== Előfordító ==== | ||
+ | |||
+ | A C fordító a forráskód lefordítása előtt elvégez egy ún. előfordítást. Az előfordítás az előfordítói utasításokon történik. Az előfordító utasítások „#” jellel kezdődnek. Előfordítással fordított utasítás típusok: | ||
+ | * fájlok beépítése | ||
+ | * makrók | ||
+ | * feltételes fordítás | ||
+ | |||
+ | Példák az előfordítói utasításokra: | ||
+ | #include <stdio.h> | ||
+ | #define A 3 | ||
+ | |||