4

C99 允许定义具有非常量大小的数组,即用于定义数组的大小可以在运行时改变。解释它的代码片段是,

void dummy_function1(unsigned int length) {

 char arrA[length];  //Allowed
 .
 .
}

但是,它不允许就地初始化它,即

void dummy_function2(unsigned int length) {

 char arrA[length]={0}; //Not Allowed, compiler throws an error
 char arrB[10]={0};     //Allowed
 .
}

我不明白,为什么可变长度的数组和恒定长度的数组的行为会有所不同。在这两种情况下,调用函数时都会为数组分配内存。

4

3 回答 3

4

这是因为编译器不知道用多少个零来“填充”剩余的元素。

该声明

char arrA[3] = { 0 };

可以很容易地翻译成

char arrA[3] = { 0, 0, 0 };

在编译期间,而变长声明则不能。

由于 C 没有运行时系统,编译器必须根据给定的长度添加代码以动态填充零。C 标准力求最大限度地减少程序员的能力,因此避免了这样的事情。从 C11 开始,可变长度数组已从标准中删除,并被标记为可选功能。

于 2013-09-17T15:52:19.057 回答
4

6.7.8 如果我们查看 C99 草案标准部分初始化3段说(强调我的),标准似乎不允许这样做:

要初始化的实体的类型应该是一个未知大小的数组或一个不是可变长度数组类型的对象类型

至于为什么很可能是因为支持可变长度数组的初始化需要在运行时进行不确定的工作量。

于 2013-09-17T15:52:21.890 回答
2

假设:C 是一种中级语言,标准委员会不希望在基本语言中包含执行在编译时未确定的工作量的操作(将库算作单独的)。

目前我想到的所有 C 的基本操作(也许有人会纠正我)只需要在编译时确定的工作量:调用一个函数,将两个数字相乘,将一个结构分配给另一个,等等。这些都可以通过在编译时执行的许多机器指令来执行。

即使为可变长度数组分配空间也只需要编译时的工作量:计算大小并从堆栈指针中减去它。相反,初始化所有这些空间需要在运行时确定的工作量。这对于 C 语言来说是不合时宜的。

库例程可能需要在运行时确定的工作量,例如memset.

于 2013-09-17T18:32:25.670 回答