Mutatók C-ben: Mi a mutató a C programozásban? Típusok

Mi a Pointer C-ben?

A Mutató C-ben egy olyan változó, amely egy másik változó címét tárolja. A mutató egy másik mutatófunkcióra is hivatkozhat. A mutató növelhető/csökkenthető, azaz a következő/előző memóriahelyre mutat. A pointer célja memóriaterület megtakarítása és gyorsabb végrehajtási idő elérése.

A mutatók használata C-ben

Ha deklarálunk egy int típusú v változót, akkor v ténylegesen tárol egy értéket.

A mutatók használata C-ben

v egyenlő most nullával.

Az értéken kívül azonban minden változónak megvan a címe (vagy egyszerűen fogalmazva: hol található a memóriában). A címet úgy lehet lekérni, hogy a változó neve elé egy „és” jelet (&) teszünk.

A mutatók használata C-ben

Ha egy változó címét kiírja a képernyőre, az teljesen véletlenszerű számnak fog kinézni (sőt, futásonként eltérő lehet).

Próbáljuk meg ezt a gyakorlatban a mutató segítségével a C példában

A mutatók használata C-ben

A program kimenete -480613588.

Nos, mi az a mutató? Érték tárolása helyett a mutató egy változó címét tárolja.


Mutatóváltozó

Int *y = &v;

VÁLTOZÓ MUTATÓ
A érték tárolt a nevezett tároló/memória cím A változó hogy mutat valahová a tárhely/memória címe másik változó

Mutató deklarálása

Mint a változók, a mutatók C programozás deklarálniuk kell, mielőtt a programban felhasználhatók lesznek. A mutatókat bárminek el lehet nevezni, feltéve, hogy megfelelnek C elnevezési szabályainak. A mutató deklarációjának formája a következő.

data_type * pointer_variable_name;

Itt,

  • adattípus a mutató C változótípusainak alaptípusa, és jelzi a változó típusát, amelyre a mutató mutat.
  • A csillag (*: ugyanaz a csillag, mint a szorzásnál), amely indirekt operátor, mutatót deklarál.

Lássunk néhány érvényes mutatódeklarációt ebben a C pointers oktatóanyagban:

int    *ptr_thing;            /* pointer to an integer */ 
int *ptr1,thing;/* ptr1 is a pointer to type integer and thing is an integer variable */
double    *ptr2;    /* pointer to a double */
float    *ptr3;      /* pointer to a float */
char    *ch1 ;       /* pointer to a character */
float  *ptr, variable;/*ptr is a pointer to type float and variable is an ordinary float variable */

Mutató inicializálása

A mutató deklarálása után úgy inicializáljuk, mint a szokásos változókat változó címmel. Ha a C programozás mutatóit inicializálás nélkül használják, és egy programban használják, az eredmények kiszámíthatatlanok és potenciálisan katasztrofálisak lehetnek.

Egy változó címének meghatározásához az „és” (&) operátort használjuk, amely egy olyan változó neve elé kerül, amelynek a címére szükségünk van. A mutató inicializálása a következő szintaxissal történik.

Mutató szintaxis

 pointer = &variable;

Az alábbiakban egy egyszerű program látható a mutató szemléltetésére:

#include <stdio.h>
int main()
{
   int a=10;    //variable declaration
   int *p;      //pointer variable declaration
   p=&a;        //store address of variable a in pointer p
   printf("Address stored in a variable p is:%x\n",p);  //accessing the address
   printf("Value stored in a variable p is:%d\n",*p);   //accessing the value
   return 0;
}

output:

Address stored in a variable p is:60ff08
Value stored in a variable p is:10
Operator Jelentés
* 2 célt szolgál

  1. Mutató nyilatkozata
  2. A hivatkozott változó értékét adja vissza
& Csak 1 célt szolgál

  • Egy változó címét adja vissza

A mutatók típusai C-ben

Az alábbiakban a különböző A mutatók típusai C-ben:

Null mutató

Létrehozhatunk nullmutatót, ha a mutató deklarációja során null értéket adunk hozzá. Ez a módszer akkor hasznos, ha nincs cím hozzárendelve a mutatóhoz. A nulla mutató mindig 0 értéket tartalmaz.

A következő program a null mutató használatát szemlélteti:

