2013-06-06 45 views
9

Giả sử khởi tạo sau:Giá trị của các yếu tố của một mảng nhân vật khởi tạo là một chuỗi rỗng

char mystr[4] = ""; 

Có đảm bảo tiêu chuẩn C99 rằng một mảng nhân vật khởi tạo một chuỗi rỗng sẽ khởi tạo tất cả các yếu tố trong mảng nhân vật để null byte? Ví dụ: tiêu chuẩn có đảm bảo rằng mystr[2] == '\0' không?

Làm thế nào về những khởi tạo:

char myfoo[4] = { '\0' }; 
char mybar[4] = { 0 }; 

Trong khi tôi khá chắc chắn rằng thiết lập một cách rõ ràng các yếu tố đầu tiên của một mảng nhân vật sẽ đảm bảo việc khởi tạo ngầm của phần còn lại của các yếu tố để 0, tôi nghi ngờ một chuỗi khởi tạo chữ kết quả trong một bản sao cho mảng - do đó có nghĩa là đơn\0 được sao chép vào mảng trong khi các phần tử còn lại không được khởi tạo.

Trả lời

12

Mục 6.7.8, đoạn 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 các ký tự ít trong một chuỗi chữ đã qua sử dụng để khởi tạo một mảng có kích thước đã biết hơn có 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ư các đối tượng có thời lượng lưu trữ tĩnh.

Và các đối tượng có thời lượng lưu trữ tĩnh được khởi tạo như thế nào?

Mục 6.7.8, đoạn 10:

Nếu một đối tượng có thời gian lưu trữ tự động không được khởi tạo một cách rõ ràng, giá trị của nó là không xác định. Nếu đối tượng có thời lượng lưu trữ tĩnh không được khởi tạo rõ ràng, thì:

  • nếu có loại con trỏ, nó được khởi tạo thành con trỏ rỗng;
  • nếu nó có loại số học, nó được khởi tạo thành số không (dương hoặc không dấu);
  • nếu nó là tổng hợp, mọi thành viên được khởi tạo (đệ quy) theo các quy tắc này;
  • nếu đó là công đoàn, thành viên có tên đầu tiên được khởi tạo (đệ quy) theo các quy tắc này.

char là một loại số học, do đó, nó được khởi tạo thành 0. Huzzah, bạn có thể dễ dàng nghỉ ngơi.

3

Có, các phần tử dư thừa của mảng luôn được khởi tạo bằng 0 và các mảng char được khởi tạo bằng cách sử dụng chuỗi ký tự cũng không ngoại lệ.

Từ tiêu chuẩn C99, phần 6.7.8.21 (trang 139 của this document):

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.

6

Ngôn ngữ C tuân theo phương pháp "tất cả hoặc không có gì" cho tất cả các lần khởi tạo tổng hợp. Nó có nghĩa là bất kỳ nỗ lực nào để cung cấp một bộ khởi tạo rõ ràng cho bất kỳ phần nào của tổng hợp (bất kể phần nhỏ đó là như thế nào) ngay lập tức đảm bảo rằng tổng hợp toàn bộ sẽ được khởi tạo. Các phần không có bộ khởi tạo rõ ràng sẽ không được khởi tạo.

Trong ví dụ của bạn, toàn bộ mảng được đảm bảo được khởi tạo bằng số không. Trong trường hợp khởi tạo cấu trúc, tất cả các trường không được khởi tạo rõ ràng nhận được giá trị bằng không.

Một hệ quả của nguyên tắc đó là bằng ngôn ngữ C bộ khởi tạo = { 0 } hoạt động như một thành ngữ số bộ khởi tạo chung số không. Kể từ khi ngôn ngữ cho phép = { value } cú pháp trong initializers đối tượng vô hướng là tốt, người ta có thể sử dụng = { 0 } để khởi bất kỳ đối tượng cho tất cả-zero bang

#define UNIVERSAL_ZERO { 0 } 

double d = UNIVERSAL_ZERO; 
char s[100] = UNIVERSAL_ZERO; 
struct { int x, y, z; } xyz = UNIVERSAL_ZERO; 
int *p = UNIVERSAL_ZERO; 
+0

Đó là một điểm tốt, tôi không bao giờ nghĩ đến việc làm điều đó để khởi tạo những thứ khác hơn mảng. Có bất kỳ bất lợi để làm điều này như trái ngược với, nói, 'memset (& xyz, 0, sizeof (xyz));' –

+2

@Taylor Brandstetter: Về mặt lý thuyết, '= {0}' là khác nhau. Nó khởi tạo dữ liệu với các giá trị '0' phụ thuộc vào loại phù hợp. Ví dụ, nếu một số nền tảng sử dụng mẫu '0xFFFFFFFFF' để biểu diễn các con trỏ null, thì' = {0} 'sẽ thực sự tạo ra biểu diễn' 0xFFFFFFFFF' thích hợp. Mặt khác, 'memset' của bạn sẽ chỉ lấp đầy mọi thứ với mẫu bit không bằng 0. Ví dụ khác, nếu một số nền tảng sử dụng mẫu bit khác 0 để đại diện cho giá trị '0.0' nổi,' = {0} 'sẽ tạo ra biểu diễn đó đúng cách, trong khi' memset' của bạn sẽ lặp lại mọi thứ bằng số không. – AnT

+1

Được cấp, trong các nền tảng thực hành sử dụng mẫu bit khác 0 để biểu thị giá trị bằng không là hiếm và/hoặc kỳ lạ. Trên nền tảng hàng ngày điển hình, 'memset' đạt được hiệu ứng tương tự như' = {0} 'và, rất có thể, tạo ra cùng một mã. – AnT

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