考虑以下代码:
#include <iostream>
using namespace std;
int main()
{
int x = 3;
const int i[] = { 1, 2, 3, 4 };
float f[i[3]];
struct S { int i, j; };
const S s[] = { { 1, 2 }, { 3, 4 } };
double d[s[1].j];
}
Run Code Online (Sandbox Code Playgroud)
它运行没有错误.但是,以下内容:
#include <iostream>
using namespace std;
int x = 3;
const int i[] = { 1, 2, 3, 4 };
float f[i[3]]; // error: array bound is not an integer constant …Run Code Online (Sandbox Code Playgroud) 以下代码在gcc 4.8和Clang 3.2下编译:
int main()
{
int size = 10;
int arr[size];
}
Run Code Online (Sandbox Code Playgroud)
C++标准的8.3.4/1表示数组的大小必须是一个整数常量表达式,这size似乎不是.这是两个编译器中的错误,还是我错过了什么?
最新的VC++ CTP用这个有趣的消息拒绝代码:
error C2466: cannot allocate an array of constant size 0
Run Code Online (Sandbox Code Playgroud)
有趣的是,它似乎认为size是零.但至少它拒绝了代码.gcc和Clang应该不一样吗?
c++ arrays compile-time-constant variable-length-array c++11
我们已经知道,VLA(在C99中标准化)不是C++标准的一部分.
所以下面的代码在C++中是"非法的":
void foo(int n) {
int vla[n];
for (int i = 0; i < n; ++i) {
vla[i] = i;
}
}
Run Code Online (Sandbox Code Playgroud)
尽管编译器(g ++和clang ++)接受代码作为有效语法,但只有在启用情况下才会生成警告 .-pedantic
ISO C++禁止变长数组'vla'[-Wvla]
我的问题是:
为什么编译器接受该声明?
编译器不能只拒绝一个长度为的数组[is-no-know-at-compile-time]?
是否存在一种兼容性语法规则?
标准说了什么?
从生成的汇编代码中我看到编译器在循环中写入堆栈,就像普通数组一样,但我找不到任何关于标准行为的信息.
我一直认为c ++中不允许使用变长数组(参考:为什么变量长度数组不是C++标准的一部分?).但是为什么这段代码编译和工作?
#include <iostream>
using namespace std;
int main () {
int n;
cin >> n;
int a[n];
for (int i=0; i<n; i++) {
a[i] = i;
}
for (int i=0; i<n; i++) {
cout << a[i] << endl;
}
}
Run Code Online (Sandbox Code Playgroud) 根据这个答案,其中指出:
编译器知道int类型的大小,因此可以生成正确的汇编程序指令,该指令将在堆栈上保留足够的空间,以便让foo存在.
编译器需要知道函数将在堆栈上占用的大小才能实现它.
那么,为什么这段代码会编译?
int f(int n)
{
int x[n];
}
int main()
{
f(3);
f(5);
//etc
}
Run Code Online (Sandbox Code Playgroud)
x 是一个整数数组,但它的大小不是常量,它可以在调用函数的任何时候改变.
我在这里错过了什么?
所以我总是被告知你应该在编译时不知道数组的大小时使用动态内存.例如,用户需要输入数组的大小.
int n;
cin >> n;
int array[n];
for(int ii = 0; ii < n; ii++)
{
array[ii] = ii;
}
for(int ii = 0; ii < n; ii++)
{
cout << array[ii] << endl;
}
Run Code Online (Sandbox Code Playgroud)
然而,这对我来说很好,我一直认为我需要使用指针和新的运算符.动态内存是否仅适用于您想要更改阵列大小,释放空间或控制何时释放内存的能力?谢谢.
我从这里读到了这段话:http://www.cplusplus.com/doc/tutorial/dynamic/
您可能想知道声明正常数组和为指针分配动态内存之间的区别,正如我们刚刚所做的那样.最重要的区别是数组的大小必须是一个常量值,它将其大小限制为我们在设计程序之前决定的时间,在执行之前,而动态内存分配允许我们在使用任何变量或常量值作为其大小执行程序(运行时).
但是这个我的代码工作得很好:
int number;
cin>>number;
int myArray[number];
cout<<sizeof(myArray)/sizeof(myArray[0])<<endl;
cout<<sizeof(myArray)<<endl;
Run Code Online (Sandbox Code Playgroud)
这是否意味着数组是在动态内存中创建的?或者它是在静态内存中创建的,但它的大小仍然在运行时确定?
看到这段代码
#include<iostream>
int main
{
using namespace std;
int a=7;
char arr[a];
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在我的书中写道,array_size必须是一个常量但是代码块没有给出错误...
它不是唯一的例子......还有其他一些例子.
谁是错误的IDE,编译器或任何其他的东西???
使用较新或较旧的书会导致这样的问题?
我一直在读,数组应该在编译时具有已知的大小.这是一段代码示例:
int temp = 5;
const int size = temp;
int array[size];
Run Code Online (Sandbox Code Playgroud)
但是,我编译并运行代码,没有错误.
作者是否正确,在上面的代码中,数组的大小在运行时是已知的?如果他是,为什么我能编译并运行代码?
在我看来,这个大小在编译时是已知的.有什么我不明白的东西吗?
编辑.我使用了g ++编译器而没有额外的选项:g ++ main.C -o main
似乎记得C++中的静态数组只能从const表达式初始化,但如果你写:
#include <iostream>
int main() {
int n;
std::cin >> n;
int a[n];
std::cout << sizeof(a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
该程序成功编译(gcc C++ 17)并打印n*sizeof(int).但为什么会这样呢?