2011-07-03 28 views
7

Tôi đang học C hôm nay. Tôi đã được mã hóa trong các ngôn ngữ được quản lý (Java, C#, Python, vv) trong một thời gian. Tôi nghĩ rằng tôi đã hiểu được chi tiết của con trỏ, nhưng sau đó tôi đã viết mã sau đây hoạt động như mong đợi, nhưng tạo ra cảnh báo 'loại con trỏ không tương thích'.Làm rõ lý do tại sao mã C này hoạt động

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; 
} 

Vì vậy, tôi googled, và kết thúc việc thay đổi dòng

setText(&output); 

để

setText(output); 

mà đã thoát khỏi những cảnh báo. Nhưng bây giờ tôi không biết tại sao người đầu tiên làm việc gì cả. Tôi đã gửi địa chỉ của một địa chỉ như xa như tôi có thể nói (vì char * x; về cơ bản là giống như char x [];). Tôi đang hiểu lầm gì và tại sao cả hai đều làm việc?

+0

Thật khó để cho bạn biết tại sao 'setText' hoạt động mà không thấy triển khai. Mặc dù, nếu tất cả 'setText' làm được thiết lập một biến, sau đó chương trình thoát, làm thế nào bạn có thể thực sự biết nếu chương trình đang làm những gì bạn muốn? – jwodder

+2

'T *' là * không * giống với 'T [K]'. Xem ví dụ http://c-faq.com/~scs/cgi-bin/faqcat.cgi?sec=aryptr – delnan

+0

@delnan: Liên kết dường như bị hỏng – Cameron

Trả lời

17

Loại của outputchar [10], phân rã đến một char * trong bối cảnh của một cuộc gọi chức năng (đó là lý do các biến thể thứ hai hoạt động).

Loại &outputchar (*)[10], tức là một con trỏ tới mảng. Đây không phải là điều tương tự, do đó cảnh báo trình biên dịch. Tuy nhiên, giá trị của &output (địa chỉ) tương đương với giá trị output (sau khi đã phân rã thành số char *), do đó kết quả cuối cùng là "như mong đợi".

Điều này nghe có vẻ giống như người đi bộ, nhưng có một sự khác biệt khá quan trọng. Hãy thử các cách sau:

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); 
} 

Đề nghị đọc là the C FAQ on arrays and pointers, cụ thể là câu hỏi 6.3 và 6.12.

+1

Và nó "hoạt động" bất chấp cảnh báo vì cả hai đều chỉ đến cùng một vị trí. –

+1

Ví dụ hay. Nó thực sự giúp minh họa những gì đang diễn ra ở đây. – hbw

+0

Có, ví dụ đó đã giúp. Cảm ơn bạn. – atheaos

Các vấn đề liên quan