2013-05-12 16 views
5

Program:Wskaźniki i alokacji pamięci w C

int x; 
int *y; 
int **z; 

z = (int **) malloc (sizeof(int *)); 
y = (int *) malloc (sizeof(int)); 
x = 1; 
*z = &x; 
*y = x; 
. 
. 
. 

Pytanie: Jaka jest różnica między:

*z = &x; 
*y = x; 

z tego co rozumiem * Z wskazuje na adres xi * y punktów do x, ale dla * y do wskazania x nie wymaga adresu x? Naprawdę nie rozumiem, co się dzieje z tymi dwoma zmiennymi.

Edycja: Chcę również wiedzieć, kiedy wiemy, kiedy zmienna jest przydzielana na stosie lub na stercie?

  • Dlaczego na stosie są przydzielane x, yi z?
  • Dlaczego wartości * y, ** y, * z, ** z są przydzielane do sterty?

Wreszcie zmienia się * z, zmień ** z?

+0

"Z tego co rozumiem ..." Nie rozumiesz. z i y nadal wskazują dowolny blok pamięci, na który wskazywali, kiedy je przydzieliliście. –

+0

Nie należy rzutować wartości zwracanej przez 'malloc()' w C. Pomoże to zidentyfikować błąd braku prototypu dla niego. – jxh

+1

Przede wszystkim musisz zrozumieć, że te dwa ostatnie stwierdzenia są całkowicie różne. Pierwszy przypisuje * adres * x do dowolnych punktów z, podczas gdy drugi przydziela * wartość * x do dowolnego punktu y. Jeśli przypiszesz wartość, to oryginał i kopia staną się "rozłączone", tak że zmiana jednego nie zmieni drugiego. Ale kiedy użyjesz tylko adresu, te dwie są połączone przy biodrze - zmień je i zmień drugie. –

Odpowiedz

6

z to wskaźnik do wskaźnika (który zazwyczaj wskazuje na dynamicznie przydzieloną tablicę wskaźników).

y to wskaźnik do int. Ponownie, częściej niż wskaże dynamicznie przydzieloną tablicę z int s.

Zatem *z = &x; ustawia wskaźnik, który oznacza z na punkt o numerze x. Tj. z wskazuje na wskaźnik, który (z kolei) wskazuje na x.

*y = x; bierze wartośćz x i przypisanie go do int wskazywanego przez y.

W takich sytuacjach często pomocne jest zdjęcie.Tak więc, nasze podstawowe definicje dają nam ten:

enter image description here

robimy:

z = (int **) malloc (sizeof(int *)); 
y = (int *) malloc (sizeof(int)); 

Który nam daje to:

enter image description here

Następnie robimy:

*z = &x; 
*y = x; 

Który daje nam to:

enter image description here

We wszystkich z nich, przerywana linia oznacza wskaźnik z jednego miejsca do drugiego, podczas gdy linia ciągła wskazuje kopiowanie wartości z jednego miejsca do drugiego.

Możemy następnie rozważyć długoterminowe różnice między nimi. Rozważmy na przykład, co się stanie, jeśli dodamy x=2; po wszystkich zadaniach powyżej.

W tym przypadku *y będzie nadal wynosić 1, ponieważ skopiowana wartość 1 z x do *y. **z będzie jednak równy 2, ponieważ jest to tylko wskaźnik do x - każda zmiana w x zostanie odzwierciedlona w **z.

2

Linia ta przechowuje adres zmiennej x w pamięci wskazywanego przez z:

*z = &x; 

Linia ta przechowuje wartość z x w pamięci wskazywanego przez y:

*y = x; 

Dwie instrukcje przypisania są niepowiązane: druga tworzy kopię, wh ile ten pierwszy nie. Jeśli zmienisz wartość x, a następnie pobierzesz **z, zobaczysz nową wartość x; jednak pobranie *y przywróci poprzednią wartość x (tj. 1).

+0

Dziękujemy! To ma sens! –

0

różnica między dwoma zadań że pierwszy (* z) jest przypisanie do typu adresu jako wartość wskaźnika, gdzie druga (* Y) przypisanie wartości do adresu wskazywanego przez y.

oba przypisują wartości do pamięci, do której są wskazane.

Różnica polega na typie wartości zapisanej w przydzielonej pamięci. pierwsza wartość jest adresem i dlatego dostaje adres x jako wartość. Druga wartość jest liczbą całkowitą i tam dostaje wartość x.

* y nie wskazuje na x.

wskazuje na nieznaną lokalizację w pamięci, do której kopiowana jest wartość x. to przypisanie wartości x do przestrzeni pamięci przydzielonej dla y.