W języku C parametry w funkcji zawsze są przekazywane przez wartość — to znaczy, kopia wartości z wywołującego kodu jest przekazywana do funkcji. Jeśli konieczne jest zmienienie wartości zmiennej poza funkcją, używa się przekazywania przez wskaźnik.
Podczas przekazywania skalaru (np. int) funkcja otrzymuje swoją kopię:
void foo(int a) { a = 10; } int main() { int x = 5; foo(x); // x == 5, nie zmieni się! }
Aby zmienić wartość zmiennej, używa się wskaźnika:
void foo(int* a) { *a = 10; } int main() { int x = 5; foo(&x); // x == 10, wartość się zmieniła! }
Czy tablica jest parametrem funkcji przekazywanym przez referencję?
Wielu odpowiada, że "przez referencję", jednak w C tablica w sygnaturze funkcji nie może być przekazana przez referencję, w rzeczywistości degraduje do wskaźnika.
Poprawna odpowiedź:
Gdy tablica jest przekazywana do funkcji, w rzeczywistości przekazywany jest wskaźnik na jej pierwszy element. To znaczy, wywoływana funkcja nie zna rzeczywistego rozmiaru tablicy, a wszelkie zmiany elementów tablicy są odzwierciedlane w oryginalnej tablicy.
void foo(int arr[]) { arr[0] = 100; } int main() { int a[3] = {1,2,3}; foo(a); // a[0] będzie 100! }
Historia
int arr[10], ale w kodzie wywołującym tablica miała mniejszy rozmiar. Z powodu tego, że funkcja nie znała faktycznego rozmiaru, wystąpiło przepełnienie bufora i uszkodzenie pamięci.