In C, const
应该读作只读。它没有定义编译时间。
const int a = 5;
Here a
, is not所需的常量表达式C标准 http://port70.net/~nsz/c/c11/n1570.html#6.7.9p4:
6.7.9 初始化
4 具有静态或线程存储持续时间的对象的初始值设定项中的所有表达式都应为常量
表达式或字符串文字。
因此该错误表明您正在使用 C89/C90 编译器。您可以读取用户的输入a
并声明一个变长数组 https://en.wikipedia.org/wiki/Variable-length_array,这是一个 C99 功能,具有自动存储期限。
Using #define
是另一种方式。但它只是一个文本替换,并定义了一个具有自动存储持续时间的数组。与定义相同int arr[5];
你自己。
如果你想在动态存储(通常称为“堆”)上分配内存,你必须使用malloc() http://man7.org/linux/man-pages/man3/malloc.3.html系列函数,在整个程序执行过程中都有生命周期,直到您调用free()
on it.
(请注意,这种行为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(尽管 gcc 支持它)一个扩展 https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html即使在 C89/C90 中)。因此,如果您使用的编译器不支持 C99,则无法使用 VLA。
例如,Visual Studio 并不完全支持所有 C99 和 C11 功能。虽然,Visual Studio 2015 支持大多数 C99 功能 http://blogs.msdn.com/b/vcblog/archive/2014/06/18/crt-features-fixes-and-breaking-changes-in-visual-studio-14-ctp1.aspx、VLA 不是其中之一。
但同样的代码在 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。
From 6.10.8.3 条件特征宏 http://port70.net/~nsz/c/c11/n1570.html#6.10.8.3
__STDC_NO_VLA__
整数常量1,旨在表明该实现不支持可变长度数组或可变长度数组
修改后的类型。
我个人不使用 VLA,因为如果数组大小相当大,则无法移植地发现分配失败。例如。
size_t size = 8*1024;
int arr[size];
在上面的片段中,如果arr
分配失败,直到运行时你才会知道。内存分配取决于平台的“足够小”大小是多少。因此,在一台机器上,1MB 分配可能会成功,而另一台机器上可能会失败,更糟糕的是,没有办法捕获此失败。
因此,VLA 的使用受到限制,只能与您知道在给定平台上始终会成功的小型阵列一起使用。但我会简单地对数组大小进行硬编码并处理边界条件。