c-声明中的数组长度可以是非常量吗



我对C中的数组声明有点困惑。我知道可以这样做:

int a[20];  // Reserved space for 20 int array
int b[] = {32, 431, 10, 42};  // Length in square brackets is auto-calculated
int *c = calloc(15, sizeof(int));  // Created a pointer to the dynamic int array

但有可能做到这一点吗?:

int my_array[sizeof(int) * 5];

它是一个有效的代码,还是数组长度应该是一个常量表达式(在ANSI C中(?

此声明

int my_array[sizeof(int) * 5];

不声明可变长度数组,因为表达式sizeof(int) * 5是常量整数表达式。因此,即使您的编译器不支持可变长度数组,您也可以使用这样的声明。

来自C标准(6.6常数表达式(

6整数常量表达式117(应具有整数类型,并且仅具有作为整数常数、枚举常数等的操作数,字符常量,sizeof结果为整数的表达式常量和浮点常量,它们是铸造。整数常量表达式中的强制转换运算符只能将算术类型转换为整数类型,作为操作数到sizeof运算符。

和(6.7.6.2数组声明符(

4如果大小不存在,则数组类型为不完整类型。如果大小为*,而不是表达式,数组类型为未指定大小的可变长度数组类型,只能使用在具有函数原型范围的声明或类型名称中;这样的数组仍然是完整的类型如果大小是整数常量表达式,并且元素类型具有已知的常量大小,所述数组类型不是可变长度数组类型否则数组类型是可变长度的数组类型。(可变长度数组是实现不需要支持的条件特性;参见6.10.8.3。(

可变长度数组的声明可能看起来像

const int n = 5;
int my_array[sizeof(int) * n];

C11及更高版本可选支持可变长度阵列。

(这个答案回答了标题中的问题,"声明中的数组长度可以是非常量吗?"正文中给出的例子int my_array[sizeof(int) * 5];没有非常量长度。(

可变长度数组在当前的C标准(2018(中是可选的,这意味着C实现可以选择是否支持它们。它们在1999年C标准中是强制性的,在2011年标准中是可选的。

可变长度数组只能在函数内部或参数中声明,不能在文件范围内声明,并且它们不能具有静态或线程存储持续时间。

sizeof(int) * 5在您的问题中的示例语句中使用:int my_array[sizeof(int) * 5];是一个常量表达式,因此尽管它不能很好地说明您的主要问题,但它是C数组声明的合法语法。

除了C99之外,在最新的C编译器实现中,可变长度数组是可选的。(在C99中,必须包含VLA。(

因此,如果你的编译器支持VLA,下面是一个例子:

char string[100] = {0};
scanf("%99s", string);
int VLAarray1[strlen(string)+1];//per question in comments about functions to size array.
memset(VLA1array, 0, sizeof(VLAarray1));//see Note below for initialization
int arrayLen = 0;
scanf("%d", &arrayLen);
int VLAarray2[arrayLen];
memset(VLAarray2, 0, sizeof(VLAarray2));//see Note below for initialization
int nonVLAarray[100] = {0};//initialization during declaration of nonVLA

注意:VLA在声明期间不能以任何形式初始化。与所有变量一样,最好在随后的语句中通过显式为其整个内存区域赋值来初始化它。

将VLA作为函数参数传递不在您的问题范围内,但如果您感兴趣,这里会对该主题进行很好的讨论。

最新更新