2010-01-10 44 views
31

Trong các quy tắc sau đây đối với trường hợp khi mảng phân rã để con trỏ:Literal chuỗi khởi tạo cho một mảng ký tự

Một giá trị trái [xem câu hỏi 2,5] của kiểu mảng-of-T xuất hiện trong một biểu thức phân rã (với ba ngoại lệ) thành một con trỏ đến phần tử đầu tiên của nó; loại con trỏ kết quả là con trỏ tới T.

(Các trường hợp ngoại lệ là khi mảng là các toán hạng của một nhà điều hành sizeof hoặc &, hoặc là một chuỗi initializer đen cho một mảng ký tự.)

Làm thế nào để hiểu được những trường hợp khi mảng là "đen string initializer cho một mảng ký tự "? Một số ví dụ xin vui lòng.

Cảm ơn!

+1

Liên quan: [Ngoại lệ đối với mảng không phân rã thành con trỏ?] (Http://stackoverflow.com/questions/17752978/exception-to-array-not-decaying-into-a-pointer) – legends2k

Trả lời

39

Ba trường hợp ngoại lệ, nơi một mảng không phân hủy thành một con trỏ như sau:

Exception 1. - Khi mảng là các toán hạng của sizeof.

int main() 
{ 
    int a[10]; 
    printf("%zu", sizeof(a)); /* prints 10 * sizeof(int) */ 

    int* p = a; 
    printf("%zu", sizeof(p)); /* prints sizeof(int*) */ 
} 

Exception 2. - Khi mảng là các toán hạng của toán tử &.

int main() 
{ 
    int a[10]; 
    printf("%p", (void*)(&a)); /* prints the array's address */ 

    int* p = a; 
    printf("%p", (void*)(&p)); /*prints the pointer's address */ 
} 

ngoại lệ 3. - Khi mảng được khởi tạo với một chuỗi chữ.

int main() 
{ 
    char a[] = "Hello world"; /* the literal string is copied into a local array which is destroyed after that array goes out of scope */ 

    char* p = "Hello world"; /* the literal string is copied in the read-only section of memory (any attempt to modify it is an undefined behavior) */ 
} 
+1

Tôi thích câu trả lời của bạn tốt hơn nhiều trước tất cả các chỉnh sửa. Nói ngắn gọn và trả lời câu hỏi. Bây giờ nó trả lời rất nhiều câu hỏi mà thậm chí không được hỏi. :-) –

+0

Cảm ơn Prasson. Một số câu hỏi: (1) trong ngoại lệ 3, vì vậy ở đây lvalue "Xin chào thế giới" là khởi tạo chuỗi chữ của mảng char "a", và do đó "Hello world" không phân rã thành một con trỏ? (2) trong Ngoại lệ 2, là "& a" giống với địa chỉ của phần tử đầu tiên của mảng "a"? – Tim

+0

Câu trả lời là (1) có, (2) không. Đối với (2), trên hầu hết các máy tính, nếu bạn in các giá trị, chúng sẽ in giống nhau (tôi không biết bất kỳ nơi nào chúng sẽ không). Nhưng '& a' trỏ tới toàn bộ mảng trong khi' & a [0] 'trỏ tới phần tử đầu tiên của' a'. Vì vậy, nếu bạn in '& a + 1' và' & a [0] + 1', chúng sẽ khác nhau ngay cả khi '& a' và' & a [0] 'in cùng một giá trị. –

5

Đây là một chuỗi initializer đen cho một mảng ký tự:

char arr[] = "literal string initializer"; 

cũng có thể là:

char* str = "literal string initializer"; 

Từ K & R2:

Một chuỗi chữ, cũng được gọi là chuỗi không đổi, là một chuỗi các ký tự sur được làm tròn bằng dấu ngoặc kép như trong "...". Một chuỗi có loại `` mảng là ký tự '' và lớp lưu trữ tĩnh (xem mục Par.A.3 bên dưới) và được khởi tạo với các ký tự đã cho. Cho dù các chuỗi ký tự giống hệt nhau là riêng biệt được thực hiện xác định và hành vi của một chương trình cố gắng để thay đổi một chuỗi chữ là không xác định.

+3

Như Prasoon đề cập đến, đây không phải là điều tương tự –

+0

Cảm ơn, Eli. Vì vậy, trong những ví dụ này, chuỗi iniitalizer dạng chuỗi là gì? Và "Giá trị của loại mảng-T" là gì không phân rã thành con trỏ? – Tim

+0

Đã trả lời câu hỏi sai. – cdosborn

2

Nó có vẻ như bạn kéo mà trích dẫn từ FAQ comp.lang.c (có thể một phiên bản cũ hoặc có thể phiên bản in; nó không hoàn toàn phù hợp với tình trạng hiện tại của một trực tuyến):

http://c-faq.com/aryptr/aryptrequiv.html

Phần tương ứng liên kết với các phần khác của Câu hỏi thường gặp để giải thích những ngoại lệ đó.Trong trường hợp của bạn, bạn nên xem xét:

http://c-faq.com/decl/strlitinit.html

7

Giả tờ khai

char foo[] = "This is a test"; 
char *bar = "This is a test"; 

Trong cả hai trường hợp, các loại chuỗi chữ "This is a test" là "mảng 15 phần tử của char" . Trong hầu hết các trường hợp, các biểu thức mảng được chuyển đổi hoàn toàn từ loại "phần tử N thành phần của T" thành "con trỏ đến T" và biểu thức đánh giá đến địa chỉ của phần tử đầu tiên của mảng. Trong tuyên bố cho bar, đó là chính xác những gì sẽ xảy ra.

Trong tuyên bố cho foo, tuy nhiên, biểu thức đang được sử dụng để khởi tạo nội dung một mảng khác và do đó, không phải là được chuyển thành loại con trỏ; thay vào đó, nội dung của chuỗi ký tự được sao chép vào foo.

+0

+1 cho câu trả lời rõ ràng và ngắn gọn; có lẽ là người duy nhất ở đây để cho thấy rằng ngoại lệ là về chuỗi _literal và không phải là mảng char nó được gán cho (cho rằng cả hai đều là mảng ký tự). – legends2k

+0

'" Đây là một thử nghiệm "' như một chuỗi khởi tạo ** là ** một mảng. Như một biểu thức nó không phân rã thành một con trỏ nhưng vẫn là một mảng. Xuất sắc. – cdosborn

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