2013-08-21 9 views
5

W przypadku poniższego programu, dlaczego pierwsza printf drukuje różne wartości dla argv i &argv? Drugi printf drukuje tę samą wartość dla a i &a. Jaki jest mechanizm przechowywania zmiennych argumentów do programu?Różne wartości wyjściowe między argv i normalną tablicą ciągów

#include<stdio.h> 
    int main(int argc, char * argv[]){ 
    char * a[10]; 
    printf("%d %d\n\n",argv,&argv); 
    printf("%d %d",a,&a); 
    return 0; 
} 

Jaki jest mechanizm przechowywania argumentów wiersza poleceń do tablicy ciągów

+1

printf ("% d% d", a, &a); tutaj & a i a wskaże ten sam adres ... nie musisz więc drukować ich obu, i użyj% p zamiast% d, aby wydrukować adres. – sunny1304

+0

Myślę, że to dlatego, że wskaźnik argv jest inicjowany, ale twój wskaźnik nie jest tak, że dostał ten sam adres – Saxtheowl

Odpowiedz

5

Problem nie polega na argv jest wyjątkowy, ale o funkcji przejścia argumentów. Wypróbuj ten program:

#include<stdio.h> 

void foo(int a[]) 
{ 
    int b[10]; 
    printf("foo :%p %p\n",a,&a); 
    printf("foo :%p %p\n",b,&b); 
} 

int main(int argc, char* argv[]) 
{ 
    int a[10]; 
    printf("main:%p %p\n", a, &a); 
    foo(a); 
    return 0; 
} 

produkcja w moim komputerze:

main:0x7fffb4ded680 0x7fffb4ded680 
foo :0x7fffb4ded680 0x7fffb4ded628 
foo :0x7fffb4ded630 0x7fffb4ded630 

Pierwsza i trzecia linia nie jest zaskakujące, ponieważ na tablicy arr, arr i &arr mają taką samą wartość. Druga linia musi być wyjaśniona.

Jak widać, gdy a jest przekazywana w funkcji foo wartość a się nie zmieniło, ale adres &a się zmieniło od funkcji C zawsze przekazywać argumenty przez wartość, nie będzie lokalna kopia argumentu wewnątrz funkcji.

To samo dotyczy argv, ponieważ jest to tylko argument funkcji main.


EDIT: Dla tych, którzy nie zgadza się ze mną, moja odpowiedź nie jest w stosunku do drugiej odpowiedzi. Wręcz przeciwnie, uzupełniają się nawzajem. argv jest wskaźnikiem dokładnie dlatego, że jest tablicą, która została przekazana jako argument funkcji i "zepsuła się" do wskaźnika. Ponownie, argv nie jest specjalny, działa tak samo jak inne tablice, które są przekazywane jako argument funkcji, to cały punkt mojego przykładu kodu.

+0

Ładny przykład kodu! Po prostu myślę, że 'argv' w głównej ma jakieś specjalne miejsce zanim zobaczę twoją odpowiedź! –

+0

To nie jest tak naprawdę odpowiedź. Dla każdej zmiennej typu "a" typu tablicowego, '& a' i' a' jako wskaźniki zawsze * będą miały ten sam adres. Jest to wynikiem działania typów tablic w C. Różnica polega na tym, że 'argv' nie jest typu tablicowego. – newacct

+0

@newacct Więc dlaczego 'argv' jest wskaźnikiem? Dokładnie dlatego, że jest przekazywany jako argument funkcji i "zepsuty" do wskaźnika. –

4

Różnica między argv i a w przykładzie z pkt 6.7.6.3 ad 7 do C-standardzie:

deklaracja parametru jako „” tablicy typu „” powinny być dostosowane "kwalifikowany wskaźnik do typu" ", gdzie kwalifikatory typu (jeśli występują) są określone w [i] pochodnej typu tablicowego. Jeśli słowo kluczowe static pojawia się również w obrębie [i] pochodnej typu tablicowego, to dla każdego wywołania funkcji wartość odpowiadającego faktycznego argumentu powinna zapewniać dostęp do pierwszego elementu tablicy z co najmniej taką samą liczbą elementów, jak podano według wyrażenia rozmiaru.

W konsekwencji argv jest wskaźnik, który posiada własny adres, podczas a jest tablicą i a wskazuje na adres pierwszego elementu tablicy, który jest taki sam jak adres tablicy.

+0

+1 To jest prawdziwa odpowiedź – newacct

Powiązane problemy