#include <stdio.h>
int main()
{
	int *p = NULL; 	//null pointer
	printf(“The value inside variable p is:\n%x”,p);
	return 0;
}

output:

The value inside variable p is:
0

Üres mutató

In C programozás, az üres mutatót általános mutatónak is nevezik. Nincs szabványos adattípusa. A void mutató a void kulcsszó használatával jön létre. Bármely változó címének tárolására használható.

Az alábbi program az üres mutató használatát szemlélteti:

#include <stdio.h>
int main()
{
void *p = NULL; 	//void pointer
printf("The size of pointer is:%d\n",sizeof(p));
return 0;
}

output:

The size of pointer is:4

Vad mutató

A mutatót vad mutatónak nevezik, ha nincs inicializálva semmire. Az ilyen típusú C-mutatók nem hatékonyak, mert egy ismeretlen memóriahelyre mutathatnak, ami problémákat okozhat a programunkban, és a program összeomlásához vezethet. Mindig legyen óvatos, amikor vad mutatókkal dolgozik.

A következő program a wild pointer használatát szemlélteti:

#include <stdio.h>
int main()
{
int *p; 	//wild pointer
printf("\n%d",*p);
return 0;
}

output:

timeout: the monitored command dumped core
sh: line 1: 95298 Segmentation fault      timeout 10s main

A 'c'-ben lévő egyéb mutatótípusok a következők:

  • Lógó mutató
  • Komplex mutató
  • Mutató közelében
  • Távoli mutató
  • Hatalmas mutató

Közvetlen és közvetett hozzáférési mutatók

C-ben két egyenértékű módja van a változó tartalom elérésének és kezelésének

  • Közvetlen hozzáférés: közvetlenül a változó nevét használjuk
  • Közvetett hozzáférés: mutatót használunk a változóra

Értsük meg ezt az alábbi program segítségével

#include <stdio.h>
/* Declare and initialize an int variable */
int var = 1;
/* Declare a pointer to int */
int *ptr;
int main( void )
{
/* Initialize ptr to point to var */
ptr = &var;
/* Access var directly and indirectly */
printf("\nDirect access, var = %d", var);
printf("\nIndirect access, var = %d", *ptr);
/* Display the address of var two ways */
printf("\n\nThe address of var = %d", &var);
printf("\nThe address of var = %d\n", ptr);
/*change the content of var through the pointer*/
*ptr=48;
printf("\nIndirect access, var = %d", *ptr);
return 0;}

A program hibamentes fordítása után az eredmény:

Direct access, var = 1
Indirect access, var = 1

The address of var = 4202496
The address of var = 4202496

Indirect access, var = 48

Mutatós aritmetika C-ben

A mutató műveleteit a következő ábra foglalja össze

Mutatós aritmetika C-ben
Mutató OperaTIONS

Elsőbbségi művelet (elsőbbség)

Amikor C-mutatókkal dolgozunk, be kell tartanunk a következő prioritási szabályokat:

  • A * és & operátorok prioritása megegyezik az unáris operátorokkal (a tagadás!, az inkrementáció++, a csökkentés–).
  • Ugyanebben a kifejezésben a *, &,!, ++, – unáris operátorok jobbról balra kerülnek kiértékelésre.

Ha egy P mutató egy X változóra mutat, akkor * P használható mindenhol, ahol X írható.

A következő kifejezések egyenértékűek:

int X =10
int *P = &Y;
For the above code, below expressions are true
Kifejezés Egyenértékű kifejezés
I=*P+1

*P=*P+10

*P+=2

++*P

(*P)++

Y=X+1

X=X+10

X+=2

++X

X++

Ez utóbbi esetben zárójelekre van szükség: mivel az unáris * és ++ operátorok jobbról balra kerülnek kiértékelésre, a zárójelek nélkül a P mutató növekszik, nem pedig az az objektum, amelyre P mutat.

Az alábbi táblázat bemutatja a C-mutatók kezelésekor használható számtani és alapműveleteket

OperaCIÓ Magyarázat
Átruházás int *P1,*P2
P1=P2;
P1 és P2 ugyanarra az egész változóra mutat
Növekedés és csökkentés Int *P1;
P1++;P1– ;
Eltolás hozzáadása (állandó) Ez lehetővé teszi, hogy a mutató N elemet mozgasson a táblázatban.
A mutató a változó típusának bájtjainak N-szeresével nő vagy csökken.
P1+5;

