Skip to content

Instantly share code, notes, and snippets.

@pjastr
Last active March 17, 2020 14:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pjastr/799a20403b72fc20a1e681ec61c78259 to your computer and use it in GitHub Desktop.
Save pjastr/799a20403b72fc20a1e681ec61c78259 to your computer and use it in GitHub Desktop.

Krótkie wytłumaczenie wskaźników w języku C.

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).

https://youtu.be/SCar2LJv_2Y

##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

Bibliografia:

  1. David Griffiths, Dawn Griffiths, C. Rusz głową!, Wyd. Helion 2013.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment