2011-11-23 34 views
10

Nếu tôi viết:Khởi tạo char mảng với String nhỏ Literal

char arr[8] = "abc"; 

Có bất kỳ đặc điểm kỹ thuật hơn những gì arr[4] có thể? Tôi đã làm một số xét nghiệm với Clang và có vẻ như các ký tự còn lại trong mảng được đặt thành rỗng. Ngoài ra, char arr[8] = ""; zeroes mỗi byte. Không chắc chắn nếu đây là một biên dịch thuận tiện, hành vi tiêu chuẩn, trùng hợp ngẫu nhiên hoặc tôi đã nhận nó sai.


void a() 
{ 
    char arr[8] = "abc"; /* breakpoint here, line 3 */ 
    strcpy(arr, "1234567"); 
} 
int main() 
{ 
    a(); 
    a(); 
    return 0; 
} 

Debugger bảng điểm:

 
Breakpoint 1, a() at str.c:3 
3   char arr[8] = "abc"; 
(gdb) s 
Current language: auto; currently minimal 
4   strcpy(arr, "1234567"); 
(gdb) p arr 
$1 = "abc\000\000\000\000" 
(gdb) c  
Continuing. 

Breakpoint 1, a() at str.c:3 
3   char arr[8] = "abc"; 
(gdb) p arr 
$2 = "1234567" 
(gdb) s 
4   strcpy(arr, "1234567"); 
(gdb) p arr 
$3 = "abc\000\000\000\000" 
+0

@Lundin - trên thực tế, arr [3] được thiết lập để null-chấm dứt, vì vậy ông ấy đúng để hỏi về arr [4] –

+0

@JamesCaccese Có vẻ là một lỗi đánh máy ... anyway, tất cả đều được giải thích trong câu trả lời tôi đăng. – Lundin

+0

@Lundin - ai là lỗi đánh máy, của bạn hay @ sidyll's? Nhận xét của bạn ở trên rằng arr [4] được đặt thành null-chấm dứt vì "" là sai. arr [3] được đặt thành null-termination vì "", arr [4] được đặt thành 0 vì nó không được khởi tạo một cách rõ ràng. Câu trả lời của bạn dưới đây là chính xác, nhưng nhận xét của bạn bị tắt bởi một và nó gây nhầm lẫn vấn đề. Vì bạn không thể chỉnh sửa nhận xét, có thể bạn nên xóa nhận xét đó. –

Trả lời

16

Đó là hành vi tiêu chuẩn.

arr[3] được khởi tạo thành 0 vì điểm dừng 0 là một phần của chuỗi ký tự.

Tất cả các yếu tố còn lại được khởi tạo 0 quá - ISO/IEC 9899:1999, 6.7.8, 21:

Nếu có ít initializers trong một danh sách cú đúp kín hơn có những yếu tố hoặc thành viên của một tổng hợp, hoặc ít ký tự trong chuỗi ký tự được sử dụng để khởi tạo một mảng có kích thước đã biết hơn số phần tử trong mảng, phần còn lại của tổng hợp sẽ là được khởi tạo hoàn toàn giống như đối tượng có thời lượng lưu trữ tĩnh.

char đối tượng với dung lượng tĩnh được khởi tạo là 0.

+0

Cảm ơn bạn đã tham khảo tiêu chuẩn. – sidyll

+0

... nhưng điều đó chỉ được định nghĩa cho một danh sách kèm theo cú đúp, đó không phải là mã được sử dụng trong câu hỏi, phải không? – kusma

+1

Không, "... hoặc ít ký tự hơn trong chuỗi ký tự ...". –

3

Đây là hành vi tiêu chuẩn. Mỗi phần tử của một mảng không được khởi tạo rõ ràng được khởi tạo thành giá trị mặc định ('\0' cho char), nếu bất kỳ tiền tố nào của mảng được khởi tạo trong khai báo. Nó cũng hoạt động cho các loại khác:

int a[10] = {1}; 

zeroes out a[1] qua a[9].

0

Theo tiêu chuẩn, tất cả các chỉ số vượt quá những gì được quy định sẽ được thiết lập để không/null. Thêm thông tin trong this SO post

7
char arr[8] = "abc"; 

là hoàn toàn tương đương với

char arr[8] = {'a', 'b', 'c', '\0'}; 

ISO C 6.7.8 §21 bang mà

Nếu có ít initializers trong một cú đúp kín danh sách hơn có là các thành phần hoặc thành viên của tổng hợp hoặc ít ký tự hơn trong một số chuỗi ký tự được sử dụng để khởi tạo một mảng có kích thước đã biết hơn có là các phần tử trong mảng, phần còn lại của tổng hợp sẽ là được khởi tạo hoàn toàn giống như đối tượng có thời lượng lưu trữ tĩnh .

Trong tiếng Anh đơn giản này có nghĩa là tất cả các giá trị vào cuối mảng của bạn sẽ được thiết lập là 0. Vì vậy, đảm bảo tiêu chuẩn mà mã của bạn là tương đương với:

char arr[8] = {'a', 'b', 'c', '\0', 0, 0, 0, 0}; 

Bây giờ tất nhiên, '\ 0 'cũng có giá trị bằng 0.

Quy tắc này là phổ quát cho tất cả các mảng chứ không chỉ cho chuỗi. Ngoài ra, điều tương tự cũng áp dụng khi khởi tạo cấu trúc nhưng chỉ thiết lập rõ ràng một vài thành viên của nó (6.7.8 §18).


Đây là lý do tại sao bạn có thể viết mã như

char arr[8] = ""; 

Trong ví dụ này, yếu tố đầu tiên của mảng được khởi tạo explicity để '\ 0', và phần còn lại của mục ngầm để zero . Trình biên dịch chuyển này để

char arr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 
+0

Các đối tượng 'có thời gian lưu trữ tĩnh 'nghĩa là gì? Tôi không thể hiểu rằng một phần của đặc điểm kỹ thuật. Bạn có thể giải thích nó không? –

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