int main{ const int a = 5; int i; int arr [a]; for (i = 0; i < 5; i++) { arr[i] = i * 2; } printf("%d",arr[1]); return 0; }
解决方法
const int a = 5;
这里一个,不是C standard要求的一个常数表达式:
6.7.9 Initialization
4 All the expressions in an initializer for an object that has static or thread storage duration shall be constant
expressions or string literals.
所以错误表示您正在使用C89 / C90编译器.您可以从用户那里读取输入,并声明一个具有自动存储持续时间的variable length array,这是一个C99功能.
使用#define是另一种方式.但它只是一个文本替换,并定义了一个具有自动存储持续时间的数组.与定义int arr [5]相同;你自己.
如果要在动态存储(通常称为“堆”)中分配内存,则必须使用malloc()
系列函数,这将在整个程序执行期间生效,直到您调用free()为止.
(请注意,const的这种行为只在C中.C在此方面有所不同,将按照预期的方式工作).
如果我在C89中编译代码,它将失败:
#include <stdio.h> int main(){ const int a = 5; int i; int arr [a]; for (i = 0; i < 5; i++) { arr[i] = i * 2; } printf("%d",arr[1]); return 0; } $gcc -Wall -Wextra -std=c89 -pedantic-errors test.c test.c: In function âmainâ: test.c:7:4: error: ISO C90 forbids variable length array âarrâ [-Wvla] int arr [a]; ^
因为C89不支持VLA(尽管在C89 / C90中gcc也支持它为an extension).因此,如果您使用的是不支持C99的编译器,则不能使用VLA.
例如,visual studio并不完全支持所有C99和C11功能.虽然,Visual studio 2015 support most C99 features,VLAs不是其中之一.
但同样的代码在C99和C11中编译没有任何问题:
$gcc -Wall -Wextra -std=c99 -pedantic-errors t.c $gcc -Wall -Wextra -std=c11 -pedantic-errors t.c
这是因为在C99中添加了可变长度数组(VLA).请注意,VLA已经在C11标准中成为可选.所以实施可能不支持C11中的VLA.
您需要测试__STDC_NO_VLA__以检查您的实施不支持VLA.
从6.10.8.3 Conditional feature macros
__STDC_NO_VLA__
The integer constant 1,intended to indicate that the implementation does not support variable length arrays or variably
modified types.
我个人不使用VLA,因为如果阵列大小相当大,则无法轻易找到分配失败.例如.
size_t size = 8*1024; int arr[size];
在上面的片段中,如果arr分配失败,直到运行时才会知道.什么是“足够小”的大小,内存分配是平台依赖的.所以在一台机器上,1MB的分配可能会成功,另一个可能会失败,更糟糕的是,没有办法抓住这个失败.
因此,使用VLA是有限的,只能用于您知道将永远在给定平台上成功的小阵列.但是,我只是硬编码数组大小并处理边界条件.