C programming language
Főnév
C programming language (tsz. C programming languages)
C programozási nyelv
1. Bevezetés
A C programozási nyelv az egyik legfontosabb és legszélesebb körben használt nyelv a szoftverfejlesztésben. 1972-ben Dennis Ritchie fejlesztette ki a Bell Labs-nél, eredetileg az UNIX operációs rendszer implementálására.
A C fő jellemzői:
- Hordozhatóság: különböző hardvereken is lefordítható
- Hatékonyság: a C nyelv közel áll a gépi kódhoz, ezért nagyon gyors
- Egyszerű nyelvi elemek: néhány alapvető struktúra, de nagyon erőteljes
- Alacsony szintű hozzáférés: lehetőség van közvetlen memóriakezelésre
- Sok utódnyelvet inspirált: C++, Java, C#, Objective-C, Go, Rust stb.
A C-t mai napig használják:
- operációs rendszerek fejlesztéséhez (Linux kernel, Windows részei)
- beágyazott rendszerekhez
- compiler fejlesztéshez
- nagy teljesítményű alkalmazásokhoz
2. Alapvető szintaxis
A C szabad formátumú nyelv:
- a sorok vége nem jelent végrehajtási határt
- a sorok között tetszőleges szóköz/újsor helyezhető el
- az utasítások végét pontosvessző (
;) jelzi - az utasításblokkokat kapcsos zárójelek (
{ ... }) határolják
Példa:
#include <stdio.h>
int main(void)
{
printf("Hello, world!\n");
return 0;
}
A program belépési pontja a main() függvény. A printf() függvény kiírja a konzolra a megadott szöveget. A return 0; a program sikeres befejezését jelzi.
Megjegyzések (kommentek):
- Többsoros:
/* Ez
egy
több soros
komment */
- Egysoros (C99 óta):
// Ez egy egysoros komment
3. Kulcsszavak
A C-ben előre definiált kulcsszavak vannak, amelyeket nem használhatunk változó- vagy függvénynévként.
Főbb kulcsszavak:
auto break case char const continue default do double else enum extern float for goto if inline int long register restrict return short signed sizeof static struct switch typedef union unsigned void volatile while
C99-től kiegészült:
_Bool _Complex _Imaginary
C11-től:
_Atomic _Generic _Noreturn _Static_assert _Thread_local
C23-tól (újabb attribútumok):
[[deprecated]] [[nodiscard]] [[maybe_unused]] [[fallthrough]] stb.
4. Adattípusok
A C programozási nyelv számos alapvető adattípust biztosít.
4.1 Egész típusok (integer types)
Az egész típusok egész számokat tárolnak (előjeles vagy előjel nélküli).
| Típus | Tipikus méret (bit) | Tartomány |
|---|---|---|
char |
8 | -128 .. 127 vagy 0 .. 255 |
signed char |
8 | -128 .. 127 |
unsigned char |
8 | 0 .. 255 |
short vagy short int |
≥16 | -32 768 .. 32 767 |
unsigned short |
≥16 | 0 .. 65 535 |
int |
≥16, gyakran 32 | platformfüggő |
unsigned int |
≥16 | platformfüggő |
long |
≥32 | platformfüggő |
unsigned long |
≥32 | platformfüggő |
long long |
≥64 | -9×10^18 .. +9×10^18 |
unsigned long long |
≥64 | 0 .. 18×10^18 |
Fontos:
- A
chartípus lehet signed vagy unsigned, fordítófüggő. - Az
intmérete általában 32 bit, de nem garantált. - A sizeof() operátorral lekérdezhetjük bármely típus méretét.
Példa:
printf("%zu\n", sizeof(int)); // pl. kiírja: 4 (bájt)
4.2 Lebegőpontos típusok (floating point types)
A lebegőpontos típusok tört számokat (valós számokat) tárolnak:
| Típus | Jellemző pontosság | Megjegyzés |
|---|---|---|
float |
~6-7 decimális jegy | egyszeres pontosság |
double |
~15-16 jegy | dupla pontosság |
long double |
≥15 jegy (platformfüggő) | kiterjesztett pontosság |
Példa:
float f = 3.14f;
double d = 3.14159265358979;
long double ld = 3.141592653589793238L;
4.3 Felsorolt típusok (enum)
Az enum névvel ellátott egész konstansok csoportját definiálja.
Példa:
enum Color { RED, GREEN, BLUE };
enum Color c = GREEN;
- Alapértelmezetten
RED = 0,GREEN = 1,BLUE = 2. - Konkrét értékeket is rendelhetünk:
enum Color { RED = 10, GREEN = 20, BLUE = 30 };
Az enum típus belül egész számként reprezentálódik (int típus).
4.4 Típusmódosítók (type modifiers)
A C négy típusmódosítót biztosít:
signed— előjelesunsigned— előjel nélkülishort— rövidített (kisebb méretű)long— megnövelt méretű
Példa kombinációk:
unsigned int x;
signed long y;
unsigned long long big;
Összefoglalás:
short int→shortis eléglong int→longis elégunsigned int→unsignedis elég
5. Storage class specifiers (Tárolási osztály-specifikátorok)
A tárolási osztályok meghatározzák:
- változó élettartamát (meddig létezik)
- láthatóságát (hol látható)
- tárolási helyét
5.1 auto
- Alapértelmezett helyi változókra (függvényen belül)
- Nem szükséges kiírni →
autoelhagyható.
auto int x; // ugyanaz mint: int x;
5.2 register
- Azt jelzi a fordítónak, hogy regiszterben tárolja a változót (gyorsabb elérés).
- Modern fordítók figyelmen kívül hagyhatják.
- Regiszterváltozóra nem lehet címet venni.
register int counter;
5.3 static
- A függvényen belül: statikus változó, amely megőrzi értékét a függvényhívások között.
- A függvényen kívül: csak a fordítási egységen belül látható.
Példa függvényen belül:
void foo(void)
{
static int call_count = 0;
call_count++;
printf("Call count: %d\n", call_count);
}
5.4 extern
- A változó már máshol definiálva van (másik fájlban pl.
.cfájlban). - Csak declaráció, nem foglal helyet.
extern int global_variable;
5.5 _Thread_local (C11)
- Minden szálnak saját példánya van a változóból.
_Thread_local int thread_counter;
- C23-tól:
thread_localnéven is elérhető.
6. Mutatók (Pointers)
A mutató (pointer) egy memóriacímet tárol. Segítségével változó címére hivatkozhatunk.
int x = 10;
int *p = &x; // p az x címét tartalmazza
printf("%d\n", *p); // *p dereferálás: kiírja az x értékét → 10
&→ cím operátor (address-of)*→ dereferálás (pointer által mutatott érték)
Pointer típusok:
int *p; // mutató int-re
float *fp; // mutató float-ra
double *dp; // mutató double-re
char *cp; // mutató karakterre
NULL pointer
- Ha mutató nem mutat érvényes címre, értékét
NULL-ra állítjuk.
int *p = NULL;
Mutató mutatóra
int x = 5;
int *p = &x;
int **pp = &p; // pp mutat egy mutatóra
Mutatókkal műveletek:
- Mutatók aritmetikája:
p + 1,p - 1→ típus méretétől függően lépked a memóriában. - Két mutató kivonása: a köztes elemek száma.
7. Tömbök (Arrays)
A tömb egy azonos típusú elemek sorozata.
Definiálás:
int arr[5];
- 5 darab
inttípusú elem:arr[0],arr[1], …,arr[4].
Inicializálás:
int arr[3] = {1, 2, 3};
Ha kevesebb értéket adunk meg, a maradék nullázódik.
int arr[5] = {1, 2}; // arr[2..4] = 0
Tömb méretének lekérdezése:
size_t size = sizeof(arr) / sizeof(arr[0]);
Tömb indexelése:
arr[0] = 10;
printf("%d\n", arr[0]); // 10
Tömb és pointer kapcsolata:
- Egy tömb neve pointerként viselkedik → a tömb első elemének címét adja.
int arr[5];
int *p = arr; // ekvivalens: int *p = &arr[0];
- Így a
p[i]⇔arr[i].
8. Stringek (Character arrays)
A string a C-ben karaktertömb, amelynek null karakter ('\0') jelzi a végét.
Példa:
char str[] = "Hello";
Valójában:
'H' 'e' 'l' 'l' 'o' '\0'
String kiírás:
printf("%s\n", str);
Karakterlánc literál:
char *p = "Hello";
Ez egy mutató egy konstans stringre.
String műveletek:
A string.h fejlécfájl tartalmazza:
| Függvény | Leírás |
|---|---|
strlen(s) |
String hossz |
strcpy(d, s) |
String másolás |
strcat(d, s) |
String összefűzés |
strcmp(s1, s2) |
String összehasonlítás |
Példa:
#include <string.h>
char str1[20] = "Hello ";
char str2[] = "World";
strcat(str1, str2); // str1 most: "Hello World"
Escape szekvenciák:
| Jelzés | Jelentés |
|---|---|
\n |
új sor |
\t |
tabulátor |
\" |
idézőjel |
\\ |
backslash |
\0 |
string vége |
Példa:
printf("Hello\nWorld\n");
9. Vezérlési szerkezetek
A vezérlési szerkezetek segítségével elágazásokat és ismétléseket valósíthatunk meg.
9.1 if, if-else
Alapszerkezet:
if (feltétel) {
// utasítás(ok), ha igaz
}
if-else:
if (feltétel) {
// ha igaz
} else {
// ha hamis
}
if-else if-else lánc:
if (a > b) {
// ág 1
} else if (a == b) {
// ág 2
} else {
// ág 3
}
9.2 switch-case
Többirányú elágazás:
switch (kifejezés) {
case érték1:
// utasítások
break;
case érték2:
// utasítások
break;
default:
// ha egyik sem teljesül
}
- A
breaknélkül a végrehajtás továbbcsúszik a következő ágra → “fallthrough”.
Példa:
switch (x) {
case 1:
printf("Egy\n");
break;
case 2:
printf("Kettő\n");
break;
default:
printf("Ismeretlen\n");
}
9.3 while ciklus
Előtesztelő ciklus:
while (feltétel) {
// amíg a feltétel igaz
}
9.4 do-while ciklus
Utótesztelő ciklus:
do {
// legalább egyszer végrehajtódik
} while (feltétel);
9.5 for ciklus
Klasszikus számlálós ciklus:
for (kezdeti érték; feltétel; léptetés) {
// ciklusmag
}
Példa:
for (int i = 0; i < 10; i++) {
printf("%d\n", i);
}
9.6 break, continue, goto
- break → kilépés a ciklusból vagy switch-ből
- continue → ciklus következő iterációjára ugrik
- goto → ugrás egy címkére (általában kerülendő)
for (int i = 0; i < 10; i++) {
if (i == 5)
break; // kilépés
if (i % 2 == 0)
continue; // páros számokat kihagy
printf("%d\n", i);
}
10. Függvények
Szintaxis:
visszatérési_típus függvénynév(paraméterlista)
{
// utasítások
return érték; // ha nem void
}
Példa:
int osszeg(int a, int b)
{
return a + b;
}
Hívás:
int eredmeny = osszeg(3, 4);
Paraméterek
- érték szerinti átadás → másolatot kap a függvény.
- mutatóval átadás → lehetőséget ad a változó módosítására.
Példa mutatóval:
void novel(int *p)
{
(*p)++;
}
int x = 5;
novel(&x); // x most 6
Visszatérési érték
- A függvény visszaadhat értéket a
returnutasítással. - Ha nincs visszatérési érték:
voidtípusú.
void hello(void)
{
printf("Hello!\n");
}
Függvénymutatók
Egy mutató tárolhat függvény címét.
Példa:
int osszeg(int a, int b) { return a + b; }
int (*fp)(int, int) = osszeg;
int eredmeny = fp(5, 7); // 12
- Függvénymutatókat gyakran használnak callback-ekhez (pl.
qsort).
11. Struktúrák (struct)
A struct összetett adattípus, amelyben különböző típusú adatelemeket (tagokat) csoportosíthatunk.
Deklarálás:
struct Point {
int x;
int y;
};
Használat:
struct Point p1;
p1.x = 10;
p1.y = 20;
Inicializálás:
struct Point p2 = { 5, 15 };
Tagok elérése:
printf("x = %d, y = %d\n", p2.x, p2.y);
Mutatóval:
struct Point *pp = &p2;
printf("%d %d\n", pp->x, pp->y);
->operátor: pointeren keresztül tag elérése.
struct typedef-fel:
Gyakran használjuk typedef-pel:
typedef struct Point {
int x, y;
} Point;
Point p3;
→ innentől struct kulcsszó nem szükséges.
12. Uniók (union)
Az unió (union) hasonló a struct-hoz, de minden tag ugyanazon a memóriacímen osztozik. → Egyszerre csak egy tag aktív.
Deklarálás:
union Data {
int i;
float f;
char str[20];
};
Használat:
union Data d;
d.i = 10;
printf("%d\n", d.i);
d.f = 220.5;
printf("%f\n", d.f);
- Itt a
d.fbeállítása felülírja ad.ikorábbi értékét, mert ugyanazt a memóriát használják.
Méret:
- Egy unió mérete akkora, mint a legnagyobb tag mérete.
printf("%zu\n", sizeof(union Data));
Tipikus felhasználás:
- memóriatakarékosság.
- értelmező/átalakító struktúrák (pl. kommunikációs protokollok).
13. Bitmezők (Bit field)
A bitmező lehetővé teszi, hogy struct-on belül adott számú bitet adjunk meg.
Deklarálás:
struct {
unsigned int a : 3; // 3 bit
unsigned int b : 5; // 5 bit
} flags;
flags.a3 bites egész szám.flags.b5 bites egész szám.
Használat:
flags.a = 5;
flags.b = 17;
printf("%u %u\n", flags.a, flags.b);
Tipikus felhasználás:
- hardveres regiszterek bitjeinek kezelése.
- jelzők (flags) tárolása hatékonyan.
Korlátozások:
- Bitmezőhöz nem lehet címet venni (
&flags.atilos). - Bitmezők csak
int,unsigned intvagy_Booltípusúak lehetnek.
14. Preprocessor (Előfeldolgozó)
A C fordítási folyamata preprocessorral kezdődik. → Sorok elején # karakterrel írt utasításokat dolgoz fel.
14.1 #include
Más fájlok beillesztése:
#include <stdio.h> // rendszerheader
#include "myheader.h" // saját header
14.2 #define
Makródefiníció (egyszerű szöveg-helyettesítés):
#define PI 3.14159
printf("%f\n", PI);
Paraméteres makró:
#define SQUARE(x) ((x) * (x))
printf("%d\n", SQUARE(5)); // 25
14.3 #ifdef, #ifndef, #endif
Feltételes fordítás:
#ifdef DEBUG
printf("Debug mode\n");
#endif
#ifndef MY_HEADER_H
#define MY_HEADER_H
// header tartalom
#endif
→ include guard: megakadályozza a header többszöri beillesztését.
14.4 Egyéb direktívák
| Direktíva | Leírás |
|---|---|
#undef |
Makró törlése |
#if, #elif, #else, #endif |
Összetett feltételes fordítás |
#error |
Hibaüzenet generálása fordításkor |
#pragma |
Fordítóspecifikus utasítások |
15. A C standard könyvtár
A C standard könyvtár számos hasznos függvényt és makrót biztosít, amelyeket header fájlok segítségével érünk el.
15.1 stdio.h
Be/Ki műveletek (Standard I/O)
Főbb függvények:
printf(); // formázott kiírás
scanf(); // formázott beolvasás
puts(); // string kiírás
gets(); // (NEM AJÁNLOTT — biztonsági okokból)
putchar(); // karakter kiírása
getchar(); // karakter beolvasása
fopen(); // fájl megnyitása
fclose(); // fájl lezárása
fprintf(); // formázott írás fájlba
fscanf(); // formázott olvasás fájlból
fread(), fwrite(); // bináris fájl I/O
15.2 stdlib.h
Általános segédfüggvények
malloc(); // memóriafoglalás
calloc(); // nullázott memóriafoglalás
realloc(); // átméretezés
free(); // memória felszabadítás
atoi(); // string -> int
atof(); // string -> float
exit(); // program befejezése
system(); // shell parancs futtatása
rand(); // véletlenszám
srand(); // seed inicializálása
15.3 string.h
String műveletek
strlen(); // string hossza
strcpy(); // string másolása
strncpy(); // string másolása, korlátozott hossz
strcat(); // string összefűzés
strncat(); // string összefűzés, korlátozott hossz
strcmp(); // string összehasonlítás
strncmp(); // részleges összehasonlítás
strchr(); // karakter keresése stringben
strstr(); // substring keresése
memcpy(); // memória másolás
memset(); // memória feltöltés
15.4 math.h
Matematikai függvények
sqrt(); // négyzetgyök
pow(); // hatványozás
sin(); cos(); tan(); // trigonometrikus függvények
asin(); acos(); atan(); atan2();
exp(); log(); log10();
fabs(); // abszolút érték
floor(); ceil(); // lefelé, felfelé kerekítés
15.5 time.h
Idő kezelése
time(); // aktuális idő (epoch time)
clock(); // CPU idő
difftime(); // két időpont különbsége
strftime(); // idő formázás
localtime(); // idő bontása helyi időzónára
gmtime(); // UTC idő bontása
15.6 errno.h
Hibakódok kezelése
- A globális
errnováltozóval jelezhetjük a hibákat.
#include <errno.h>
#include <stdio.h>
if (fopen("nemletezo.txt", "r") == NULL) {
perror("Hiba"); // Kiírja a hibát
}
- Tipikus hibakódok:
EACCES // hozzáférési hiba
ENOENT // fájl nem létezik
ENOMEM // nincs elég memória
16. Tipikus hibák és jó gyakorlatok
16.1 Tipikus hibák
- Túlindexelés tömbben
int a[10];
a[10] = 5; // hibás, érvényes index: 0..9
- Memória felszabadítás elfelejtése
char *p = malloc(100);
/* ... */
free(p); // kötelező!
- Null pointer dereferálása
int *p = NULL;
printf("%d\n", *p); // undefined behavior
- Nem inicializált változók használata
int x;
printf("%d\n", x); // szemét érték
- Elfelejtett
breaka switch-ben
switch (x) {
case 1:
// utasítás
// break elfelejtve → továbbcsúszik!
16.2 Jó gyakorlatok
✅ Minden változót inicializáljunk. ✅ Memóriát mindig felszabadítani → free(). ✅ Tömbindexet mindig ellenőrizzük. ✅ Ellenőrizzük a malloc() visszatérési értékét (NULL ellenőrzés!). ✅ Header guard minden header fájlban:
#ifndef MYHEADER_H
#define MYHEADER_H
// tartalom
#endif
✅ Függvények deklarációját mindig header fájlba tegyük. ✅ const használata, ha a függvény nem módosít bemenetet:
void printArray(const int *arr, size_t size);
17. Undefined behavior példák
A C nyelv egyik sajátossága, hogy bizonyos hibák esetén undefined behavior (nem definiált viselkedés) lép fel.
Példák:
1. Többszörös módosítás sorrend nélkül
int i = 5;
i = i++ + ++i; // undefined behavior
2. Null pointer dereferálás
int *p = NULL;
*p = 10; // crash!
3. Tömb túlindexelése
int arr[3] = {1, 2, 3};
printf("%d\n", arr[5]); // undefined behavior
4. Nem inicializált változó használata
int x;
printf("%d\n", x); // random érték, undefined behavior
5. Már felszabadított memória használata
int *p = malloc(sizeof(int));
*p = 5;
free(p);
printf("%d\n", *p); // use-after-free → undefined behavior
18. Új szabványok (C99, C11, C17, C23)
A C nyelv az eredeti K&R C és ANSI C (C89/C90) után több szabványfrissítést kapott:
C99 (1999)
👉 Fontos újítások:
_Booltípus, illetvestdbool.hheader +boolkulcsszó:
#include <stdbool.h>
bool b = true;
- Egyszerűbb ciklusok (for) deklarációja:
for (int i = 0; i < 10; i++)
inlinekulcsszó → függvény inline-olható.long long int→ legalább 64 bites egész.//típusú egysoros komment szabványos lett.- Variábilis méretű tömbök (VLAs):
int n;
scanf("%d", &n);
int arr[n];
_Complex,_Imaginarytípusok (speciális matematikai célokra).
C11 (2011)
👉 Fontos újítások:
- _Thread_local → szálonkénti lokális változó:
_Thread_local int counter;
- _Static_assert → fordítási idejű ellenőrzés:
_Static_assert(sizeof(int) == 4, "int mérete nem 4 bájt!");
<threads.h>→ C-ben natív thread API (ritkán használt).<stdatomic.h>→ atomi műveletek (párhuzamos programozás támogatása).
C17 (2017)
👉 Karbantartó frissítés, főleg hibajavítások. → Új nyelvi funkció nem jött.
C23 (2023)
👉 Friss, modern C-szabvány. Főbb újítások:
- Attribútumok bevezetése C++11 mintára:
[[nodiscard]] // ha visszatérési értéket nem használunk, figyelmeztet
[[deprecated("használata nem ajánlott")]]
[[maybe_unused]] // ha változót direkt nem használunk
[[fallthrough]] // switch-ben fallthrough jelölése
boolkulcsszó most már natív,stdbool.hnem kötelező.- Decimal lebegőpontos típusok:
_Decimal32
_Decimal64
_Decimal128
- u8 karakterláncok, jobb Unicode támogatás.
- typeof, typeof_unqual → GCC-féle bővítés szabványosítása.
- Különféle modernizálások, optimalizálások.
19. Összefoglalás
A C nyelv a mai napig az egyik legfontosabb programozási nyelv:
- Erőteljes → hardverközeli műveletek
- Gyors → közel gépi kód
- Hordozható → minden platformon elérhető
- Egyszerű alapszintaxis, ugyanakkor erőteljes eszköztár
Alapvető nyelvi eszközök:
✅ Típusok: int, float, char, double, struct, union, enum ✅ Mutatók ✅ Tömbök ✅ Stringek ✅ Függvények, függvénymutatók ✅ Vezérlési szerkezetek: if, switch, for, while, do-while, break, continue, goto ✅ Standard könyvtár: stdio.h, stdlib.h, string.h, math.h, time.h, errno.h ✅ Modern C: _Static_assert, inline, bool, nodiscard, stb.
Mire figyelj:
🚫 Undefined behavior → nagyon sok lehetséges buktató ✅ Mindig inicializálj! ✅ Ellenőrizd a memóriaműveletek sikerét. ✅ Ne írj túl a tömbhatáron. ✅ Használj modern C szabványokat (legalább C99 vagy C11).
Használati területek:
- Operációs rendszerek (Linux kernel → C-ben íródott)
- Beágyazott rendszerek
- Szuperszámítógépes programok
- Compiler-ek, runtime rendszerek
- Hardver-vezérlő szoftverek
- Nagy teljesítményű alkalmazások
👉 Tanuláshoz ajánlott könyvek / források:
- The C Programming Language — Brian W. Kernighan & Dennis M. Ritchie (K&R könyv)
- C Programming: A Modern Approach — K. N. King
- 21st Century C — Ben Klemens
- cppreference.com C részlege → modern C szabványok naprakészen
Záró megjegyzés
A C nyelv megismerése nagyszerű alapot ad bármely más programozási nyelv megtanulásához.
- A memóriakezelés, a mutatók, a típusok és a low-level gondolkodás készségei mindenhol hasznosak.
Sok C kód még évtizedekig életben marad — érdemes stabil C ismereteket szerezni.
- C programming language - Szótár.net (en-hu)
- C programming language - Sztaki (en-hu)
- C programming language - Merriam–Webster
- C programming language - Cambridge
- C programming language - WordNet
- C programming language - Яндекс (en-ru)
- C programming language - Google (en-hu)
- C programming language - Wikidata
- C programming language - Wikipédia (angol)