ProgrammationDéveloppeur C

Comment fonctionne le mécanisme de passage des arguments aux fonctions en C ? Comment éviter les erreurs typiques lors du passage de variables de types différents, structures et tableaux ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

En C, les arguments des fonctions sont toujours passés par valeur. Cela signifie que la fonction reçoit une copie de la valeur de l'argument. Pour les types simples (int, float), c'est évident : les modifications à l'intérieur de la fonction n'affectent pas la variable d'origine. Pour les tableaux et les structures, il y a des nuances :

  • Lors du passage d'un tableau à une fonction, c'est en fait un pointeur vers son premier élément qui est passé, et non le tableau entier. Cependant, le pointeur lui-même est toujours passé par valeur.
  • Pour les structures, on peut explicitement passer une copie (par valeur), mais il est souvent plus avantageux de le faire via un pointeur — ainsi, la fonction pourra modifier la structure d'origine.

Exemple : traitement d'un tableau et d'une structure

#include <stdio.h> typedef struct { int a; int b; } Pair; void modifyArray(int arr[], int size) { arr[0] = 42; // modifie le tableau d'origine } void modifyStruct(Pair s) { s.a = 100; // change seulement la copie locale } void modifyStructPtr(Pair *s) { s->a = 200; // change l'original via le pointeur } 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 ", nums[0], p.a); // nums[0]=42, p.a=200 return 0; }

Question piège.

Question : Si la fonction est déclarée comme void func(int arr[10]), le tableau à l'intérieur de la fonction aura-t-il toujours 10 éléments ?

Réponse : Non. L'écriture int arr[10] dans les arguments équivaut en fait à int *arr — la taille du tableau est perdue lors du passage. La fonction ne connaît pas la longueur réelle du tableau, donc prenez toujours un paramètre supplémentaire avec sa longueur. Sinon, vous risquez de sortir des limites du tableau et d'avoir un comportement indéfini (UB).

Exemple :

void foo(int arr[10]) { printf("%d ", arr[9]); // arr ne contient pas nécessairement 10 éléments ! }

Histoire

Dans un projet de traitement de signaux, on a passé un tableau à travers une fonction en pensant que sa longueur était toujours la même, mais dans un cas, un tableau plus petit a été passé. Résultat : accès hors mémoire, plantage de l'application et comportement imprévisible sur le contrôleur.


Histoire

Dans un logiciel bancaire, on a essayé de modifier une structure en la passant par valeur, et non par pointeur. Les modifications n'étaient pas enregistrées, ce qui a empêché le module de traitement de mettre à jour l'état des comptes, entraînant des erreurs dans les calculs.


Histoire

Dans un système de télémétrie, un étudiant a ajouté une fonction de nettoyage d'un tableau, mais a oublié de passer la longueur, et les tableaux avaient des tailles différentes. L'erreur n'a été détectée qu'après la collecte d'un grand volume de données incorrectes et un long temps de recherche de bugs.