Istnieje kilka trudności ze wskaźnikami:
- Aliasing Możliwość zmiany wartości obiektu przy użyciu różnych nazw / zmiennych.
- Brak lokalizacji Możliwość zmiany wartości obiektu w kontekście innym niż ten, w którym jest deklarowana (dzieje się tak również w przypadku argumentów przekazywanych przez referencję).
- Niezgodność czasu życia Czas życia wskaźnika może różnić się od czasu życia obiektu, na który wskazuje, co może prowadzić do nieprawidłowych odwołań (SEGFAULTS) lub śmieci.
- Wskaźnik arytmetyczny . Niektóre języki programowania pozwalają na manipulowanie wskaźnikami jako liczbami całkowitymi, co oznacza, że wskaźniki mogą wskazywać w dowolnym miejscu (w tym w najbardziej nieoczekiwanych miejscach, w których występuje błąd). Aby poprawnie używać arytmetyki wskaźników, programista musi być świadomy wielkości pamięci wskazywanych obiektów, i to jest coś więcej do przemyślenia.
- Rzutowanie typu Zdolność rzutowania wskaźnika z jednego typu na inny pozwala na zastąpienie pamięci obiektu innego niż zamierzony.
Właśnie dlatego programista musi dokładniej przemyśleć, kiedy używa wskaźników (nie wiem o dwóch poziomach abstrakcji ). Oto przykład typowych błędów popełnianych przez nowicjusza:
Pair* make_pair(int a, int b)
{
Pair p;
p.a = a;
p.b = b;
return &p;
}
Zauważ, że kod podobny do powyższego jest całkowicie rozsądny w językach, które nie mają pojęcia wskaźników, ale raczej jedną z nazw (referencji), obiektów i wartości, jako funkcjonalne języki programowania i języki z odśmiecaniem (Java, Python). .
Trudność z funkcjami rekurencyjnymi występuje, gdy ludzie bez wystarczającego zaplecza matematycznego (gdzie rekurencyjność jest powszechna i wymagana wiedza) próbują do nich podejść, myśląc, że funkcja będzie zachowywać się inaczej w zależności od tego, ile razy była wcześniej wywoływana . Problem ten nasila się, ponieważ funkcje rekurencyjne mogą być rzeczywiście tworzone w sposób, w jaki trzeba myśleć w ten sposób, aby je zrozumieć.
Pomyśl o funkcjach rekurencyjnych z przekazywanymi wskaźnikami, jak w proceduralnej implementacji drzewa czerwono-czarnego, w którym struktura danych jest modyfikowana na miejscu; jest to coś trudniejszego do myślenia niż funkcjonalny odpowiednik .
Nie jest to wspomniane w pytaniu, ale innym ważnym problemem, z którym nowicjusze mają trudności, jest współbieżność .
Jak wspomnieli inni, istnieje dodatkowy, nie konceptualny problem z niektórymi konstrukcjami języka programowania: jest tak, że nawet jeśli zrozumiemy, proste i uczciwe błędy w tych konstrukcjach mogą być niezwykle trudne do debugowania.