Pointers in C: Wat is Pointer in C-programmering? Soorten

โšก Slimme samenvatting

Pointers in C zijn variabelen die het geheugenadres van een andere variabele opslaan. Ze maken dynamische geheugenallocatie, efficiรซnte verwerking van arrays en strings en complexe datastructuren mogelijk, waarbij de adres-van- en dereferentie-operatoren worden gebruikt om waarden te lezen of te wijzigen.

  • ๐Ÿ“Œ Definitie: Een pointer bevat het geheugenadres van een andere variabele.
  • ๐Ÿ”ง OperaTorens: De operator & retourneert een adres; de operator * dereferentieert het adres.
  • ๐Ÿงท Verklaring: Schrijf naar data_type *name en initialiseer vervolgens met het adres van een variabele.
  • ???? ๏ธ types: Null-, void- en wildpointers gedragen zich anders en vereisen speciale aandacht.
  • โž• Rekenkundig: Het verhogen van een pointer verplaatst deze met de grootte van het basistype.
  • ๐Ÿค– AI-assistentie: AI-tools sporen segmentatiefouten op en signaleren zwevende pointers tijdens de review.

Wijzers in C

Wat is een pointer in C?

A wijzer In C is een pointer een variabele die het adres van een andere variabele opslaat. Een pointer kan ook verwijzen naar een andere pointer of naar een functie. Een pointer kan worden verhoogd of verlaagd om naar de volgende of vorige geheugenlocatie te wijzen. Het doel van een pointer is om geheugenruimte te besparen en een snellere uitvoeringstijd te bereiken.

Aanwijzingen gebruiken in C

Als we een variabele v van het type int declareren, slaat v een waarde op. Elke variabele heeft, naast de waarde, ook een adres, oftewel de locatie in het geheugen. Het adres kan worden opgevraagd door een ampersand (&) voor de variabelenaam te plaatsen. Als je het adres van een variabele afdrukt, ziet het eruit als een willekeurig getal dat bij elke uitvoering kan verschillen.

Een pointer slaat geen waarde op, maar het adres van een variabele. Bijvoorbeeld:

int *y = &v;
VARIABELE PUNT
A waarde opgeslagen in een genoemd opslag-/geheugenadres. A variabele uit die wijst het opslag-/geheugenadres van ander variabel.

Een aanwijzer declareren

Net als variabelen, verwijzingen naar binnen C programmeren Pointers moeten worden gedeclareerd voordat ze kunnen worden gebruikt. Een pointerdeclaratie heeft de volgende vorm:

data_type *pointer_variable_name;

Hier data type `<type>` is het basistype van de pointer en geeft het type aan van de variabele waarnaar de pointer wijst. Het sterretje (*), hetzelfde symbool dat voor vermenigvuldiging wordt gebruikt, is de indirectie-operator die een pointer declareert. Enkele geldige pointerdeclaraties zijn:

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 */

Een aanwijzer initialiseren

Na het declareren van een pointer initialiseren we deze met het adres van de variabele. Als een pointer niet geรฏnitialiseerd is en toch gebruikt wordt, kunnen de gevolgen onvoorspelbaar en potentieel desastreus zijn. Om het adres van een variabele te verkrijgen, gebruiken we de ampersand (&) operator vรณรณr de variabelenaam:

pointer = &variable;

Hieronder staat een eenvoudig programma dat een pointer illustreert:

#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 Betekenis
* Dient twee doelen: het declareert een pointer en retourneert de waarde van de variabele waarnaar wordt verwezen (dereferentie).
& Dient รฉรฉn doel: het adres van een variabele retourneren.

Soorten aanwijzingen in C

Nul punten

We maken een null-pointer aan door er tijdens de declaratie de waarde NULL aan toe te kennen. Dit is handig wanneer er nog geen adres aan de pointer is toegewezen. Een null-pointer bevat altijd de waarde 0.

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

Ongeldige aanwijzer

Een void-pointer, ook wel een generieke pointer genoemd, heeft geen standaard gegevenstype. Hij wordt aangemaakt met het sleutelwoord `void` en kan het adres van elke variabele opslaan:

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

Wilde Pointer

Een pointer wordt een 'wild pointer' genoemd als deze niet is geรฏnitialiseerd. Deze pointers zijn niet efficiรซnt omdat ze naar een onbekende geheugenlocatie kunnen wijzen, wat problemen kan veroorzaken en het programma kan laten vastlopen. Wees altijd voorzichtig met wild pointers:

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

Andere typen pointers in C zijn onder andere de zwevende pointer, de complexe pointer, de nabije pointer, de verre pointer en de enorme pointer.

Directe en indirecte toegangsaanwijzers

In C zijn er twee gelijkwaardige manieren om de inhoud van een variabele te benaderen en te manipuleren. Directe toegang maakt gebruik van de variabelenaam zelf, terwijl indirecte toegang gebruikmaakt van een pointer naar de variabele:

#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;
}

Wijzer Rekenen in C

