1.这是可行的:
const int size = 2; int array[size] = {0};
1.这有编译错误:
int a = 2; const int size = a; int array[size] = {0};
为甚么?
dfuffjeb1#
因为C委员会的人决定这么做。技术上的原因是用于初始化size的第一个表达式是常量表达式,它可以在编译时计算,这意味着编译器也可以知道数组的大小,并且可以在编译时进行分配(在这种情况下,“保留”可能是更合适的术语)。在第二种情况下,表达式不是常量表达式(给定C定义),并且这种反转是不可能的。在第二种情况下,值在size初始化时确实是固定的,这一事实完全无关。规则基于“表达式类型”,第二个表达式使用可变变量,因此编译器认为它是非常量。允许第二种形式用于编译时初始化需要进行流分析,因为编译器需要区分
size
int a = 2; const int size = a;
以及
int a = foo(); const int size = a;
其中涉及size的表达式实际上是相同的。
brc7rcf02#
这里,2是一个文本值,这意味着,你不能改变它,编译器在编译时就知道这个值。
2
但是,a是一个变量,这意味着值a可以被改变,并且在运行时是确定的,所以编译器禁止你这样做。
a
int a = 2; int size = a; int* array = new int[size];
因此,您可以申请动态大小的数组。
lxkprmvk3#
这是关于内存管理的。当操作系统试图运行你的程序时,由于C++的特性,操作系统会想要知道堆栈区域的确切空间。在第一个例子中,操作系统会知道变量的值不会改变。但是对于第二个例子,在操作系统视图中,你的第一个变量“a”可以在
int a = 2;
这个和这个
const int size = a;
变量a是可以改变的,这就是为什么编译器不允许你编译代码。为了学习更多关于内存管理的基础知识,我推荐你阅读https://stackoverflow.com/a/24922/2326288这篇评论。
rryofs0p4#
因为在第一种情况下,size是由编译器在编译时初始化的,在第二种情况下,a * 可以在 run-time 初始化,因此size也将在运行时初始化,并且不再是编译时常量。
4条答案
按热度按时间dfuffjeb1#
因为C委员会的人决定这么做。
技术上的原因是用于初始化
size
的第一个表达式是常量表达式,它可以在编译时计算,这意味着编译器也可以知道数组的大小,并且可以在编译时进行分配(在这种情况下,“保留”可能是更合适的术语)。在第二种情况下,表达式不是常量表达式(给定C定义),并且这种反转是不可能的。
在第二种情况下,值在
size
初始化时确实是固定的,这一事实完全无关。规则基于“表达式类型”,第二个表达式使用可变变量,因此编译器认为它是非常量。允许第二种形式用于编译时初始化需要进行流分析,因为编译器需要区分
以及
其中涉及
size
的表达式实际上是相同的。brc7rcf02#
这里,
2
是一个文本值,这意味着,你不能改变它,编译器在编译时就知道这个值。但是,
a
是一个变量,这意味着值a
可以被改变,并且在运行时是确定的,所以编译器禁止你这样做。因此,您可以申请动态大小的数组。
lxkprmvk3#
这是关于内存管理的。
当操作系统试图运行你的程序时,由于C++的特性,操作系统会想要知道堆栈区域的确切空间。在第一个例子中,操作系统会知道变量的值不会改变。但是对于第二个例子,在操作系统视图中,你的第一个变量“a”可以在
这个和这个
变量a是可以改变的,这就是为什么编译器不允许你编译代码。
为了学习更多关于内存管理的基础知识,我推荐你阅读https://stackoverflow.com/a/24922/2326288这篇评论。
rryofs0p4#
因为在第一种情况下,
size
是由编译器在编译时初始化的,在第二种情况下,a
* 可以在 run-time 初始化,因此size
也将在运行时初始化,并且不再是编译时常量。