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.
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á.
#include <stdio.h> int main() { printf("Helló Világ\n"); }
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.
A C nyelv lehetővé teszi egy és többsoros megjegyzés elhelyezését.
// egy soros megjegyzés
/* több
soros
megjegyzés
*/
Ha leírok egy karaktersorozatot, például alma, a printf() függvény a képernyőre írja:
#include <stdio.h> int main() { printf("alma"); }
#include <stdio.h> int main() { puts("alma"); }
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.
printf("%d", 35);
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.
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 "\t", amely egy tabulátorjelet küld a képernyőre.
Az ilyen karaktereket hívjuk Escape szekvenciáknak.
Mivel az idézőjelnek (") 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 |
\" | Idézőjel |
\% | Százalékjel |
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;
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:
#include <stdio.h> #include <limits.h> int main() { printf("%d\n", INT_MAX); }
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.
Lehet szám, karakter, karaktersorozat, stb.
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
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
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.
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:
#define azonosító helyettesítő–szöveg
Egy konkrét példa:
#define MAX 5 #define FELSOHATAR 100 #define ALSOHATAR 50
Egy nem módosítható objektumot deklarál. Az azonosítót nem használhatjuk egy egyenlőségjel baloldalán.
const int a = 5;
#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]); }
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.
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.
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.
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.
int also, felso, lepes; char c, sor[1000];
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
int also; int felso; int lepes; char c; char sor[1000];
A változók a deklaráció során kezdeti értéket is kaphatnak:
int i = 0; char esc = '\\'; int hatar = MAXSOR+1; float eps = 1.0e-5
Bármely változó deklarációjában alkalmazható a const minősítő. Pl.:
const double e = 2.71828182845905; const char uzenet [ ] = ”figyelem:”; int strlen(const char[ ]);
Kétfajta operátort különböztetünk meg:
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
+ összeadás - kivonás * szorzás / osztás % maradék képzés
Példák:
int c = 3 + 5;
int a = 3; int b = 5; int osszeg = a + b;
Maradékképzés:
int maradek = 9 % 2;
A maradékot a „maradek” nevű változóban tároljuk.
> < >= <= == Egyenlő != Nem egyenlő
Az eredményük vagy 0 (hamis) vagy 1 (igaz)
&& É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)
a = a + 1 -> a += 1 a = a - 1 -> a -= 1 a = a * 1 -> a *= 1 a = a / 1 -> a /= 1
a = a * (b + 1) -> a *= b + 1
++ --
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 ÉS |
| | bitenkénti VAGY |
^ | bitenkénti kizáró vagy |
<< | bitléptetés balra |
>> | bitléptetés jobbra |
~ | egyeskomplemens |
Csak egész számokra alkalmazhatók
000011 | nem számít mennyit jelent |
000010 | 3-at jelent, ennyivel léptetünk |
001100 | eredmény |
a = 6 | 0000 0110 | |
~a | 1111 1001 | 249 |
() | 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 |
< <= >= > | kisebb mint, kisebb vagy egyenlő, nagyobb vagy egyenlő, nagyobb mint |
== =! | egyenlő, nem egyenlő |
& | bitenkénti megengedő (inkluzív) és |
^ | kizáró (exkluzív) vagy |
| | bitenkénti vagy |
&& | és |
|| | 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:
12/2*3 = 18
A zárójel mindig módosítja a kiértékelés sorrendjét.
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:
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.
Az f konverziós karaktert valós számok kiíratására használjuk.
A c konverziós karaktert, karakterek kiíratására használjuk.
Az s konverziós karaktert, karaktersorozatok, vagyis szövegek kiíratására használjuk.
Kiíratás 2 tizedesjegy pontossággal:
Kiíratás 20 szélesen:
Balra igazítás:
formátum karakter | típus | Használatra példa |
---|---|---|
ld | long | |
d | int, short, char | |
f | float | |
c | char, int | |
Lg | long double | |
% | százalék jelet ír a képernyőre | printf("%%\n"); |
A matematikai függvények a math.h nevű fejállományban vannak.
PI értéke
M_PI 3.14159265358979323846
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.
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:
cc -l m -o main main.c
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);
Érdekesség, hogy az abs() függvény másik programozói könyvtárban van, a stdlib.h könyvtárban.
Szintaxis:
int abs(int) //Abszolút érték
Használata, például:
Ha fordításnál kihagyjuk az stdlib.h programozói könyvtárat, akkor figyelmeztetést kapunk:
warning: implicit declaration of function 'abs' [-Wimplicit-function-declaration] int ered = abs(szam);
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
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.
#include <stdio.h> #include <stdlib.h> int main() { div_t a = div(5, 2); printf("%d\n", a); }
A struktúra így néz ki:
typedef struct { int quot; int rem; } div_t;
Mivel az eredményt struktúrában kapjuk, kiírathatjuk külön az osztás eredményét, és a maradékot is:
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:
int vel = rand() % 4 + 1;
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:
srand(time(NULL)); int vel1 = rand() % 4 + 1; int vel2 = rand() % 4 + 1;
A time() függény a time.h fejállományban található.
Írjunk egy programot, ami kiírja a legnagyobb generálható egész számot.
Fordítás és futtatás:
cc -o maxrand maxrand.c ./maxrand
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.
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.
int a = 35; short b = a;
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ú?
int a = 32768; short b = a;
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:
double a = 35.123; int b = a;
A függvények az stdlib.h programozói könyvtárban találhatók.
double atof(const char*) int atoi(const char*) long atol(const char*) int ltoa(int, char*, int)
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.
char s[3]; strcpy(s, "15"); int a = atoi(s);
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:
char *s = (char*) malloc(5 * sizeof(char)); strcpy(s, "15"); int a = atoi(s);
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.
char *s = (char*) malloc(5 * sizeof(char)); strcpy(s, "15"); long a = atol(s);
Az atol() függvény a stdlib.h fejállományból érhető el.
char *s = (char*) malloc(5 * sizeof(char)); strcpy(s, "15"); float a = atof(s);
Az atof() függvény a stdlib.h fejállományból érhető el.
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);
#include <stdio.h> int main() { int a; printf("Szam: "); scanf("%d", &a); printf("Ezt írtad: %d\n", a); }
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.
#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); }
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.
Ha egy float típusú változóba kérünk be számot, a formátumkarakter „f” karakter:
#include <stdio.h> int main() { float szam1; printf("Valós szám: "); scanf("%f", &szam1); printf("Ezt írtad: %f\n", szam1); }
Dupla pontos szám bekérésénél a formátumkarakterből kettő kell: „lf”.
Egy karakter bekérése esetén a formátumkarakter egy „c” betű.
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.
#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); }
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:
#include <stdio.h> int main() { char nev[30]; printf("Keresztnév: "); scanf("%s", nev); printf("Ezt írtad: %s\n", nev); }
A bekérésnél itt sem kell a „&” karakter.
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.
#include <stdio.h> int main() { char nev[100]; printf("Név: "); fgets(nev, 100, stdin); printf("Ezt írtad: %s\n", nev); }
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:
if (s[strlen(s)-1]=='\n') s[strlen(s)-1] = '\0';
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.
#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); }
A Karaktersorozat fejezetben még lesz szó, azok bekéréséről.
Bizonyos utasítások végrehajtását feltételhez köthetjük.
#include <stdio.h> int main() { int a = 5; if(a > 0) printf("Pozitív szám\n"); }
#include <stdio.h> int main() { int a = 5; if(a > 0) printf("Pozitív szám\n"); else printf("Nulla vagy negatív\n"); }
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.
#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"); } }
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.
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.
for(kezdőérték ; feltétel ; növekmény ) { //ciklus törzse }
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.
#include <stdio.h> int main() { int i; for(i=0; i<10;i++) printf("%d\n", i); }
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.
#include <stdio.h> int main() { int i=0; while(i<10) { printf("%d\n", i); i++; } }
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.
#include <stdio.h> int main(){ int i=0; do { printf("%d\n", i); i++; }while(i<10); }
Felsorolt vagy enum típus. Az enum a felsorolt értékeket egészként tárolja.
enum {hetfo, kedd, szerda, csutortok pentek};
A hetfo 0 értékkel egyenlő, a kedd 1 értékkel, a szerda 2, stb.
#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"); }
A fenti példában deklarálunk egy a változót, amely a het napjai értéket veheti fel:
enum het a;
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:
a = hetfo;
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:
if(a==hetfo)
Az a változóval persze többet is tehetünk. Például növelhetjük az értéket:
a++
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.
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:
'\0'
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:
char *s;
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:
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:
malloc(30);
Ezzel még nincs kész. Meg kell adni, hogy melyik mutatóhoz rendeljük ezt a 30 byte-ot:
s = malloc(30);
A malloc() azonban void típust ad vissza, amit át kell alakítanunk char* típusúvá:
s = (char*) malloc(30);
Ez már egy működő helyfoglalás.
A deklarálás és a helyfoglalás együtt ezek után:
#include <stdlib.h> int main() { char *s; s = (char*) malloc(30); }
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:
#include <stdlib.h> int main() { char *s; s = (char*) malloc(30 * sizeof(char)); }
Ha szeretnénk megváltoztatni a lefoglalt hely méretét az következő utasítással tehetjük meg:
A lefoglalt hely felszabadítása:
Példa:
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:
#include <stdlib> #include <string.h> int main() { char *gyumolcs; gyumolcs = (char*) malloc(30 * sizeof(char)); strcpy(gyumolcs, "szilva"); }
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:
#include <string.h> int main() { char gyumolcs[30]; strcpy(gyumolcs, "szilva"); }
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:
#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); }
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.
#include <stdio.h> #include <stdlib> int main() { char *gyumolcs; gyumolcs = (char*) malloc(30 * sizeof(char)); scanf("%s" gyumolcs); printf("%s\n", gyumolcs); }
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.
#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); }
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:
A C nyelvben az strtok() függvényt használhatjuk egy karaktersorozat darabolására.
Szintaktikája:
#include <string.h> char *strtok( char *str1, const char *str2 );
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ó.
strcpy(str, "alma:körte:szilva:barack"); strtok(str, ":");
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:
strtok(str, ":");
Minden további hívást a NULL értékkel kell végrehajtani:
strtok(NULL, ":");
A teljes megvalósítás így nézhet ki:
#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, ":"); } }
Másik példa:
#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); } }
Ugyanaz más szeparátorral:
#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); } }
A szeparátorokaból lehet több is:
#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); } }
Lásd még:
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.
int tomb[4];
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.
int tomb[4]; tomb[0] = 3; tomb[1] = 8; tomb[2] = 5; tomb[3] = 2;
Felhasználni ugyanígy tudjuk. Ha szeretném például kiíratni a tömb egyik elemét, azt így tehetem meg:
printf("%d\n", tomb[0]);
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.
#include <stdio.h> int main() { int tomb[] = {3, 5, 6, 7, 8, 9 }; printf("%d\n", tomb[0]); }
Megadható a tömb nagysága:
int tomb[3] = {3, 5, 6};
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.
int tomb[5] = {3, 5, 6};
Ez már helytelen:
int tomb[2] = {3, 5, 6};
int tomb[] = {3, 8, 5, 6, 2, 9 }; int n = sizeof tomb / sizeof tomb[0];
Vagy:
int tomb[] = {3, 8, 5, 6, 2, 9 }; size_t meret = sizeof(tomb) / sizeof(tomb[0]);
Vagy:
int tomb[] = {3, 8, 5, 6, 2, 9 }; int n = sizeof tomb / sizeof *tomb;
Komplett példa:
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 |
Az alábbi egyszerű mátrixot szeretnénk megvalósítani:
3 | 12 | 8 | 9 |
2 | 15 | 17 | 7 |
int tomb[2][4];
Ez két sort és 4 oszlopot jelent.
Értékadás:
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;
int tomb2[2][4] = { {3, 13, 8, 9}, {2, 15, 17, 7} };
GCC-ben:
int tomb[10] = {[0 ... 9] = 5};
Egyébként meg egy for ciklussal.
Tömb átadása paraméterként:
#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]); }
Az átadott tömb cím szerint adódik át.
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:
typedef típus újtipusnév;
Legyen a példa kedvéért egy új típus amely megegyezik az egészeket tárolni képes int típussal:
typedef int TEgesz;
Ezek után, például így használhatom:
TEgesz szam = 5;
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:
typedef int TEgeszTomb[100];
Ezek után így használhatom:
TEgeszTomb tomb; tomb[0] = 5; tomb[1] = 8; //...
Még hasznosabb, amikor a saját típust paraméterlistában használjuk.
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:
FILE *fp; fp = fopen("adat.txt", "w");
alma szilva barack
#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); }
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:
#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); }
Az adat.txt állományhoz írunk áradatokat.
alma 250 szilva 300 barack 450
#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); }
#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); }
#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); }
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.
#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); }
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.
#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); }
Érték szerint átadott paraméterek:
int novel(int szam) { return szam + 1; }
Globális paraméterek
int szam = 0; void novel() { szam = szam + 1; }
Cím szerint átadott paraméterek
void novel(int *szam) { *szam = *szam + 1; } int main() { int szam = 0; novel(&szam); }
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)
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
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.
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.
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 |
time_t datum = time(NULL); strftime(sz, sizeof(sz), "%c", &datum); printf("%s\n", sz);
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.
Mivel számítógépről beszélünk, ezért ez monitor, nyomtató vagy más ehhez hasonló eszköz.
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.
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.
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.
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.
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:
Példák az előfordítói utasításokra:
#include <stdio.h> #define A 3