2011-07-03 25 views
7

Uczę się dzisiaj C. Już od jakiegoś czasu koduję w zarządzanych językach (Java, C#, Python itp.). Pomyślałem, że rozumiem szczegóły wskaźników, ale potem napisałem poniższy kod działający zgodnie z oczekiwaniami, ale wygenerowałem ostrzeżenie "niekompatybilny typ wskaźnika".Wyjaśnienie, dlaczego ten kod C działa

void setText(char* output) { 
    //code to set output to whatever, no problems here. 
} 

int main(int argc, const char* argv[]) { 
    char output[10]; 

    setText(&output); 

    //[EDITED] ...other test code which printf's and further manipulates output. 

    return 0; 
} 

Więc google, a skończyło się na zmianę linii

setText(&output); 

do

setText(output); 

który pozbył się ostrzeżenia. Ale teraz nie wiem, dlaczego ten pierwszy w ogóle działał. Przesyłam adres adresu, o ile wiem (ponieważ char * x; jest w zasadzie taki sam jak char x [];). Co ja nie rozumiem i dlaczego oba te elementy działają?

+0

Trudno powiedzieć, dlaczego 'setText' działał, nie widząc jego implementacji. Chociaż, jeśli wszystkie 'setText' nie ustawi zmienną, po której program się kończy, jak możesz naprawdę stwierdzić, czy program robi to, co chcesz? – jwodder

+2

'T *' to * nie * jest takie samo jak 'T [K]'. Zobacz np. http://c-faq.com/~scs/cgi-bin/faqcat.cgi?sec=aryptr – delnan

+0

@delnan: Link wydaje się zepsuty – Cameron

Odpowiedz

17

Typ z output jest char [10], który rozpada się do char * w kontekście wywołania funkcji (co jest dlaczego drugi wariant działa).

Typ &output to char (*)[10], tj. Wskaźnik do tablicy. To nie jest to samo, stąd ostrzeżenie kompilatora. Jednak wartość o wartości z &output (adres) jest równa wartości output (po zepsuciu się do char *), więc wynik końcowy jest "zgodny z oczekiwaniami".

To może brzmieć jak pedantia, ale jest dość ważna różnica. Wypróbuj następujące:

void foo(const char *p) 
{ 
    printf("%s\n", p); 
} 

int main(void) 
{ 
    char output[][6] = { "Hello", "world" }; 

    foo(output[0] + 1); 
    foo(&output[0] + 1); 
} 

Zalecane jest następujące czytanie: the C FAQ on arrays and pointers, w szczególności pytanie 6.3 i 6.12.

+1

I to "działa" pomimo ostrzeżenia, ponieważ oba kończą się wskazując na to samo miejsce. –

+1

Dobry przykład. To naprawdę pomaga zilustrować, co się tutaj dzieje. – hbw

+0

Tak, ten przykład pomógł. Dziękuję Ci. – atheaos