您不能使用类型限定符或static
在 C89/90 中数组声明的大小部分。这些功能是 C99 特有的。
static
在数组声明中告诉编译器你保证指定数量的元素将始终出现在作为实际参数传递的数组中。这可能有助于编译器生成更高效的代码。如果您在实际代码中违反了承诺(即传递较小的数组),则行为是未定义的。例如,
void foo(int a[static 3]) {
...
}
int main() {
int a[4], b[2];
foo(a); /* OK */
foo(b); /* Undefined behavior */
}
The *
数组声明的大小部分仅在函数原型声明中使用。它表明该数组具有可变长度(VLA)。例如,在函数定义中,您可以使用具有具体运行时大小的 VLA
void foo(int n, int a[n]) /* `a` is VLA because `n` is not a constant */
{
...
}
当你声明原型时你可以做同样的事情
void foo(int n, int a[n]); /* `a` is VLA because `n` is not a constant */
但如果你不指定参数名称(这在原型中是可以的),你就不能使用n
当然是数组大小。然而,如果您仍然需要告诉编译器该数组将是 VLA,您可以使用*
为了这个目的
void foo(int, int a[*]); /* `a` is VLA because size is `*` */
请注意,带有一维数组的示例并不是一个好的示例。即使你省略了*
并将上述函数声明为
void foo(int, int a[]);
那么代码仍然可以正常工作,因为在函数参数声明中,数组类型无论如何都会隐式替换为指针类型。但是一旦你开始使用多维数组,正确使用*
变得重要。例如,如果函数定义为
void bar(int n, int m[n][n]) { /* 2D VLA */
...
}
原型可能如下所示
void bar(int n, int m[n][n]); /* 2D VLA */
or as
void bar(int, int m[*][*]); /* 2d VLA */
在后一种情况下,第一个*
可以省略(因为数组到指针的替换),但第二个不能省略*
.