Bij het werken met pointers moet je rekening houden met de volgende prioriteitsregels. De operatoren * en & hebben dezelfde prioriteit als de unaire operatoren (negatie !, verhogen ++, verlagen โ€“). In dezelfde expressie worden de unaire operatoren *, &, !, ++ en โ€” van rechts naar links geรซvalueerd. Als een pointer P naar een variabele X wijst, kan *P overal gebruikt worden waar X geschreven kan worden. De volgende expressies zijn equivalent:

Expressie Gelijkwaardige expressie
Y = *P + 1 Y = X + 1
*P = *P + 10 X = X + 10
*P += 2 X += 2
+**P ++X
(*P)++ X++

In het laatste geval zijn haakjes nodig: omdat de unaire operatoren * en ++ van rechts naar links worden geรซvalueerd, zou zonder haakjes de pointer P worden verhoogd in plaats van het object waarnaar deze wijst. De rekenkundige bewerkingen die beschikbaar zijn op pointers zijn toewijzing, verhoging en verlaging, en optellen of aftrekken.tracHet toekennen van een integer-offset, waarmee de pointer met dat aantal elementen wordt verplaatst (elke stap is gelijk aan de grootte in bytes van het basistype).

C-pointers en arrays met voorbeelden

Traditioneel benaderen we array-elementen met behulp van een index, maar pointers maken dit ook eenvoudig. Een pointer die is ingesteld op de arraynaam wijst naar het eerste element:

#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;
}

Door een getal bij een pointer op te tellen, verschuift deze dat aantal elementen vooruit. Als p naar geheugenlocatie 0 wijst, zorgt p + 1 ervoor dat de pointer naar geheugenlocatie 1 wijst.

C Pointers en strings met voorbeelden

Een string is een array van char-objecten die eindigt met een null-teken '\0'. We kunnen strings manipuleren met behulp van pointers:

#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;
}

Een andere manier om met tekenreeksen om te gaan, is met een array van pointers:

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

Voordelen van pointers in C

  • Pointers zijn handig voor het rechtstreeks benaderen van geheugenlocaties.
  • Ze bieden een efficiรซnte manier om toegang te krijgen tot de elementen van een array.
  • Ze worden gebruikt voor dynamische geheugenallocatie en -deallocatie.
  • Ze worden gebruikt om complexe datastructuren te vormen, zoals gekoppelde lijsten, grafieken en bomen.

Nadelen van pointers in C

  • Pointers zijn wat lastig te begrijpen.
  • Ze kunnen fouten veroorzaken zoals segmentatiefouten of toegang tot een onbedoelde geheugenlocatie.
  • Een onjuiste waarde die aan een pointer wordt toegekend, kan leiden tot geheugenbeschadiging.
  • Pointers zijn ook verantwoordelijk voor geheugenlekken als het geheugen niet wordt vrijgegeven.
  • Het is de verantwoordelijkheid van de programmeur om zorgvuldig met een pointer om te gaan.

Veelgestelde vragen

Een zwevende pointer wijst naar geheugen dat is vrijgegeven of buiten het bereik valt. Voorkom dit door de pointer direct na het aanroepen van `free` op `NULL` te zetten en te controleren of deze op `NULL` staat voordat u hem gebruikt.

Het dereferencen van een NULL-pointer veroorzaakt een segmentatiefout en laat het programma vastlopen tijdens de uitvoering. Controleer altijd of een pointer niet NULL is voordat u de operator * gebruikt om te lezen of te schrijven.

Een dubbele pointer, gedeclareerd als int **pp, slaat het adres van een andere pointer op. Deze wordt gebruikt voor dynamische 2D-arrays en om een โ€‹โ€‹pointerargument binnen een functie te wijzigen.

Een pointer slaat een geheugenadres op, en adressen hebben op een bepaald platform dezelfde breedte, doorgaans 4 bytes op 32-bits en 8 bytes op 64-bits, ongeacht het type waarnaar de pointer verwijst.

Een functiepointer slaat het adres van een functie op, zodat deze dynamisch kan worden aangeroepen. Het wordt veel gebruikt voor callbacks en voor het samenstellen van tabellen met functies die tijdens de uitvoering worden geselecteerd.

Functies zoals malloc en calloc retourneren een pointer naar geheugen dat tijdens de uitvoering op de heap is toegewezen. Je hebt toegang tot dat geheugen via de pointer en je geeft het vrij met free om geheugenlekken te voorkomen.

Ja. AI-assistenten lezen een segmentatiefout en de omliggende code, leggen vervolgens de waarschijnlijke oorzaak uit, zoals een niet-geรฏnitialiseerde of vrijgegeven pointer, en stellen een oplossing voor die u kunt controleren.

AI-gestuurde analysetools, samen met tools zoals Valgrind, signaleren geheugen dat nooit wordt vrijgegeven en pointers die na vrijgave nog steeds worden gebruikt. Ze automatiseren de codebeoordeling en markeren risicovolle patronen voordat de code wordt uitgebracht.

Vat dit bericht samen met: