可以使用const变量来声明C中数组的大小吗?

use*_*196 37 c arrays const

为什么以下代码会抛出错误?

const int a = 5;
int b[a]={1,2,3,4,5};
Run Code Online (Sandbox Code Playgroud)

而且当我尝试编译没有"const"关键字的上述代码时,我得到了同样的错误:

int a = 5; 
int b[a]={1,2,3,4,5};
Run Code Online (Sandbox Code Playgroud)

为什么会这样?我在这里做的错误是什么?

还有另一个问题:什么时候常量被代码中的实际值替换,即如果我声明一个变量说:const int x = 5; 我知道在RAM中没有为变量x分配内存,但是ROM中的常量变量区域保持值5,并且x在代码中出现x的地方简单地替换为值5.但这什么时候发生的?编译时间?启动时间?预处理时间?

PS:我说的是嵌入式C(在微控制器上运行等),而不是在桌面上运行的C. 因此嵌入式系统必然会有一个ROM(Flash,EEPROM ......).那会发生什么?

Ker*_* SB 34

这只是语言的限制.静态有界数组的大小需要是常量表达式,不幸的是在C中,它只是像文字常量或sizeof表达式之类的东西,而不是一个const常见的变量.

(正如西蒙指出的那样,因为C99还有运行时限制的数组,或者"可变长度数组",其大小可以由任何变量的值给出.但这是一种不同的动物.)

您可能有兴趣听说C++中的规则是不同的,其中a static const int确实是一个常量表达式,而C++ 11甚至添加了一个新的关键字constexpr,以允许更广泛地使用包含更多值为"可以合理地在编译时确定".

  • C99中的规则也不同,尽管数组将被视为动态的. (7认同)

Jen*_*ens 31

在C中,const是一个用于只读的用词不当.const变量可以改变它们的值,例如声明它是完全可以的

const volatile int timer_tick_register; /* A CPU register. */
Run Code Online (Sandbox Code Playgroud)

您可以阅读并获得每次读取的不同值,但不能写入.因此,语言规范把const合格的对象为常量表达式适于阵列尺寸.


Cir*_*四事件 21

VLA的两个主要替代品:enum和宏

enum:

enum N { N = 5 };
int is[N];
Run Code Online (Sandbox Code Playgroud)

这是因为枚举成员是常量表达式:枚举成员可以是ANSI-C中数组的大小吗?

使用宏:

#define N 5
int is[N];
Run Code Online (Sandbox Code Playgroud)

enums 的优点是enums具有范围,并且是编译步骤的一部分,因此它们也可能导致更好的错误消息.

宏的优点是你可以更好地控制常量的类型(例如#define N 1vs #define N 1u),而enums被固定到某些实现定义的类型:sizeof(enum)== sizeof(int),总是?但在这种情况下,这并不重要.

为什么要避免VLA

  • 这个答案是唯一一个有解决方案的答案(枚举而不是#define-yuck)。 (2认同)