C programming language (tsz. C programming languages)
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:
A C-t mai napig használják:
A C szabad formátumú nyelv:
;
) jelzi{ ... }
) határoljákPé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.
/* Ez
egy
több soros
komment */
// Ez egy egysoros komment
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):
] ] ] ] stb.
A C programozási nyelv számos alapvető adattípust biztosít.
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:
char
típus lehet signed vagy unsigned, fordítófüggő.int
mérete általában 32 bit, de nem garantált.Példa:
printf("%zu\n", sizeof(int)); // pl. kiírja: 4 (bájt)
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;
Az enum
névvel ellátott egész konstansok csoportját definiálja.
Példa:
enum Color { RED, GREEN, BLUE };
enum Color c = GREEN;
RED = 0
, GREEN = 1
, BLUE = 2
.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).
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
→ short
is eléglong int
→ long
is elégunsigned int
→ unsigned
is elég
A tárolási osztályok meghatározzák:
auto
elhagyható.auto int x; // ugyanaz mint: int x;
register int counter;
Példa függvényen belül:
void foo(void)
{
static int call_count = 0;
call_count++;
printf("Call count: %d\n", call_count);
}
.c
fájlban).extern int global_variable;
_Thread_local int thread_counter;
thread_local
néven is elérhető.
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)
int *p; // mutató int-re
float *fp; // mutató float-ra
double *dp; // mutató double-re
char *cp; // mutató karakterre
NULL
-ra állítjuk.int *p = NULL;
int x = 5;
int *p = &x;
int **pp = &p; // pp mutat egy mutatóra
p + 1
, p - 1
→ típus méretétől függően lépked a memóriában.
A tömb egy azonos típusú elemek sorozata.
int arr;
int
típusú elem: arr
, arr
, …, arr
.
int arr = {1, 2, 3};
Ha kevesebb értéket adunk meg, a maradék nullázódik.
int arr = {1, 2}; // arr = 0
size_t size = sizeof(arr) / sizeof(arr);
arr = 10;
printf("%d\n", arr); // 10
int arr;
int *p = arr; // ekvivalens: int *p = &arr;
p
⇔ arr
.
A string a C-ben karaktertömb, amelynek null karakter ('\0'
) jelzi a végét.
char str = "Hello";
Valójában:
'H' 'e' 'l' 'l' 'o' '\0'
printf("%s\n", str);
char *p = "Hello";
Ez egy mutató egy konstans stringre.
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 = "Hello ";
char str2 = "World";
strcat(str1, str2); // str1 most: "Hello World"
Jelzés | Jelentés |
---|---|
\n
|
új sor |
\t
|
tabulátor |
\"
|
idézőjel |
\\
|
backslash |
\0
|
string vége |
Példa:
printf("Hello\nWorld\n");
A vezérlési szerkezetek segítségével elágazásokat és ismétléseket valósíthatunk meg.
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
}
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
}
break
né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");
}
Előtesztelő ciklus:
while (feltétel) {
// amíg a feltétel igaz
}
Utótesztelő ciklus:
do {
// legalább egyszer végrehajtódik
} while (feltétel);
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);
}
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);
}
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);
Példa mutatóval:
void novel(int *p)
{
(*p)++;
}
int x = 5;
novel(&x); // x most 6
return
utasítással.void
típusú.void hello(void)
{
printf("Hello!\n");
}
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
qsort
).
A struct összetett adattípus, amelyben különböző típusú adatelemeket (tagokat) csoportosíthatunk.
struct Point {
int x;
int y;
};
struct Point p1;
p1.x = 10;
p1.y = 20;
struct Point p2 = { 5, 15 };
printf("x = %d, y = %d\n", p2.x, p2.y);
struct Point *pp = &p2;
printf("%d %d\n", pp->x, pp->y);
->
operátor: pointeren keresztül tag elérése.
Gyakran használjuk typedef
-pel:
typedef struct Point {
int x, y;
} Point;
Point p3;
→ innentől struct
kulcsszó nem szükséges.
Az unió (union) hasonló a struct
-hoz, de minden tag ugyanazon a memóriacímen osztozik. → Egyszerre csak egy tag aktív.
union Data {
int i;
float f;
char str;
};
union Data d;
d.i = 10;
printf("%d\n", d.i);
d.f = 220.5;
printf("%f\n", d.f);
d.f
beállítása felülírja a d.i
korábbi értékét, mert ugyanazt a memóriát használják.
printf("%zu\n", sizeof(union Data));
A bitmező lehetővé teszi, hogy struct
-on belül adott számú bitet adjunk meg.
struct {
unsigned int a : 3; // 3 bit
unsigned int b : 5; // 5 bit
} flags;
flags.a
3 bites egész szám.flags.b
5 bites egész szám.
flags.a = 5;
flags.b = 17;
printf("%u %u\n", flags.a, flags.b);
&flags.a
tilos).int
, unsigned int
vagy _Bool
típusúak lehetnek.
A C fordítási folyamata preprocessorral kezdődik. → Sorok elején # karakterrel írt utasításokat dolgoz fel.
Más fájlok beillesztése:
#include <stdio.h> // rendszerheader
#include "myheader.h" // saját header
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
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.
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 |
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.
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
Á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
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
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
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
Hibakódok kezelése
errno
vá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
}
EACCES // hozzáférési hiba
ENOENT // fájl nem létezik
ENOMEM // nincs elég memória
int a;
a = 5; // hibás, érvényes index: 0..9
char *p = malloc(100);
/* ... */
free(p); // kötelező!
int *p = NULL;
printf("%d\n", *p); // undefined behavior
int x;
printf("%d\n", x); // szemét érték
break
a switch-benswitch (x) {
case 1:
// utasítás
// break elfelejtve → továbbcsúszik!
✅ 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);
A C nyelv egyik sajátossága, hogy bizonyos hibák esetén undefined behavior (nem definiált viselkedés) lép fel.
int i = 5;
i = i++ + ++i; // undefined behavior
int *p = NULL;
*p = 10; // crash!
int arr = {1, 2, 3};
printf("%d\n", arr); // undefined behavior
int x;
printf("%d\n", x); // random érték, undefined behavior
int *p = malloc(sizeof(int));
*p = 5;
free(p);
printf("%d\n", *p); // use-after-free → undefined behavior
A C nyelv az eredeti K&R C és ANSI C (C89/C90) után több szabványfrissítést kapott:
👉 Fontos újítások:
_Bool
típus, illetve stdbool.h
header + bool
kulcsszó:#include <stdbool.h>
bool b = true;
for (int i = 0; i < 10; i++)
inline
kulcsszó → függvény inline-olható.long long int
→ legalább 64 bites egész.//
típusú egysoros komment szabványos lett.int n;
scanf("%d", &n);
int arr;
_Complex
, _Imaginary
típusok (speciális matematikai célokra).
👉 Fontos újítások:
_Thread_local int counter;
_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).
👉 Karbantartó frissítés, főleg hibajavítások. → Új nyelvi funkció nem jött.
👉 Friss, modern C-szabvány. Főbb újítások:
] // ha visszatérési értéket nem használunk, figyelmeztet
]
] // ha változót direkt nem használunk
] // switch-ben fallthrough jelölése
bool
kulcsszó most már natív, stdbool.h
nem kötelező._Decimal32
_Decimal64
_Decimal128
A C nyelv a mai napig az egyik legfontosabb programozási nyelv:
✅ 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.
🚫 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).
👉 Tanuláshoz ajánlott könyvek / források:
A C nyelv megismerése nagyszerű alapot ad bármely más programozási nyelv megtanulásához.
Sok C kód még évtizedekig életben marad — érdemes stabil C ismereteket szerezni.