Historycznie wskaźniki stały się podstawą pracy z pamięcią w języku C i zapewniły elastyczny mechanizm do efektywnego dostępu do elementów tablicy oraz dynamicznych struktur. Niemniej jednak składnia i semantyka wskaźników na tablice oraz tablic wskaźników często wywołują zamieszanie.
Problem: początkujący programiści często mylą wskaźnik na tablicę (pointer to array) i tablicę wskaźników (array of pointers), co prowadzi do niewłaściwego użycia pamięci, błędów w przekazywaniu parametrów i trudnych do skonstruowania błędów składniowych.
Rozwiązanie:
Przykład deklaracji i użycia:
// Wskaźnik na tablicę 10 int: int (*p)[10]; int arr[10]; p = &arr; // Tablica 10 wskaźników na int int *ap[10]; for (int i = 0; i < 10; ++i) { ap[i] = &arr[i]; } // Jak uzyskać element przez wskaźnik na tablicę: (*p)[2] = 5; // trzeci element arr // Jak uzyskać wartość, korzystając z tablicy wskaźników: *ap[2] = 8; // trzeci element arr przez ap
Kluczowe cechy:
**Czy int p[10] i int (p)[10] są takie same?
Nie. int *p[10] to tablica 10 wskaźników na int. int (*p)[10] to wskaźnik na tablicę 10 int. Duże zamieszanie powstaje bez nawiasów!
Przykład kodu:
int arr[10]; int *p[10]; // tablica wskaźników int (*q)[10] = &arr; // wskaźnik na tablicę
*Czy można swobodnie przypisywać zwykły wskaźnik na int do zmiennej typu int (p)[10]?
Nie. Zwykły int * wskazuje na jeden element, a int (*p)[10] — na tablicę 10 całych; typy są niezgodne bez jawnego rzutowania.
Jak poprawnie przekazać dwuwymiarową tablicę do funkcji?
Należy wyraźnie określić rozmiar drugiego wymiaru:
void foo(int a[][4], int n); // tablica n wierszy po 4 elementy
lub użyć wskaźnika na tablicę:
void bar(int (*a)[4], int n);
Inżynier zadeklarował zmienną jako int *p[10], próbował przypisać do niej &arr, gdzie arr — int arr[10] i uzyskać dostęp jako do tablicy, co prowadzi do błędu kompilacji lub niewłaściwego zachowania.
Zalety:
Wady:
Programista starannie używa nawiasów: int (*p)[10], wyraźnie rozumie różnicę, poprawnie przekazuje tablice do funkcji, korzysta z typedef w celu uproszczenia deklaracji.
Zalety:
Wady: