2014-07-13 7 views
5

Jestem nowy w C i wskaźnikach. Poniżej znajduje się kod, z którym eksperymentowałem.Inny adres wskaźnika wydrukowany wewnątrz funkcji

struct node{ 
    struct node * next; 
    struct node * prev; 
    int num; 
}; 

void func(struct node * leaf , struct node ** add_leaf){ 
    printf("function starts"); 
    printf("&leaf = %p add_leaf = %p\n" , &leaf , add_leaf); 
    printf("leaf = %p *add_leaf = %p\n" , leaf , *add_leaf); 
    printf("function over"); 
    return 
} 


void main(){ 
    struct node * leaf = (struct node*)malloc(sizeof(struct node)); 
    printf("leaf = %p\t&leaf = %p\n" , leaf , &leaf); 
    func(leaf , &leaf); 
} 

Wartości liścia i * add_leaf są równe i to było to, czego się spodziewałem. Jednak nie mogłem zrozumieć, dlaczego wystąpiła różnica w wartościach & liści i add_leaf po wydrukowaniu wewnątrz funkcji. Tutaj próbuję wydrukować adres liścia wskaźnika węzła.

+0

dzięki, dokonano zmiany – user3663685

Odpowiedz

3

Zmienna lokalna leaf w pliku jest kopiowana po wywołaniu func. Oznacza to, że lokalna zmienna leaf wewnątrzma taką samą wartość jak leaf wewnątrz main, tj. Wskazuje na ten sam adres pamięci (a zatem równoważność dla drugiego sprawdzenia), ale sama jest przechowywana pod innym adresem.

+1

... z efektem netto, że parametry stają się zmiennymi lokalnymi. Jeśli więc chcesz potraktować taki, jak wiele innych języków, nazywa się 'inout' lub podobnym - jako coś, co możesz zmodyfikować i który ma tę modyfikację, wpłynąć na wartości podane w zasięgu wywołania - musisz dodać dodatkowy poziom pośredni i modyfikować za pomocą odniesienia do wskaźnika. Jest to (częściowo), dlaczego twój kod przyjmuje "liść" jako wskaźnik: może więc modyfikować rzecz tak, że modyfikacje są bardziej lokalne i przejściowe. – Tommy

0

leaf to wskaźnik do struct node, a wskaźnik to 32-bitowa (w zależności od architektury) liczba całkowita, która jest przechowywana gdzieś w pamięci.

Po przejściu leaf do printf, co się stanie, kopia zmiennej leaf zostanie wykonana na stosie. Ta kopia odpowiada 2. lokalnemu argumentowi funkcji printf.

Ale kiedy przechodzą &leaf do funkcji printf, co możesz zrobić, to przekazać adres zmiennej leaf.

Ponieważ zmienna leaf w main() i drugi argument printf są w dwóch różnych lokalizacjach, rzeczywiście wydrukuje dwa adresy pamięci.

2

Zwykle łatwiej jest zrozumieć wskaźniki, jeśli rysujesz obraz ze strzałkami i polami.

& liść daje adres varible liści, a ponieważ masz dwie różne zmienne nazwie liść (oba zawierające odnośniki do swojej malloc przyznane struct), można uzyskać dwa różne adresy:

enter image description here