Historia pytania:
Arytmetyka wskaźników powstała w języku C, aby zapewnić efektywną pracę z pamięcią, tablicami i strukturami. Jest ściśle związana z adresowaniem pamięci i tym, jak C działa на najniższym poziomie — dodawanie lub odejmowanie od wskaźnika pozwala uzyskać dostęp do kolejnych elementów tablicy.
Problem:
Główną trudnością jest to, że arytmetyka wskaźników nie jest równoważna arytmetyce liczb: dodanie 1 do wskaźnika zwiększa jego wartość o rozmiar typu, na który wskazuje. Klasyczne błędy to: wychodzenie poza granice przydzielonej tablicy, praca z wskaźnikami niekompatybilnych typów oraz próby obliczeń z void *.
Rozwiązanie:
Zawsze należy uwzględniać rozmiar typu podczas pracy z wskaźnikami, unikać obliczeń algebraicznych z void*, kontrolować granice tablicy. Do uzyskania dostępu do elementu tablicy używać indeksacji lub obliczonych wskaźników, wcześniej sprawdzając granice.
Przykład kodu:
#include <stdio.h> int main() { int arr[5] = {1, 2, 3, 4, 5}; int *p = arr; printf("%d ", *(p + 2)); // 3 // Niedopuszczalne: p + 10 wychodzi poza granice tablicy return 0; }
Kluczowe cechy:
Czy można dodawać do wskaźnika wartości typu float lub zmienne innych typów?
Nie, do wskaźników można dodawać lub odejmować tylko wartości typu całkowitego. Użycie zmiennej zmiennoprzecinkowej spowoduje błąd kompilacji.
*Czy (arr + i) i arr[i] zawsze zwracają to samo, nawet jeśli i wychodzi poza granice tablicy?
Nie. Semantycznie są równoważne, ale jeśli indeks wychodzi poza granice tablicy, oba wyrażenia prowadzą do nieokreślonego zachowania (undefined behavior).
Co się stanie, gdy odejmiemy wskaźniki wskazujące na różne tablice?
Wynik nie jest zdefiniowany przez standard i jest uznawany za błąd. Można odejmować tylko wskaźniki znajdujące się w ramach jednej tablicy (lub pamięci przydzielonej jednym blokiem).
buffer overrun)W kodzie programista używa arytmetyki wskaźników do przeszukiwania tablicy:
Zalety:
Wady:
W wersji po refaktoryzacji używa się jawnych kontroli granic na każdym kroku:
Zalety:
Wady: