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 :
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 : 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.