Felhasználói eszközök

Eszközök a webhelyen


oktatas:programozas:c:c_nyelv

Különbségek

A kiválasztott változat és az aktuális verzió közötti különbségek a következők.

Összehasonlító nézet linkje

Előző változat mindkét oldalon Előző változat
Előző változat
oktatas:programozas:c:c_nyelv [2019/01/05 22:08]
oktatas:programozas:c:c_nyelv [2020/05/24 19:15] (aktuális)
admin [Mátrix]
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 1970­es é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á.
 +
 +===== Gyakorlat 001 =====
 +
 +  * Válaszoljon a következő kérdésekre:​
 +    * Ki kezdte fejleszteni a C nyelvet?
 +    * Milyen operációs rendszerre tervezték a C nyelvet eredetileg?
 +    * Milyen programozási nyelvből örökölt tulajdonságokat a C nyelv?
 +    * Mikor fogadták el a C nyelvet ANSI szabványnak?​
 +===== 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 fejállományban vagy 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|}}
 +
 +===== Megjegyzés =====
 +
 +A C nyelv lehetővé teszi egy és többsoros megjegyzés elhelyezését. ​
 +
 +
 +<code c>
 +// egy soros megjegyzés
 +</​code>​
 +
 +
 +<code c>
 +/* több
 +   soros
 +   ​megjegyzés
 +*/
 +</​code>​
 +
 +===== Gyakorlat 002 =====
 +
 +  * Írjon programot, ami kiírja a településének a nevét, és irányító számot egy újabb sorba.
 +  * Az előző programban, írja többsoros megjegyzésbe saját nevét.
 +
 +===== 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 ​  |
 +|  \%  |  Százalékjel ​ |
 +
 +===== Gyakorlat 003 =====
 +
 +  * Írjon programot, ami "Kék János"​ nevet.
 +    * A következő sorba, tabulátorral tagolva a fizetését írja ki, ami 2856000.
 +    * A program írja ki a saját (szerző) nevét is, a "​szerző:​ " szöveg után.
 +
 +
 +===== 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>​
 +
 +===== Valós típus =====
 +
 +Legnagyobb tárolható double típus:
 +<code c valos.c>
 +#include <​stdio.h>​
 +#include <​float.h>​
 +int main() {
 +    printf("​double:​ %g\n", DBL_MAX);
 +}
 +
 +</​code>​
 +
 +<code c>
 +printf("​float : %g\n", FLT_MAX);
 +</​code>​
 +
 +
 +| FLT_MAX |
 +| DBL_MAX |
 +===== Gyakorlat 004 =====
 +
 +  * Válaszoljon a következő kérdésekre:​
 +    * Mi a legnagyobb tárolható szám, ha short típust adok meg?
 +    * Mi a legnagyobb tárolható szám, ha char típust adok meg?
 +    * Mi annak az állandónak a neve, amiből kideríthető,​ mi legnagyobb tárolható int típus?
 +
 +
 +
 +
 +
 +===== Á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. escape­sorozatokat ​
 +(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 TELJESNEV­et 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>​
 +int main() {
 +    const int a = 5;
 +    printf("​%d\n",​ a);
 +}
 +</​code>​
 +
 +
 +
 +<code c konst2.c>​
 +#include <​stdio.h>​
 +#define MERET 3
 +typedef double Ttomb[MERET];​
 +int 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|}}
 +
 +A const módosító mondja meg, hogy nevesített állandót szeretnénk,​
 +létrehozni. Amikor a programozó állandót hoz létre, azt vállalja, ​
 +hogy ezt a memória területet a program tovább része alatt nem
 +szeretné megváltoztatni. ​
 +
 +===== Gyakorlat 005 =====
 +
 +  * Írjon programot, amely két állandót tartalmaz:
 +    * a programban használja a #define utasítást
 +    * az egyik szám, egy iskolában adható legkisebb osztályzatot tartalmazza
 +    * a másik szám, az iskolában adható legnagyobb osztályzatot tartalmazza
 +    * az állandók neveit válassza meg tetszőlegesen
 +
 +
 +===== 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>​
 +===== Gyakorlat 006 =====
 +
 +  * Válaszoljon a következő kérdésekre:​
 +    * 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>​
 +int 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.
 +
 +===== Gyakorlat 007 =====
 +
 +  * Válaszoljon a következő kérdésekre:​
 +    * Mire való a % operátor?
 +    * Mire való a && operátor?
 +    * Mire való a || operátor?
 +    * Mire való a ++ operátor?
 +
 +
 +
 +===== Formázott 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
 +
 +
 +A leggyakrabban használt konverziós karakterek, a d, f, c és s.
 +
 +
 +A d konverziós karaktert egész számok kiíratására használjuk. ​
 +
 +{{:​oktatas:​programozas:​c:​egsz_szam_formazasa.png?​200|}}
 +
 +Az f konverziós karaktert valós számok kiíratására használjuk. ​
 +
 +{{:​oktatas:​programozas:​c:​valos_szam_formazasa.png?​200|}}
 +
 +A c konverziós karaktert, karakterek kiíratására használjuk. ​
 +
 +{{:​oktatas:​programozas:​c:​karakter_formazasa.png?​200|}}
 +
 +Az s konverziós karaktert, karaktersorozatok,​ vagyis szövegek kiíratására használjuk. ​
 +
 +{{:​oktatas:​programozas:​c:​szoveg_formazasa.png?​200|}}
 +
 +
 +
 +
 +
 +Kiíratás 2 tizedesjegy pontossággal:​
 +<code c main.c>
 +#include <​stdio.h>​
 +int main() {
 + double a = 31.123456;
 + printf("​%.2f\n",​ a);
 +}
 +
 +</​code>​
 +
 +Kiíratás 20 szélesen:
 +<code c main.c>
 +#include <​stdio.h>​
 +int main() {
 + double a = 31.123456;
 + printf("​%20.2f\n",​ a);
 +
 +}
 +
 +</​code>​
 +
 +Balra igazítás:
 +<code c main.c>
 +#include <​stdio.h>​
 +int main() {
 + double a = 31.123456;
 + printf("​|%-20.2f|\n",​ a);
 +}
 +
 +</​code>​
 +
 +
 +
 +
 +^  formátum karakter ​ ^  típus ​ ^  Használatra példa ​ ^
 +|  ld  | long |
 +|  d  | int, short, char |
 +|  f  | float |
 +|  c  | char, int |
 +|  Lg  | long double |
 +|  <​nowiki>​%</​nowiki> ​  | százalék jelet ír a képernyőre | <​nowiki>​printf("​%%\n"​);</​nowiki> ​ |
 +
 +===== Gyakorlat 008 =====
 +
 +  * Válaszoljon a következő kérdésekre:​
 +    * Milyen formátum karakter szükséges egy egész érték kiíratásához?​
 +    * Milyen formátum karakter szükséges egy valós érték kiíratásához?​
 +    * Milyen formátum karakter szükséges egy karakter kiíratásához?​
 +    * Milyen formátum karakter szükséges egy karaktersorozat kiíratásához?​
 +
 +
 +===== 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>​
 +int main() {
 + printf("​%f\n",​ M_PI);
 +}
 +</​code>​
 +
 +==== Szinusz ====
 +
 +A trigonometriai függvények szög helyett radiánban várják az értéküket. ​
 +A feladatokban általában szögben adják meg az értékeket,​ amit át kell számolnunk
 +radiánban. ​
 +
 +
 +Ha például van 30 fokunk, akkor meg kell szorozni PI értékével, ​
 +majd az eredményt el kell osztani 180-nal. ​
 +
 +<code c main.c>
 +#include <​stdio.h>​
 +#include <​math.h>​
 +
 +int main() {
 + printf("​%f\n",​ sin(30 * M_PI / 180));
 +
 +}
 +
 +</​code>​
 +Készítsük el példaprogramot,​ majd fordítsuk és futtassuk. ​
 +
 +A matematikai függvények használata esetén szükség van egy új kapcsolóra,​ a -l.
 +A -l értéke egy "​m"​ betű, utalva a math-ra. Egy matematikai függvény használata esetén,
 +tehát így fordítunk egy C forráskódot:​
 +
 +<code bash>
 +cc -l m -o main main.c
 +</​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); ​         // Lelfele 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);
 +
 +<code c main.c>
 +#include <​stdio.h>​
 +#include <​math.h>​
 +int main() {
 + printf("​%f\n",​ sqrt(9.5));
 +}
 +</​code>​
 +
 +
 +<code c trig.c>
 +#include <​stdio.h>​
 +#include <​math.h>​
 +int main() {
 +        printf("​%f\n",​ pow(2,8));
 +}
 +</​code>​
 +
 +
 +==== Az abszolút érték egész számokkal ====
 +
 +Érdekesség,​ hogy az abs() függvény másik programozói könyvtárban van, a stdlib.h könyvtárban.
 +
 +Szintaxis:
 +<​code>​
 +int abs(int) ​     //Abszolút érték
 +</​code>​
 +
 +Használata,​ például:
 +<code c main.c>
 +#include <​stdlib.h>​
 +
 +int main() {
 +    int szam = -4;
 +    int ered = abs(szam);
 +}
 +</​code>​
 +
 +
 +Ha fordításnál kihagyjuk az stdlib.h programozói könyvtárat,​
 +akkor figyelmeztetést kapunk:
 +<​code>​
 +warning: implicit declaration of function '​abs'​ [-Wimplicit-function-declaration]
 +  int ered = abs(szam);
 +</​code>​
 +
 +
 +
 +Az újabb GCC 5-s verzióban az alapértelmezetten C szabvány a C11. 
 +Ez megköveteli,​ hogy szerepeltessük az #include fordítási direktívával,​
 +a stdlib.h könyvtárat.
 +
 +
 +A fordító rávehető, hogy C89/C90 szabványt használjon,​ ami nem találja ​
 +hibának, ha nem fordítjuk az stdlib.h könyvtárat hozzá. ​
 +
 +  cc -std=gnu89 -o main main.c
 +
 +Az alapértelmezett C11 szabványt nem kell megadni, de megadható:
 +  cc -std=gnu11 -o main main.c
 +
 +
 +==== Egész osztás ====
 +
 +Az stdlib.h fejállományban van egy div() függvény, amellyel egész osztást ​
 +végezhetünk. A div() függvény egy div_t struktúrát ad vissza.
 +
 +<code c oszt.c>
 +#include <​stdio.h>​
 +#include <​stdlib.h>​
 +
 +int main() {
 +    div_t a = div(5, 2);
 +    printf("​%d\n",​ a);
 +}
 +
 +</​code>​
 +
 +A struktúra így néz ki:
 +<code c>
 +typedef struct
 +  {
 +    int quot;
 +    int rem;
 +  } div_t;
 +</​code>​
 +
 +
 +Mivel az eredményt struktúrában kapjuk, kiírathatjuk külön az
 +osztás eredményét,​ és a maradékot is:
 +
 +<code c oszt.c>
 +#include <​stdio.h>​
 +#include <​stdlib.h>​
 +
 +int main() {
 +    div_t a = div(5, 2);
 +    printf("​%d\n",​ a.quot);
 +    printf("​%d\n",​ a.rem);
 +}
 +
 +</​code>​
 +
 +
 +
 +===== Gyakorlat 009 =====
 +
 +  * Válaszoljon a következő kérdésekre:​
 +    * Mi a 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 ====
 +Egy számítógépen nem könnyű valódi véletlen számot generálni, mivel
 +minden folyamat jól meghatározott algoritmusok mentén fut.
 +A C nyelvben az stdlib.h fejállományban (programozói könyvtár),​
 +van definiálva két függvény, ami véletlen szám generálást,​ segíti.
 +
 +A következő táblázatban ezeket látjuk:
 +
 +
 +| int rand(void) | Véletlen szám generálás |
 +| void srand(unsigned int) | A véletlen szám generálás előkészítése |
 +
 +A két függvény az ANSI szabvány része.
 +
 +A rand() függvény 0 és egy nagy egész szám között generál véletlen számot.
 +A nagy egész szám a stdlib.h fejállományban van definiálva,​ neve **RAND_MAX**,​ ami
 +egy állandó. Ez tartalmazza a legnagyobb generálható egész számot.
 +64 bites Debian GNU/Linux 10 verzióban ez: **2147483367**.
 +
 +Általában nem ilyen számra van szükség van szükség, helyette valamilyen
 +adott tartományban van véletlen számra szükségünk.
 +
 +Ezért a kapott véletlen számon, elvégzünk egy egész osztást, és
 +annak maradékát vesszük figyelembe. Ha például 0 és 3 közötti ​
 +számra van szükségünk (ebbe bele értve a 0 és a 3-t is, akkor,
 +4-gyel osztunk. A kapott maradék 0, 1, 2 vagy 3 lesz. 
 +Ez lesz a véletlen számunk. ​
 +
 +Ha 1, 2, 3 és 4-s számok közül szeretnénk véletlenszerűen számokat ​
 +kapni, akkor az előző eredményhez adjunk hozzá 1-t. A véletlen szám
 +generálása,​ ekkor így néz ki:
 +<code c>
 +int vel = rand() % 4 + 1;
 +</​code>​
 +
 +Az srand() függvényre azért van szükségünk,​ mert nélküle mindig ​
 +ugyanazt a véletlen számot kapjuk. Paraméterként egy time()
 +függvény szokás futtatni NULL paraméterrel:​
 +<code c>
 +srand(time(NULL));​
 +int vel1 = rand() % 4 + 1;
 +int vel2 = rand() % 4 + 1;
 +</​code>​
 +
 +A time() függény a time.h fejállományban található. ​
 +
 +==== Maximum kiíratása ====
 +Írjunk egy programot, ami kiírja a legnagyobb generálható egész számot.
 +
 +<code c maxrand.c>​
 +#include <​stdio.h>​
 +#include <​stdlib.h>​
 +
 +int main() {
 +    printf("​%d\n",​ RAND_MAX);
 +}
 +</​code>​
 +
 +Fordítás és futtatás:
 +<code bash>
 +cc -o maxrand maxrand.c
 +./maxrand
 +</​code>​
 +
 +==== 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>​
 +int 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 veletlen(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",​ veletlen(6));​
 +}
 +</​code>​
 +
 +===== Gyakorlat 010 =====
 +
 +  * Válaszoljon a következő kérdésekre:​
 +    * Milyen fejállományban van a rand() függvény?
 +    * Milyen fejállományban található a time() függvény?
 +    * Milyen fejállományban található a RAND_MAX állandó?
 +    * Milyen fejállományban található a srand() függvény?
 +  * Írjon programot, amely kockadobást szimulál.
 +    * Mentés: kocka.c
 +  * Írjon programot, amely pókerhez 5 kockadobást szimulál.
 +    * Mentés: poker.c
 +
 +
 +
 +
 +===== Konverzió =====
 +==== Típusátalakítások ====
 +
 +Egy int típusú változó értéke gond nélkül áttehető egy short típusú változóba,​ amíg az elfér a
 +a short típusban. ​
 +<code c>
 +int a = 35;
 +short b = a;
 +</​code>​
 +
 +A short típusban a legnagyobb tárolható szám: 32767. Mi történik, akkor, ha 
 +32768 számot tesszük "​a"​ változóba,​ ami int típusú? ​
 +
 +<code c>
 +int a = 32768;
 +short b = a;
 +</​code>​
 +
 +Az eredeti szám ilyenkor nem marad meg, értékvesztés történik.
 +
 +Ha valós típusú változó értékét tesszük egész típusú változóba,​
 +akkor a törtrészek elvesznek, de a típusátalakítás működik:
 +
 +<code c>
 +double a = 35.123;
 +int b = a;
 +</​code>​
 +
 +==== Karaktersorozatok és számok közötti konverziók ====
 +
 +A függvények az stdlib.h programozói könyvtárban találhatók.
 +
 +<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á ​ ====
 +
 +A következő példában egy s változót hozunk létre,
 +amelyben 2 karakter szeretnénk tárolni. ​
 +A C nyelvben nincs karaktersorozat (string) számára típus.
 +Ezért egy karakter tömböt fogunk használni. A char s[3],
 +egy tömb amiben karaktereket tárolhatunk,​ összesen 3 darabot.
 +
 +Mi csak két karakter szeretnénk tárolni "​15",​ de a
 +karaktersorozatot lezáró \0 érték számára is helyet
 +kell foglalni, ezért 3 byte számára foglalunk helyet.
 +
 +
 +<code c>
 +char s[3];
 +strcpy(s, "​15"​);​
 +int a = atoi(s);
 +</​code>​
 +
 +Az **atoi()** függvény a **stdlib.h** programozói könyvtárból érhető el.
 +Az **strcpy()** függvény a **string.h** programozói könyvtárból érhető el. 
 +
 +A helyfoglalást,​ néha a malloc() függvénnyel szokták megoldani,
 +amelynek a használata kicsit összetettebb,​ de az eredmény egyenértékű
 +a fenti megoldással:​
 +
 +<code c>
 +char *s = (char*) malloc(5 * sizeof(char));​
 +strcpy(s, "​15"​);​
 +int a = atoi(s);
 +</​code>​
 +
 +A (char*) típusátalakítás jelent. A malloc() a típusfoglalást után
 +void típust ad vissza, de nekünk char* típusra van szükség. ​
 +
 +Ha azt írom char s; akkor egyetlen karakter akarok tárlni az s változóban.
 +Ha azt írom char *s; akkor egy karaktersorozatra (string) mutató értéket
 +szeretnék tárolni s-ben.
 +
 +
 +==== 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>​
 +===== Gyakorlat 011 =====
 +
 +  * Válaszoljon a következő kérdésekre:​
 +    * Milyen függvénnyel lehet átkonvertálni egy karaktersorozatot (string), egész számmá?
 +
 +
 +===== Bevitel =====
 +
 +==== Szám bekérése ====
 +
 +Bekéréshez használhatjuk a scanf() függvényt,​ ami a stdio.h fejállományban van leírva.
 +A scanf() a printf() függvényhez hasonlóan használható.
 +
 +^  Formátumkarakterek ​ ^^
 +^  Karakter ​ ^  mikor használható ​ ^
 +|  %d  | egész szám bekérése ​ |
 +|  %f  | valós szám bekérése ​ |
 +|  %lf  | valós szám bekérése double típusú változóba ​ |
 +|  %c  | karakter bekérése ​ |
 +|  %s  | egy szó bekérése ​ |
 +
 +
 +A scanf() függvénynek minimum két paramétere van. Az első a formátumstring,​ utána pedig
 +annyi változó, amennyi a formátumstringben megadtunk, vesszővel tagolva. ​
 +A formtáumstringbe egy változó leírását a "​%"​ karakterrel kezdjük, és egy vagy két
 +formátumkarakterrel fejezzük be. Egy egész szám bekérése például:
 +  scanf("​%d",​ &a);
 +
 +
 +
 +<code c prog.c>
 +#include <​stdio.h>​
 +
 +int main() {
 + int a;
 + printf("​Szam:​ ");
 + scanf("​%d",​ &a);
 + printf("​Ezt írtad: %d\n", a);
 +}
 +
 +</​code>​
 +
 +Ebben a példában egyetlen egész számot kérünk be az "​a"​ változóba. ​
 +Vegyük észre az "​a"​ változó előtt a "&"​ karaktert. Erre azért van szükség, mert
 +a második paraméter nem a változó neve, hanem annak címe kell legyen. ​
 +
 +Ebből következik,​ hogy egy változó címét úgy kapjuk meg, hogy "&​valtozonev"​ formát
 +használom. ​
 +
 +
 +Több változó is bekérhető egyszerre.
 +A következő példában egyszerre két változót kérünk be.
 +<code c prog.c>
 +#include <​stdio.h>​
 +
 +int main() {
 + int szam1, szam2;
 + printf("​Két szám: ");
 + scanf("​%d %d", &szam1, &​szam2);​
 + printf("​Ezeket írtad: %d %d\n", szam1, szam2);
 +}
 +
 +</​code>​
 +
 +A program végrehajtásakor,​ ilyenkor az első szám után 1 vagy több szóközt,
 +tabulátor vagy sortörést (whitespace karakterek) írok. az első bekért szám
 +után egy Enter is írható, így a második számot a következő sorba írom be.
 +
 +==== Valós szám bekérése ====
 +Ha egy float típusú változóba kérünk be számot, a formátumkarakter "​f"​ karakter:
 +<code c prog.c>
 +#include <​stdio.h>​
 +
 +int main() {
 +    float szam1;
 +    printf("​Valós szám: ");
 +    scanf("​%f",​ &​szam1);​
 +    printf("​Ezt írtad: %f\n", szam1);
 +}
 +
 +</​code>​
 +
 +Dupla pontos szám bekérésénél a formátumkarakterből kettő kell: "​lf"​.
 +
 +
 +<code c prog.c>
 +#include <​stdio.h>​
 +
 +int main() {
 +    double szam1;
 +    printf("​Valós szám: ");
 +    scanf("​%lf",​ &​szam1);​
 +    printf("​Ezt írtad: %f\n", szam1);
 +
 +}
 +
 +</​code>​
 +
 +==== Karakter bekérése ====
 +
 +Egy karakter bekérése esetén a formátumkarakter egy "​c"​ betű.
 +
 +<code c prog.c>
 +#include <​stdio.h>​
 +
 +int main() {
 +    char ch;
 +    printf("​Karakter:​ ");
 +    scanf("​%c",​ &ch);
 +    printf("​Ezt írtad: %c\n", ch);
 +}
 +
 +</​code>​
 +
 +==== Szó bekérése ====
 +
 +A scanf() függvény alkalmas karaktersorozat beolvasására.
 +A scanf() azonban a whitespace karaktereket szeparátornak ​
 +tekinti, ezért csak szavakat képes beolvasni.
 +
 +
 +Az alábbi program képes beolvasni egy nevet, amiben nincs szóköz vagy
 +tabulátor.
 +
 +<code c prog.c>
 +#include <​stdio.h>​
 +#include <​stdlib.h>​
 +int main() {
 + char *nev;
 + nev = (char*) malloc(100 * sizeof(char));​
 + printf("​Név:​ ");
 + scanf("​%s",​ nev);
 + printf("​Ezt írtad: %s\n", nev);
 +}
 +
 +</​code>​
 +
 +Vegyük észre, hogy a scanf() függvény, második paraméterében,​ a nev változó neve elé
 +nem tettünk "&"​ karaktert, pedig azt írtuk, hogy oda cím kell. Azért nem szükséges,​
 +mert a nev változót eleve mutató típusnak deklaráltam,​ ez a "​*"​ karakter jelzi 
 +a kódban: ​
 +
 +  char *nev;
 +
 +Ez pedig azt jelenti, hogy eleve a változó címével dolgozunk. ​
 +
 +A char nev[30] egy karaktertömb,​ amiben maximum 30 karakter tárolható. ​
 +Így is használható,​ így nem szükséges külön malloc() vagy hasonló függvénnyel
 +helyet foglalni a nev változónak:​
 +  char nev[30]
 +
 +Egy konkrét példa a használatra:​
 +<code c prog.c>
 +#include <​stdio.h>​
 +
 +int main() {
 +    char nev[30];
 +    printf("​Keresztnév:​ ");
 +    scanf("​%s",​ nev);
 +    printf("​Ezt írtad: %s\n", nev);
 +}
 +
 +</​code>​
 +
 +A bekérésnél itt sem kell a "&"​ karakter.
 +
 +
 +==== Mondat bekérése ====
 +
 +Az fgets() függvény az állományok olvasására használható és az stdio.h
 +fejállományban található. Az stdio.h fejlécállományban ​
 +deklarálva van egy stdin nevű fájl is, amely billentyűzetet szimbolizálja. ​
 +Így egy valódi állomány helyett a billentyűzetet is olvashatjuk az fgets()
 +függvénnyel.
 +
 +<code c prog.c>
 +#include <​stdio.h>​
 +
 +int 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ést törölni,​ ami az Enter hatására kerül az
 +adatszerkezetbe,​ 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és-e.
 +Ha igen,​ akkor lecseréljük karaktersorozat végét
 +jelölő null karakterre.
 +
 +
 +
 +<code c prog.c>
 +#include <​stdio.h>​
 +#include <​stdlib.h>​
 +int main() {
 + char *nev;
 + nev = (char*) malloc(100 * sizeof(char));​
 + printf("​Név:​ ");
 + fgets(nev, 100, stdin);
 + printf("​Ezt írtad: %s\n", nev);
 +}
 +
 +</​code>​
 +
 +A Karaktersorozat fejezetben még lesz szó, azok bekéréséről.
 +
 +===== Gyakorlat 012 =====
 +
 +  * Válaszoljon a következő kérdésekre:​
 +    * Milyen fejállományban található a scanf() függvény?
 +    * Mire használhatjuk a scanf() függvényt?​
 +    * Melyik függvénnyel lehet mondatokat bekérni? scanf() vagy fgets()
 +
 +===== Szelekció =====
 +
 +==== if ====
 +
 +Bizonyos utasítások végrehajtását feltételhez köthetjük. ​
 +
 +
 +<code c>
 +#include <​stdio.h>​
 +
 +int main() {
 + int a = 5;
 + if(a > 0)
 + printf("​Pozitív szám\n"​);​
 +}
 +
 +</​code>​
 +
 +
 +==== if-else ====
 +
 +<code c Program01.c>​
 +#include <​stdio.h>​
 +
 +int 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>​
 +
 +int 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.
 +
 +===== Gyakorlat 013 =====
 +
 +  * Írjon programot, amely -2 és 2 között generál egy számot.
 +    * A lehetséges számok -2, -1, 0, 1, 2
 +    * Ha szám nagyobb mint 0, írja a képernyőre,​ hogy a következőt:​ "​Pozitív"​
 +  * Az előző programot, egészítse ki:
 +    * 0 vagy negatív szám esetén írja a képernyőre:​ "Nulla vagy negatív"​
 +  * Az előző programot, írja át:
 +    * 0-nál nagyobb szám esetén kiírja: "​Pozitív"​
 +    * 0 esetén "​Nulla"​
 +    * 0-nál kisebb szám esetén: "​Negatív"​
 +
 +
 +
 +
 +===== Iteráció =====
 +
 +==== for ====
 +
 +A for() utasítás, egy növekményes ciklusok számára megvalósított eszköz.
 +Három paramétere van. A paramétereket ";"​ karakterrel tagoljuk.
 +Az első paraméter a kezdőérték. A második paraméter a feltétel, amely
 +tartalmazza,​ meddig ismétlődjön a ciklus. Az utolsó paraméter a növekmény.
 +Itt növeljük a i változó tartalmát. ​
 +
 +<​code>​
 +for(kezdőérték ; feltétel ; növekmény ) {
 +    //ciklus törzse
 +}
 +</​code>​
 +
 +A ciklus törzsébe írjuk azokat az utasításokat,​ amelyek szeretnénk
 +minden egyes iterációban végrehajtani. A ciklus törzsét "​{"​ karakterrel
 +kezdjük, és "​}"​ karakterrel zárjuk. Ha csak egyetlen utasításunk van,
 +nem kötelező a kapcsos zárójelek használata. A kód átláthatósága érdekében,​
 +azonban ajánlott használni mindig.
 +
 +<code c>
 +#include <​stdio.h>​
 +
 +int main() {
 + int i;
 + for(i=0; i<​10;​i++)
 + printf("​%d\n",​ i);
 +}
 +
 +</​code>​
 +
 +
 +==== while ====
 +
 +A while() ciklusnak egyetlen paramétere van, a feltétel.
 +Ha feltétel igaz, a ciklus törzsében található utasítások ​
 +végrehajtódnak. Ha hamis, a ciklus véget ér.
 +
 +<code c>
 +#include <​stdio.h>​
 +
 +int main() {
 + int i=0;
 + while(i<​10) {
 + printf("​%d\n",​ i);
 + i++;
 + }
 +}
 +
 +</​code>​
 +
 +==== do-while ====
 +
 +A do-while, egy hátul tesztelő ciklus. A ciklus törzsét először végrehajtja,​
 +és csak ez után vizsgálja meg, hogy a feltétel igaz vagy hamis.
 +Ha feltétel igaz, a ciklus törzsét újra végrehajtja. Ha hamis,
 +a ciklus véget ér.
 +
 +<code c>
 +#include <​stdio.h>​
 +
 +int main(){
 + int i=0;
 + do {
 + printf("​%d\n",​ i);
 + i++;
 + }while(i<​10);​
 +}
 +
 +</​code>​
 +
 +
 +===== Gyakorlat 014 =====
 +
 +  * Írjon programot, amely véletlen számokat generál.
 +    * Mentés: nulig.c
 +    * A program írja ki a generált véletlen számot.
 +    * Ha a szám nem 0, akkor generáljon újabb számot.
 +
 +
 +===== Ö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>​
 +
 +int 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.
 +===== Gyakorlat 015 =====
 +
 +  * Írjon programot, amelyben az év hónapjait egy enum szerkezetben tárolja.
 +    * Mentés: havi.c
 +    * Írassa ki a hónapokat az 5-dik hónapot.
 +
 +
 +
 +
 +===== Karaktersorozat =====
 +
 +==== Tárolás ====
 +
 +A karaktersorozat (angolul string) típus nem létezik a C nyelvben. ​
 +Ha karaktersorozatot 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>​
 +
 +
 +A példa kedvéért legyen a "​Hello"​ szöveg eltárolva a fe1011 memóriacímtől kezdve. ​
 +Az alábbi táblázat mutatja, mit tartalmaz a memória.
 +
 +^ 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 karaktersorozat végére tenni, mert azt
 +a fordító automatikusan megteszi. Egy ilyen mutató létrehozása ​
 +a következő módon valósítható meg:
 +
 +
 +<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ényből egyet szoktunk használni:
 +  * malloc()
 +  * calloc()
 +Mindkettő 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ípust 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>​
 +
 +int 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 rendszeren. Erre a sizeof() ​
 +operátort használhatjuk. Az általa visszaadott értéket
 +szorozzuk be 30-al:
 +
 +
 +<code c>
 +#include <​stdlib.h>​
 +int main() {
 +    char *s;
 +    s = (char*) malloc(30 * sizeof(char));​
 +}
 +
 +</​code>​
 +
 +Ha szeretnénk megváltoztatni a lefoglalt hely méretét az következő utasítással tehetjük meg:
 +  * realloc()
 +
 +A lefoglalt hely felszabadítása: ​
 +  * free()
 +
 +
 +Példa:
 +<code c prog.c>
 +#include <​stdio.h>​
 +#include <​stdlib.h>​
 +#include <​string.h>​
 +
 +int main() {
 +    char *nev;
 +    nev = (char*) malloc(10* sizeof(char));​
 +    strcpy(nev, "​Lajos"​);​
 +    printf("​%s\n",​ nev);
 +
 +    nev = (char*) realloc(nev,​ 30 * sizeof(char));​
 +    strcpy(nev, "​Ferdinándházi Lajos"​);​
 +    printf("​%s\n",​ nev);
 +
 +    free(nev);
 +}
 +
 +</​code>​
 +
 +==== A változó használata ====
 +
 +Most már használhatjuk a "​s"​ változót. A C nyelvben egy
 +karaktersorozatot nem adhatunk meg egy egyenlőség jel jobboldalán.
 +Ha egy változóba 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>​
 +int main() {
 +    char *gyumolcs;
 +    gyumolcs = (char*) malloc(30 * sizeof(char));​
 +    strcpy(gyumolcs,​ "​szilva"​);​
 +}
 +
 +</​code>​
 +
 +Ha tömböt használunk,​ akkor nem szükséges külön helyfoglaló utasítást használni,
 +például a malloc(), mivel a eleve helyfoglalás történik. Legyen a példa kedvéért ​
 +egy "​nev"​ nevű tömb, amiben 30 karakternek foglalok helyet:
 +  char nev[30];
 +Itt lefoglaltam a helyet 30 karakter számára, nem kell külön malloc() függvény.
 +
 +
 +A használatra példa:
 +<code c>
 +#include <​string.h>​
 +int main() {
 +    char gyumolcs[30]; ​   ​
 +    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>​
 +int main() {
 +    char *gyumolcs;
 +    gyumolcs = (char*) malloc(30 * sizeof(char));​
 +    strcpy(gyumolcs,​ "​szilva"​);​
 +    printf("​%s\n",​ gyumolcs);
 +}
 +
 +</​code>​
 +
 +
 +==== Bekérés ====
 +
 +A karaktersorozatok bekéréséről már volt szó a Bekérés című fejezetben. ​
 +Itt most átismételjük a tanultakat.
 +
 +<code c bekerstr.c>​
 +#include <​stdio.h>​
 +#include <​stdlib>​
 +
 +int 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 szeretnénk beolvasni a scanf() függvénnyel,​ akkor
 +sosem magát a változó nevét kell megadni, hanem annak címét. 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. 
 +
 +Mondatok beolvasását az fgets() függvénnyel valósítjuk meg.
 +Rendelkezésre áll a gets() függvény is, de használata ​
 +biztonsági kockázatot jelent. ​
 +
 +Példa az fgets() használatára.
 +
 +<code c mondat.c>​
 +#include <​stdio.h>​
 +#include <​stdlib.h>​
 +
 +int main() {
 + char *mondat;
 + mondat = (char*) malloc(30 * sizeof(char));​
 + printf("​Mondat:​ ");
 + fgets(mondat,​ 30, stdin);
 + printf("​Ezt írtad: %s\n", mondat);
 +}
 +
 +</​code>​
 +
 +Az fgets() valójában fájlok olvasására lett kitalálva,
 +de van egy speciális fájl, aminek a neve stdin.
 +Ha ezt a fájlt olvassuk, akkor billentyűzet leütéseit
 +kapjuk meg.
 +
 +A nem ajánlott gets() függvényre példa:
 +<code c noget.c>
 +#include <​stdio.h>​
 +#include <​stdlib.h>​
 +
 +int main() {
 + char *mondat;
 + mondat = (char*) malloc(30 * sizeof(char));​
 + printf("​Mondat:​ ");
 + gets(mondat);​
 + printf("​Ezt írtad: %s\n", mondat);
 +}
 +
 +</​code>​
 +
 +==== 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>​
 +int 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>​
 +int 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>​
 +int 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>​
 +int 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]]
 +
 +
 +==== Üres vagy nem üres ====
 +
 +<code c prog.c>
 +#include <​stdio.h>​
 +
 +int main () {
 +    char szoveg[30];
 +    if(szoveg[0]) {
 +        printf("​Üres\n"​);​
 +    }
 +}
 +
 +</​code>​
 +
 +
 +<code c prog.c>
 +#include <​stdio.h>​
 +#include <​string.h>​
 +
 +int main () {
 +    char szoveg[30];
 +    if(szoveg && szoveg[0]) {
 +        printf("​Üres\n"​);​
 +    }
 +}
 +
 +</​code>​
 +
 +
 +
 +<code c prog.c>
 +#include <​stdio.h>​
 +#include <​string.h>​
 +
 +int main () {
 +    char szoveg[30];
 +    strcpy(szoveg,​ ""​);​
 +    if(szoveg[0] == '​\0'​) {
 +        printf("​Üres\n"​);​
 +    }
 +}
 +
 +</​code>​
 +
 +==== Összefűzés ====
 +
 +<code c prog.c>
 +#include <​stdio.h>​
 +#include <​string.h>​
 +
 +int main () {
 +    char szoveg1[30];​
 +    char szoveg2[30];​
 +
 +    strcpy(szoveg1,​ "​alma"​);​
 +    strcpy(szoveg2,​ "​körte"​);​
 +    strcat(szoveg1,​ szoveg2); ​
 +    printf("​Szöveg:​ %s\n", szoveg1);
 +
 +}
 +
 +</​code>​
 +
 +==== Összehasonlítás ====
 +
 +<code c prog.c>
 +#include <​stdio.h>​
 +#include <​string.h>​
 +
 +int main () {
 +    char szoveg[30];
 +    strcpy(szoveg,​ "​alma"​);​
 +
 +    if(!strcmp(szoveg,​ "​alma"​)) {
 +        printf("​Egyezik\n"​);​
 +    }else {
 +        printf("​Nem egyezik\n"​);​
 +    }  ​
 +}
 +
 +</​code>​
 +
 +===== Gyakorlat 016 =====
 +
 +  * Írjon programot, amelyben bekéri egy dolgozó nevét, települését és fizetését.
 +    * Mentés: dole.c
 +
 +
 +
 +===== 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>​
 +int 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;​
 +}
 +
 +int main() {
 + Ttomb tomb;
 +
 + tomb[0] = 5;
 + tomb[5] = 3;
 +
 + kiir(tomb);​
 + printf("​%d\n",​ tomb[0]);
 +}
 +</​code>​
 +
 +==== Tömb bejárása ====
 +
 +<code c tomb.c>
 +#include <​stdio.h>​
 +int main() {
 + int tomb[] = {3, 8, 5, 6, 2, 9 };
 +    int i;
 +    for(i=0; i<6; i++) {
 +    printf("​%d\n",​ tomb[i]);
 +    }
 +}
 +</​code>​
 +
 +==== Tömb mérete ====
 +
 +<code c>
 +int tomb[] = {3, 8, 5, 6, 2, 9 };
 +int n = sizeof tomb / sizeof tomb[0];
 +</​code>​
 +Vagy:
 +
 +<code c>
 +int tomb[] = {3, 8, 5, 6, 2, 9 };
 +size_t meret = sizeof(tomb) / sizeof(tomb[0]);​
 +</​code>​
 +
 +
 +Vagy:
 +<code c>
 +int tomb[] = {3, 8, 5, 6, 2, 9 };
 +int n = sizeof tomb / sizeof *tomb;
 +</​code>​
 +
 +
 +Komplett példa:
 +<code c tomb.c>
 +#include <​stdio.h>​
 +int main() {
 + int tomb[] = {3, 8, 5, 6, 2, 9 };
 +    int n = sizeof tomb / sizeof *tomb;
 +    int i;
 +    for(i=0; i<n; i++) {
 +    printf("​%d\n",​ tomb[i]);
 +    }
 +}
 +</​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>​
 +
 +
 +{{:​oktatas:​programozas:​c:​c_ket_dimenzios_tomb.png?​400|}}
 +
 +=== 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;
 + }
 +}
 +
 +int 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.
 +
 +===== Gyakorlat 017 =====
 +
 +  * Írjon programot, amelyben valós számokat tárol. ​
 +    * Mentés: valostomb.c
 +
 +
 +
 +===== 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;
 +}
 +
 +int 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>​
 +int 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>​
 +int 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>​
 +
 +int 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>​
 +
 +int 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>​
 +int 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>​
 +int 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>​
 +int 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>​
 +int 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>​
 +int 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;
 +}
 +
 +int 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
 +