编辑:刚刚在 wikipedia 上读到 C11 已将可变长度数组降级为可选功能 :( Doh!帖子的前半部分可能没有那么有用,但后半部分回答了您的其他一些问题 :)
作为对 Kerrek SB 帖子的补充,C99 (ISO/IEC 9899:1999) 确实具有可变长度数组的概念。该标准给出了以下示例:
#include <stddef.h>
size_t fsize3(int n)
{
char b[n+3]; // variable length array
return sizeof b; // execution time sizeof
}
sizeof
运算符扩展如下:
sizeof 运算符产生其操作数的大小(以字节为单位),它可以是表达式或带括号的类型名称。大小由操作数的类型决定。结果是一个整数。如果操作数的类型是变长数组类型,则计算操作数;否则,不计算操作数,结果是一个整数常量。
另一个很好的例子可以在wikipedia上找到。
请注意,静态声明的不能是变长数组。
至于你的其他一些问题:
问:什么时候用代码中的实际值替换常量?
如果常量是 const 变量,那么它可能永远不会被“替换”,并且始终可以作为内存区域进行访问。这是因为地址运算符&
仍然必须与变量一起使用。但是,如果从不使用变量地址,则可以“替换”它并且不分配内存。来自 C 标准:
该实现可以将非易失性的 const 对象放置在存储的只读区域中。此外,如果从未使用过此类对象的地址,则实现不需要为此类对象分配存储空间。
下一个问题...
问:我知道在 RAM 中没有为变量 x 分配内存,但 ROM 中的常量变量区域保存值 5
这取决于您的系统。如果你有 ROM 并且编译器知道 ROM 的位置,那么它很可能放在 ROM 中。如果没有 ROM,编译器(实际上是链接器)将拥有的唯一选择是 RAM。
问:在代码中出现 x 的任何地方,x 都被简单地替换为值 5。但这种情况什么时候发生?编译时间?开机时间?预处理时间?
如前所述,这取决于如何使用常量。如果从不使用 const 变量的地址并且编译器足够聪明,那么在编译时。否则,“替换”永远不会发生,它是一个在内存中具有位置的值;在这种情况下,变量在内存中的放置发生在链接时。它永远不会在预处理过程中发生。