Bạn không thể sử dụng loại vòng loại hoặc static
trong phần kích thước của khai báo mảng trong C89/90. Các tính năng này dành riêng cho C99.
static
trong khai báo mảng cho trình biên dịch biết bạn hứa rằng số lượng phần tử được chỉ định sẽ luôn có mặt trong mảng được chuyển làm đối số thực tế. Điều này có thể giúp các trình biên dịch tạo ra mã hiệu quả hơn. Nếu bạn vi phạm lời hứa của bạn trong mã thực tế (ví dụ: vượt qua một mảng nhỏ hơn), hành vi không xác định. Ví dụ:
void foo(int a[static 3]) {
...
}
int main() {
int a[4], b[2];
foo(a); /* OK */
foo(b); /* Undefined behavior */
}
Phần khai báo mảng chỉ được sử dụng trong khai báo mẫu chức năng.Nó chỉ ra rằng mảng có độ dài biến đổi (VLA). Ví dụ, trong định nghĩa chức năng bạn có thể sử dụng một VLA với bê tông chạy theo thời gian kích thước
void foo(int n, int a[n]) /* `a` is VLA because `n` is not a constant */
{
...
}
Khi bạn khai báo nguyên mẫu bạn có thể làm tương tự
void foo(int n, int a[n]); /* `a` is VLA because `n` is not a constant */
nhưng nếu bạn không xác định các tên tham số (mà là OK trong nguyên mẫu), bạn không thể sử dụng n
làm kích thước mảng của khóa học. Tuy nhiên, nếu bạn vẫn phải nói với trình biên dịch mà mảng sẽ là một VLA, bạn có thể sử dụng *
cho mục đích đó
void foo(int, int a[*]); /* `a` is VLA because size is `*` */
Lưu ý, rằng ví dụ với một mảng 1D không phải là một tốt nhất. Thậm chí nếu bạn bỏ qua *
và khai báo hàm trên như
void foo(int, int a[]);
thì mã vẫn sẽ làm việc tốt, bởi vì trong chức năng khai báo kiểu tham số mảng được ngầm thay thế bằng kiểu con trỏ anyway. Nhưng một khi bạn bắt đầu sử dụng mảng đa chiều, việc sử dụng thích hợp *
trở nên quan trọng. Ví dụ, nếu hàm được định nghĩa là
void bar(int n, int m[n][n]) { /* 2D VLA */
...
}
những nguyên mẫu có thể trông như sau
void bar(int n, int m[n][n]); /* 2D VLA */
hoặc như
void bar(int, int m[*][*]); /* 2d VLA */
Trong trường hợp sau là người đầu tiên *
thể được bỏ qua (vì thay thế mảng-thành-con trỏ), nhưng không phải là số thứ hai *
.
Tôi cho rằng nơi điều này thực sự quan trọng là khi bạn thực hiện 'f (int, int, int a [*] [*])' hoặc tương tự ... – dmckee
@dmckee: Tôi vừa thêm vào câu trả lời của mình :) – AnT
Rất nhiều người suy nghĩ dọc theo cùng một dòng quanh đây. Tâm trí tuyệt vời và tất cả ... – dmckee