C Mutatók és tömbök példákkal

Hagyományosan a tömb elemeit annak indexével érjük el, de ez a módszer kiküszöbölhető mutatók használatával. A mutatók megkönnyítik az egyes tömbelemek elérését.

#include <stdio.h>
int main()
{
    int a[5]={1,2,3,4,5};   //array initialization
    int *p;     //pointer declaration
               /*the ptr points to the first element of the array*/

    p=a; /*We can also type simply ptr==&a[0] */
    
    printf("Printing the array elements using pointer\n");
    for(int i=0;i<5;i++)    //loop for traversing array elements
    {
        	printf("\n%x",*p);  //printing array elements
        	p++;    //incrementing to the next element, you can also write p=p+1
    }
    return 0;
}

output:

1
2
3
4
5

Ha egy adott számot hozzáad egy mutatóhoz, akkor a mutató helye az összeadási művelettel kapott értékre kerül. Tegyük fel, hogy p egy mutató, amely jelenleg a 0 memóriahelyre mutat, ha végrehajtjuk a következő összeadási műveletet, p+1, akkor a következő módon fog végrehajtani:

C Mutatók és tömbök

Mutató hozzáadása/növelése

Mivel p jelenleg 0 hozzáadása után a 1 helyre mutat, az érték 1 lesz, így a mutató az 1-es memóriahelyre mutat.

C Mutatók és karakterláncok példákkal

A karakterlánc char objektumok tömbje, amely null karakterrel végződik '\ 0'. A karakterláncokat mutatók segítségével manipulálhatjuk. Ez a mutató a C példában magyarázza ezt a részt

#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);
printf("Printing all the characters in a string\n");
p=str;  //reset the pointer
for(int i=0;i<strlen(str);i++)
{
printf("%c\n",*p);
p++;
}
return 0;
}

output:

First character is:H
Next character is:e
Printing all the characters in a string
H
e
l
l
o

G
u
r
u
9
9
!

A karakterláncok kezelésének másik módja a mutatók tömbje, mint a következő programban:

#include <stdio.h>
int main(){
char *materials[ ] = {  "iron",  "copper",  "gold"};
printf("Please remember these materials :\n");
int i ;
for (i = 0; i < 3; i++) {
  printf("%s\n", materials[ i ]);}
  return 0;}

output:

Please remember these materials:
iron
copper
gold

A mutatók előnyei C-ben

  • A mutatók hasznosak a memóriahelyek eléréséhez.
  • A mutatók hatékony módot biztosítanak a tömbszerkezet elemeinek elérésére.
  • A mutatókat a dinamikus memóriafoglaláshoz és a felszabadításhoz is használják.
  • A mutatókat összetett adatszerkezetek, például linkelt lista, grafikon, fa stb. létrehozására használják.

A mutatók hátrányai C-ben

  • A mutatók megértése kissé bonyolult.
  • A mutatók különféle hibákhoz vezethetnek, például szegmentációs hibákhoz, vagy hozzáférhetnek egy olyan memóriahelyhez, amelyre egyáltalán nincs szükség.
  • Ha helytelen értéket ad meg egy mutatónak, az memóriasérülést okozhat.
  • A pointerek a memóriaszivárgásért is felelősek.
  • A mutatók viszonylag lassabbak, mint a változóké.
  • A programozók nagyon nehezen tudnak dolgozni a mutatókkal; ezért a programozó felelőssége a mutató gondos manipulálása.

Összegzésként

  • A mutató nem más, mint egy memóriahely, ahol az adatok tárolódnak.
  • A memóriahely eléréséhez egy mutatót használnak.
  • Különféle típusú mutatók léteznek, például nullmutató, vad mutató, üres mutató és más típusú mutatók.
  • A mutatók tömbökkel és karakterláncokkal együtt használhatók az elemek hatékonyabb eléréséhez.
  • Létrehozhatunk függvénymutatókat a függvény dinamikus meghívásához.
  • Az aritmetikai műveletek elvégezhetők egy mutatón, amelyet mutatóaritmetikának neveznek.
  • A mutatók függvényre is mutathatnak, ami megkönnyíti a különböző függvények meghívását mutatók tömbjének meghatározása esetén.
  • Ha különböző változó adattípusokat szeretne kezelni, használhat typecast void mutatót.