这可以工作:
const int size = 2; int array[size] = {0};
这有编译错误:
int a = 2; const int size = a; int array[size] = {0};
为什么?
因为 C++ 委员会的人是这么决定的。
技术原因是用于初始化的第一个表达式size
是一个常量表达式,它可以在编译期间计算。这意味着编译器还可以知道数组将有多大,并且可以在编译时完成分配(在这种情况下,“保留”可能是更合适的术语)。
在第二种情况下,表达式不是常量表达式(给定 C++ 定义),并且这种恢复是不可能的。
在第二种情况下,值在size
初始化时确实是固定的,这一事实完全无关紧要。规则基于“表达式类型”,第二个表达式使用可变变量,因此编译器认为它是非常量的。
允许编译时初始化的第二种形式需要流分析,因为它需要区分
int a = 2;
const int size = a;
和
int a = foo();
const int size = a;
其中涉及的表达式size
确实相同。
const int size = 2;
int array[size] = {0};
这里,2
是一个文字值,这意味着你不能改变它,编译器在编译时就知道这个值。
int a = 2;
const int size = a;
int array[size] = {0};
但是,a
是一个变量,这意味着它的值a
是可以改变的,并且会在运行时确定所以编译器禁止你。您可以使用
int a = 2;
int size = a;
int* array = new int[size];
因此,您可以申请具有动态大小的数组。
这是关于内存管理的。
当操作系统因为 C++ 的性质而试图运行你的程序时,操作系统会想知道堆栈区域的确切空间。在第一个示例中,操作系统会知道变量的值不会改变。但是对于第二个例子,从操作系统的角度来看,您的第一个变量“a”可以在
int a = 2;
这个和这个
const int size = a;
你的变量 a 可以改变。这就是为什么您的编译器不允许您编译代码的原因。
为了了解更多关于内存管理的基础知识。我建议你 https://stackoverflow.com/a/24922/2326288这个评论。
因为在第一种情况下,size
是由编译器在编译时初始化的。在第二种情况下,a
可能在运行时初始化,因此size
也将在运行时初始化,不再是编译时常量。