Przeanalizujmy poniższy kod:
int y=1;
int main()
{
int x=7;
printf("x zapisano pod adresem %#010x\n", &x);
return 0;
}
Przykładowe wyjście:
x zapisano pod adresem 0x0060ff0c
&
jest operatorem adresu. Adres zmiennej informuje, jakie jest jej położenie w pamięci. To właśnie dlatego adresy nazywamy wskaźnikami — wskazują one miejsce zmiennej w pamięci.
Przeanalizujmy kod:
void idzPrawoDol(int x, int y)
{
x=x+1;
y=y-1;
}
int main()
{
int x=20, y=15;
idzPrawoDol(x,y);
printf("Aktualna pozycja: [ %d, %d ] \n",x,y);
return 0;
}
Na wyjściu otrzymujemy:
Aktualna pozycja: [ 20, 15 ]
Dlaczego tak się dzieje?
W języku C argumenty przekazywane są przez wartość.
Na początku funkcji main
mamy dwie zmienne:
Podczas wykonywania funkcji idzPrawoDol
następuje kopiowanie wartości do zmiennych lokalnych:
a potem zmiana zmiennych lokalnych:
Jak to naprawić? Użyjemy wskaźników.
void idzPrawoDol(int *x, int*y)
{
*x=*x+1;
*y=*y-1;
}
int main()
{
int x=20, y=15;
idzPrawoDol(&x,&y);
printf("Aktualna pozycja: [ %d, %d ] \n",x,y);
return 0;
}
Aktualna pozycja: [ 21, 14 ]
Ważne, że poniższe zapisy są równoważne:
int* x;
int * x;
int *x;
int*x;
Jak to wytłumaczyć?
Operatory *
oraz &
są przeciwieństwami. Operator &
, dysponując pewnymi danymi, określa ich adres. Z kolei operator *
na podstawie adresu zwraca wartość zapisaną w danym miejscu pamięci. Wskaźniki są czasami nazywane referencjami, mówi się, że operator *
stanowi dereferencję wskaźnika (inaczej wyłuskaniem).
##O co chodzi z 0x
?
Zamiast kodu na początku możemy otrzymać "prawdziwą" liczbę w systemie szesnastkowym:
int main()
{
int x=7;
printf("x zapisano pod adresem %#010x\n", &x);
return 0;
}
W programowaniu w C częściej używa się notacji z perfiksem 0x
na oznaczenie systemu szesnastkowego https://pl.wikipedia.org/wiki/Szesnastkowy_system_liczbowy
Dłuższa historia https://stackoverflow.com/questions/2670639/why-are-hexadecimal-numbers-prefixed-with-0x
- David Griffiths, Dawn Griffiths, C. Rusz głową!, Wyd. Helion 2013.