Kiedy używać wskaźników a kiedy zwykłych zmiennych?
Można powiedzieć, że używasz "zwykłej zmiennej" jeśli interesuje Cię po prostu wartość danej zmiennej i nic więcej. Klasycznie to będzie coś w stylu:
int sum(int a, int b)
{
return a + b;
}
Tutaj mamy przekazać do funkcji wartości i zwrócić ich sumę. Jednak jeśli przekazujemy jakiś duży obiekt, np dużego stringa/obszar pamięci i chcemy mu policzyć sumę kontrolną (a może to mieć np. 10MB) więc unikamy kopiowania danych i wtedy przekazujemy do funkcji wskaźnik:
int getCRC(char *buff, int size)
{
.... // przelecenie sie po calej pamieci i policznie sumy kontrolnej
return crc;
}
Bo trzeba wiedzieć, że wywołując funkcję i przekazując do niej jakiś parametr tworzona jest nowa zmienna lokalna w funkcji na podstawie źródłowej. Nic nie stoi na przeszkodzie przekazać wartość buff
przez wartość, ale co jeśli będzie on miał rozmiar 1GB? Wtedy będzie trzeba całość skopiować do zmiennej lokalnej, co zajmie czas, może nie starczyć miejsca na stosie itp. Dlatego aby uniknąć zbędnego kopiowania przekazujemy adres bufora z rozmiarem i już ;) O ile w przypadku pierwszej sytuacji skopiowanie dwóch zmiennych typu int
będzie szybkie i bez znaczenia, to już kopiowanie całego bufora który ma potencjalnie nie wiadomo ile GB jest bez sensu.
Z tego co wyżej napisałem wynika coś ciekawego. Funkcja działa na swoich lokalnych kopiach, więc taka funkcja:
void swap(int a, int b)
{
int temp;
temp = a;
a = b;
b = temp;
}
zamieni swoje lokalne zmienne, więc jeśli damy:
void swap(int a, int b);
int x = 123;
int y = 666;
swap(x,y);
printf (x=%d, y=%d, x, y);
wypisze, że dalej x=123, y=666
Przekazanie wskaźników do zmiennych x oraz y pozwoli na zamianę już zmiennych np z funkcji wywołującej:
void swap(int *a, int *b);
int x = 123;
int y = 666;
swap(&x,&y);
printf (x=%d, y=%d, x, y);
w tym przypadku już poprawnie będzie wypisane x=666, y=123
Zwróć uwagę na zapis swap(&x,&y);
z wykorzystaniem operatora pobrania adresu zmiennej &
w wywołaniu funkcji swap
Przy okazji, kod pisany z palca, bez sprawdzenia w IDE, więc mogą być literówki ;)