ProgrammatieSysteemprogrammeur

Kunt u gedetailleerd uitleggen over de mechanismen voor het doorgeven van parameters in functies in de programmeertaal C: per waarde en per pointer? Geef voorbeelden wanneer het gebruik van elk van de benaderingen gerechtvaardigd is.

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord.

In de programmeertaal C worden parameters in functies altijd per waarde doorgegeven — dat wil zeggen, een kopie van de waarde uit de aanroepende code wordt naar de functie doorgegeven. Als het nodig is om de waarde van een variabele buiten de functie te veranderen, wordt pointer-parameter doorgegeven.

Doorgeven per waarde

Bij het doorgeven van een scalair (bijvoorbeeld, int) ontvangt de functie zijn eigen kopie:

void foo(int a) { a = 10; } int main() { int x = 5; foo(x); // x == 5, verandert niet! }

Doorgeven per pointer

Om de waarde van een variabele te veranderen, gebruiken we een pointer:

void foo(int* a) { *a = 10; } int main() { int x = 5; foo(&x); // x == 10, waarde is veranderd! }

Wanneer pointer gebruiken

  • Het is nodig om meerdere waarden terug te geven.
  • Grote structuren veranderen (bespaart tijd en geheugen, geen kopieën).
  • Voor het werken met arrays (ze worden altijd als pointer doorgegeven).

Misleidende vraag.

Is een array een parameter van de functie die per referentie wordt doorgegeven?

Veel mensen antwoorden "per referentie", maar in C kan een array in de functiehandtekening niet per referentie worden doorgegeven; feitelijk degradeert het naar een pointer.

Juiste antwoord:

Wanneer een array naar een functie wordt doorgegeven, wordt feitelijk een pointer naar het eerste element doorgegeven. Dat wil zeggen dat de aangeroepen functie de werkelijke grootte van de array niet weet, en eventuele wijzigingen aan de elementen van de array reflecteren op de originele array.

void foo(int arr[]) { arr[0] = 100; } int main() { int a[3] = {1,2,3}; foo(a); // a[0] wordt 100! }

Geschiedenis


In één project werkte een functie die waarden van een array die was gedeclareerd als int arr[10] bijwerkte, maar in de aanroepende code was de array kleiner. Omdat de functie de werkelijke grootte niet kende, vond er een buffer overflow en geheugenbeschadiging plaats.


In een ander geval werd vanwege het doorgeven van een structuur per waarde naar de functie, een groot blok geheugen verschillende keren gekopieerd, wat leidde tot prestatieproblemen van de applicatie.


De ontwikkelaar verwachtte dat het doorgeven van een scalair "per referentie" (via een pointer) de onveranderlijkheid van de oorspronkelijke waarde zou garanderen, maar wijzigde per ongeluk het geheugen buiten het bereik (fout in pointer-aritmetiek), wat leidde tot onvoorspelbare resultaten.