Mutatók C-ben: Mi a mutató a C programozásban? Típusok
⚡ Okos összefoglaló
A C nyelvben a pointerek olyan változók, amelyek egy másik változó memóriacímét tárolják. Lehetővé teszik a dinamikus memóriafoglalást, a hatékony tömb- és karakterlánc-kezelést, valamint az összetett adatszerkezeteket, az address-of és dereference operátorokat használva az értékek olvasására vagy módosítására.

Mi a mutató C-ben?
A mutató A C nyelvben a egy változó, amely egy másik változó címét tárolja. Egy mutató hivatkozhat egy másik mutatóra vagy egy függvényre is. Egy mutató növelhető vagy csökkenthető, hogy a következő vagy előző memóriahelyre mutasson. A mutató célja a memóriaterület megtakarítása és a gyorsabb végrehajtási idő elérése.
A mutatók használata C-ben
Ha egy int típusú v változót deklarálunk, a v egy értéket tárol. Minden változónak, az értékén kívül, van egy címe is, vagyis az a hely, ahol a memóriában található. A címet úgy kérhetjük le, hogy a változó neve elé egy és-jelet (&) teszünk. Ha egy változó címét kiíratjuk, az egy véletlenszámnak tűnik, amely futtatásról futtatásra változhat.
Érték tárolása helyett a mutató egy változó címét tárolja. Például:
int *y = &v;
| VÁLTOZÓ | MUTATÓ |
|---|---|
| A érték tárolt a nevezett tárolási/memóriacím. | A változó hogy mutat valahová a tárhely/memória címe másik változót. |
Mutató deklarálása
Mint a változók, a mutatók C programozás használat előtt deklarálni kell őket. A pointer deklarációjának formája a következő:
data_type *pointer_variable_name;
Itt, adattípus a mutató alaptípusa, és a mutató által jelzett változó típusát jelzi. A csillag (*), ugyanaz a szimbólum, amelyet a szorzáshoz is használnak, az indirekt operátor, amely egy mutatót deklarál. Néhány érvényes mutatódeklaráció:
int *ptr_thing; /* pointer to an integer */ int *ptr1, thing; /* ptr1 points to an int; thing is an int */ double *ptr2; /* pointer to a double */ float *ptr3; /* pointer to a float */ char *ch1; /* pointer to a character */
Mutató inicializálása
Egy mutató deklarálása után inicializáljuk azt egy változó címével. Ha egy mutatót nem inicializálunk, és mégis használunk, az eredmények kiszámíthatatlanok és akár katasztrofálisak is lehetnek. Egy változó címének lekéréséhez használjuk az és-jel (&) operátort a változó neve előtt:
pointer = &variable;
Egy egyszerű program, amely egy mutatót illusztrál, az alábbiakban látható:
#include <stdio.h> int main() { int a = 10; // variable declaration int *p; // pointer variable declaration p = &a; // store address of a in pointer p printf("Address stored in p is: %x\n", p); // access the address printf("Value stored in p is: %d\n", *p); // access the value return 0; }
output:
Address stored in p is: 60ff08 Value stored in p is: 10
| Operator | Jelentés |
|---|---|
| * | Két célt szolgál: deklarál egy mutatót, és visszaadja a hivatkozott változó értékét (dereferencia). |
| & | Egy célt szolgál: visszaadja egy változó címét. |
A mutatók típusai C-ben
Null mutató
Egy null pointert úgy hozunk létre, hogy a deklaráció során NULL értéket rendelünk hozzá. Ez akkor hasznos, ha a pointerhez még nincs cím rendelve. Egy null pointer mindig 0 értéket tartalmaz:
#include <stdio.h> int main() { int *p = NULL; // null pointer printf("The value inside variable p is: %x", p); return 0; }
Üres mutató
A void pointer, más néven generikus pointer, nem rendelkezik szabványos adattípussal. A void kulcsszóval hozható létre, és bármely változó címét tárolhatja:
#include <stdio.h> int main() { void *p = NULL; // void pointer printf("The size of pointer is: %d\n", sizeof(p)); return 0; }
Vad mutató
Egy mutatót vad mutatónak nevezünk, ha nincs semmire inicializálva. Ezek a mutatók nem hatékonyak, mert ismeretlen memóriahelyre mutathatnak, ami problémákat okozhat és a program összeomlását okozhatja. A vad mutatókkal mindig legyünk óvatosak:
#include <stdio.h> int main() { int *p; // wild pointer printf("%d", *p); return 0; }
A C nyelvben található egyéb mutatótípusok közé tartozik a függő mutató, az összetett mutató, a közeli mutató, a távoli mutató és a hatalmas mutató.
Közvetlen és közvetett hozzáférési mutatók
C nyelven két egyenértékű módja van egy változó tartalmának elérésére és manipulálására. A közvetlen hozzáférés közvetlenül a változó nevét használja, míg a közvetett hozzáférés egy mutatót a változóra:
#include <stdio.h> int var = 1; /* declare and initialize an int variable */ int *ptr; /* declare a pointer to int */ int main(void) { ptr = &var; /* point ptr to var */ printf("\nDirect access, var = %d", var); printf("\nIndirect access, var = %d", *ptr); *ptr = 48; /* change var through the pointer */ printf("\nIndirect access, var = %d", *ptr); return 0; }
Mutatós aritmetika C-ben
Amikor mutatókkal dolgozunk, tartsuk be a következő prioritási szabályokat. A * és & operátorok prioritása megegyezik az unáris operátorok prioritásával (tagadás !, növelés ++, csökkentés –). Ugyanebben a kifejezésben az unáris operátorok *, &, !, ++ és — jobbról balra értékelődnek ki. Ha egy P mutató egy X változóra mutat, akkor a *P bárhol használható, ahol X írható. A következő kifejezések ekvivalensek:
| Kifejezés | Egyenértékű kifejezés |
|---|---|
| Y = *P + 1 | Y = X + 1 |
| *P = *P + 10 | X = X + 10 |
| *P + = 2 | X + = 2 |
| ++*P | ++X |
| (*P)++ | X++ |
Az utolsó esetben zárójelek szükségesek: mivel a * és ++ egyváltozós operátorok jobbról balra értékelődnek ki, zárójelek nélkül a P mutató növekedne, nem pedig az objektum, amelyre mutat. A mutatókon elérhető aritmetikai műveletek az értékadás, a növelés és a csökkentés, valamint az összeadás vagy a sub.tracegy egészértékű eltolást ad meg, amely ennyi elemmel mozgatja el a mutatót (minden lépés egyenlő az alaptípus méretével bájtokban).
C mutatók és tömbök példákkal
Hagyományosan index segítségével érjük el a tömb elemeit, de a mutatók ezt is megkönnyítik. A tömb nevére beállított mutató az első elemre mutat:
#include <stdio.h> int main() { int a[5] = {1, 2, 3, 4, 5}; // array initialization int *p; // pointer declaration p = a; // p points to the first element; same as &a[0] for (int i = 0; i < 5; i++) { printf("%d\n", *p); // print element p++; // move to the next element } return 0; }
Egy szám hozzáadása egy mutatóhoz annyi elemet mozdít előre, amennyit csak lehetséges. Ha p a 0. memóriahelyre mutat, akkor p + 1 hatására a mutató az 1. memóriahelyre mutat.
C Mutatók és karakterláncok példákkal
A karakterlánc (string) karakter objektumok tömbje, melyek null karakterrel ('\0') végződnek. A karakterláncokat mutatók segítségével manipulálhatjuk:
#include <stdio.h> #include <string.h> int main() { char str[] = "Hello Guru99!"; char *p; p = str; printf("First character is: %c\n", *p); p = p + 1; printf("Next character is: %c\n", *p); p = str; // reset the pointer for (int i = 0; i < strlen(str); i++) { printf("%c\n", *p); p++; } return 0; }
A karakterláncok kezelésének egy másik módja a mutatók tömbje:
#include <stdio.h> int main() { char *materials[] = {"iron", "copper", "gold"}; for (int i = 0; i < 3; i++) printf("%s\n", materials[i]); return 0; }
A mutatók előnyei C-ben
- A mutatók hasznosak a memóriahelyek közvetlen eléréséhez.
- Hatékony módot biztosítanak egy tömb elemeinek elérésére.
- Dinamikus memóriaelosztásra és -felszabadításra használják őket.
- Komplex adatszerkezetek, például láncolt listák, gráfok és fák létrehozására használják őket.
A mutatók hátrányai C-ben
- A mutatók megértése kissé bonyolult.
- Olyan hibákat okozhatnak, mint a szegmentálási hibák vagy a nem kívánt memóriahelyhez való hozzáférés.
- A mutatónak adott helytelen érték memória-sérülést okozhat.
- A mutatók a memóriaszivárgásért is felelősek, ha a memória nincs felszabadítva.
- A programozó felelőssége, hogy gondosan kezelje a mutatókat.
