Điều này trông giống như một lỗi đánh máy đơn giản nhưng tình hình đủ phức tạp để giải quyết từng bước một.
Đầu tiên hãy để tôi chỉ ra giải pháp có vẻ hiệu quả:
int main()
{
str t[2] = { { { {0, 2}, {4, 6} } }, { { {1, 3}, {5, 7} } } };
cout << t[1].t[0].t[1] << t[0].t[1].t[0] << endl;
return 0;
}
Vì vậy, chúng tôi có một mảng str
chứa một mảng sct
.
Hãy bắt đầu với cái sau. Bạn khởi tạo một mảng sct
với một cái gì đó như thế này:
sct x[2] = { {0, 1}, {2, 3} };
Bây giờ cho một ví dụ duy nhất của str
bạn có thể đi với
str y = { { {0, 2}, {4, 6} } };
Những gì còn lại str t[2]
là sắp xếp hai bản sao của str
biểu thức khởi tạo trong dấu ngoặc nhọn:
str t[2] = { { { {0, 2}, {4, 6} } }, { { {1, 3}, {5, 7} } } };
Chỉnh sửa: Trong lần đọc đầu tiên tôi đã hiểu nhầm câu hỏi. Sau khi bài đăng được cập nhật, rõ ràng câu hỏi đặt ra là tại sao có thể loại bỏ hai cặp niềng răng nhưng chỉ cần một cặp kết quả là bị lỗi cú pháp.
Để hiểu cách trình phân tích cú pháp diễn giải mã, bạn có thể muốn nhìn vào cây phân tích cú pháp. Bạn có thể tạo gcc dump cây ở một số giai đoạn của trình phân tích cú pháp với -fdump-tree-...
các tùy chọn. Ở đây -fdump-tree-original
có thể hữu ích.
Để tránh nhầm lẫn thêm, hãy đảm bảo các thành phần của cấu trúc có các tên khác nhau:
struct sct
{
int a[2];
};
struct str
{
sct b[2];
};
Đây là đầu ra tôi nhận được với GCC 7.5 từ
>>>> CODE:
str t[2] = { { 0, 2, 4, 6 }, { 1, 3, 5, 7 } };
>>>> tree enabled by -tree-original
struct str t[2] = {{.b={{.a={0, 2}}, {.a={4, 6}}}}, {.b={{.a={1, 3}}, {.a={5, 7}}}}};
Bạn có thể thấy rằng trình biên dịch thêm các dấu ngoặc ẩn xung quanh các biểu thức khởi tạo cho từng cấu trúc và xung quanh các biểu thức khởi tạo cho từng trường được đặt tên.
Bây giờ hãy xem xét biểu thức không biên dịch:
str t[2] = { { {0, 2},{4, 6} }, { {1, 3},{5, 7} } };
Cây ở cấp trên biểu thức này sẽ là
/*Step 1: */ struct str t[2] = { {.b={0, 2}, {4, 6} }, {.b={1, 3}, {5, 7} } };
Nhưng vì b là một mảng sct
, chúng tôi cố gắng khởi tạo nó bằng {0,2}
cách nhận
sct b[2] = {0, 2};
Điều này mở rộng đến
struct sct b[2] = {{.a={0, 2} }};
Đây là C ++ hợp lệ do phần tử đầu tiên của mảng được khởi tạo một cách rõ ràng và phần tử thứ hai được khởi tạo ngầm với các số không.
Với kiến thức này, chúng ta có được cây sau
/*Step 2: */ struct str t[2] = { {.b={{.a={0, 2} }}, {4, 6} }, {.b={{.a={1, 3} }}, {5, 7} } };
Bây giờ chúng tôi còn lại với những điều sau đây:
struct str z = { { { {0,2} }, { {0,0} } }, {4, 6} };
Và trình biên dịch phàn nàn đúng:
error: too many initializers for ‘str’
Như một kiểm tra cuối cùng xem xét khai báo sau
struct sxc
{
sct b[2];
int c[2];
}
struct sxc z = { {0,2} , {4, 6} };
Điều này biên dịch và kết quả trong cấu trúc sau:
{ .b = { { .a={0,2} }, { .a={0,0} } }, .c={4, 6} }