我正在编写以下代码
#include<stdio.h>
void fun(int n) {
int a[n] = {0};
}
void main() {
int a[4] = {0};
int i = 0;
fun(3);
}
并收到此错误
test.c: In function 'fun':
test.c:5:5: error: variable-sized object may not be initialized
而如果我将函数fun
更改为:-
void fun(int n) {
int a[n], i = 0;
for(i = 0; i < n; i++) {
a[i] = 0;
}
}
它工作正常。 我知道该错误正在发生,因为在编译器的规范中不允许这样做,但是我想知道的是为什么无法实现? 是由于某些编译时间还是运行时评估问题? 我看过其他问题的答案,但我需要一个更详尽的答案。
答案 0 :(得分:2)
可变长度数组无法初始化
int a[n]={0};
根据C标准#6.7.9p3初始化 [已加重]
要初始化的实体的类型应为未知大小的数组或完整的对象类型不是可变长度数组类型。
使用循环是初始化可变长度数组的一种方法。您也可以像这样使用memset
:
memset(a, 0, sizeof a);
其他:
C99编译器应该支持可变长度数组,但是在C11编译器中它们是可选的。
答案 1 :(得分:0)
第一种方法不起作用,因为您使用的是初始化器,C99标准不允许使用该初始化器,因为它在编译时无法预见数组大小。
您的第二种方法是C99允许的,分配堆栈内存,并且您在声明数组之后手动正确地初始化了数组。
进行动态内存分配的另一种方法是将堆与malloc
一起使用:
int *a = malloc(sizeof(a) * n);
// do stuff with a
free(a); // return memory to the heap
顺便说一句,wikipedia article on this topic很棒。
答案 2 :(得分:0)
一种简单的方法是将数组的大小与其他参数一起发送 请记住,您应该在具有该大小的数组之前发送大小
void fun(int n,int a[n]){
}
尽管您还有其他选择,例如sizeof()
答案 3 :(得分:0)
作为H.S. answer的补充:
根据C标准#6.7.9p3初始化 [已加重]
要初始化的实体的类型应为未知大小的数组或完整的对象类型不是可变长度数组类型。
这可能是因为初始化程序必须为constant expressions。常量表达式在编译时具有确定的值。
{0}
是一个不完整的初始化程序,编译器将用0
填充剩余的值。
如果您有VLA,则编译器不知道Array的长度,因此无法为其生成初始化器。
答案 4 :(得分:-1)
这实际上取决于您的编译器。 在旧的C语言中,不能有可变大小的数组。在fun函数中,将a用作大小为n的数组。在旧的C语言中不允许这样做。但是,C99和C11标准支持可变大小的数组,因此也许您有一个旧的编译器。 (DevC?)如果要在较旧的C编译器中使用某种类型的变量数组,则必须使用malloc和free。
也许您想用C ++编写此代码? C ++也不支持可变大小的数组,但是gcc编译器可以运行此代码。
检查一下: Why aren't variable-length arrays part of the C++ standard?
如果您使用的是DevC,我认为如果将文件从test.c更改为test.cpp,此代码将起作用。