ProgrammatieC ontwikkelaar

Hoe werkt het mechanisme voor het doorgeven van argumenten in functies van de C-taal? Hoe typfouten vermijden bij het doorgeven van variabelen van verschillende types, structuren en arrays?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord.

In de C-taal worden argumenten in functies altijd per waarde doorgegeven. Dit betekent dat de functie een kopie van de waarde van het argument ontvangt. Voor eenvoudige types (int, float) is dit voor de hand liggend: veranderingen binnen de functie beïnvloeden de originele variabele niet. Voor arrays en structuren zijn er nuances:

  • Bij het doorgeven van een array aan een functie wordt eigenlijk de pointer naar het eerste element doorgegeven, niet de hele array. De pointer zelf wordt echter nog steeds per waarde doorgegeven.
  • Voor structuren kan een kopie expliciet per waarde worden doorgegeven, maar het is voordeliger om dit via een pointer te doen — zo kan de functie de oorspronkelijke structuur wijzigen.

Voorbeeld: verwerking van een array en een structuur

#include <stdio.h> typedef struct { int a; int b; } Pair; void modifyArray(int arr[], int size) { arr[0] = 42; // wijzigt de originele array } void modifyStruct(Pair s) { s.a = 100; // verandert alleen de lokale kopie } void modifyStructPtr(Pair *s) { s->a = 200; // wijzigt het origineel via de pointer } int main() { int nums[2] = {1, 2}; Pair p = {10, 20}; modifyArray(nums, 2); modifyStruct(p); modifyStructPtr(&p); printf("nums[0]=%d, p.a=%d\n", nums[0], p.a); // nums[0]=42, p.a=200 return 0; }

Misleidende vraag.

Vraag: Als een functie is gedeclareerd als void func(int arr[10]), heeft deze array binnen de functie altijd 10 elementen?

Antwoord: Nee. De notatie int arr[10] in de argumenten is in feite gelijk aan int *arr — de grootte van de array gaat verloren bij het doorgeven. De functie weet de echte lengte van de array niet, dus neem altijd een extra parameter voor de lengte mee. Anders kunnen er geheugenoverlopen plaatsvinden en UB ontstaan.

Voorbeeld:

void foo(int arr[10]) { printf("%d\n", arr[9]); // arr bevat niet per se 10 elementen! }

Geschiedenis

In een project voor signaalverwerking werd een array door een functie doorgegeven, met de gedachte dat de lengte altijd hetzelfde was, maar in één geval werd een kleinere array doorgegeven. Het resultaat — het aanspreken van geheugengebieden buiten de grenzen, het laten crashen van de applicatie en het ontstaan van onvoorspelbaar gedrag op de controller.


Geschiedenis

In banksoftware werd geprobeerd een structuur te wijzigen door deze per waarde door te geven in plaats van per pointer. Wijzigingen werden niet opgeslagen, waardoor de verwerkingseenheid de status van de rekeningen niet bijwerkte, leidend tot rekenfouten.


Geschiedenis

In een telemetriesysteem voegde een student een functie toe om een array te wissen, maar vergat de lengte door te geven, en de arrays waren van verschillende afmetingen. De fout werd pas ontdekt na het verzamelen van een grote hoeveelheid onjuiste gegevens en een lange tijd van bugopsporing.