C++11中的二维数组初始化

0s0u357o  于 2023-11-19  发布在  其他
关注(0)|答案(1)|浏览(155)

我正在尝试完全理解C++数组init。

下面是代码片段:

int main() {
    const int n= 20;
    int m;
    m = n+10;
    int (*a)[m] = new int [n][m]; //1
    int *w = new int [m]; //2
    int (*b)[n] = new int [m][n]; //3
    int (*d)[n] = new int [n][n]; //4
}

字符串
如果我尝试完成这段代码,我会得到错误:

error: array size in new-expression must be constant
error: the value of 'm' is not usable in a constant expression
note: 'int m' is not const


我读过,数组的init变量必须是一个const,但是,如果是这样,那么我有一些问题:
1.为什么可以使用非常量变量m初始化一维数组**(2)
1.为什么可以在行数位置使用非常量变量
m初始化二维数组(3)
1.为什么不能在列号位置使用非常量变量
m初始化二维数组(1)**?
以防万一,我会澄清,我不是在寻找变通办法,另一种方法,等等,只是为了理论知识。
谢谢你,谢谢

kmbjn2e3

kmbjn2e31#

a指向一个分配了new T[n];的(一维)数组,该数组的类型为T
当访问第i个数组元素时(如a[i]),或者甚至当计算其地址时(如a+i),编译器必须计算 offset,即数组中的第一个字节与第i个元素中的第一个字节之间有多少字节。
这样的offset就被计算为i * sizeof(T)。如果sizeof(T)是一个静态已知的常数,即在编译时已知,那么这个乘法可以变得更有效。出于这个原因,禁止那些大小不能静态预测的类型T是有意义的。ISO C遵循这条路径。
注意,数组的大小(n)在这里无关紧要,因为它不影响偏移量的计算。大小n可以在运行时自由计算。我们只关心sizeof(T)是静态已知的。
好消息是对于大多数类型T,我们确实可以在编译时计算sizeof(T)。如果T是数值类型或指针,我们知道它的大小。如果它是一个类,我们知道所有成员的sizeof,我们也知道类的大小(这将是它们的总和,加上一些填充)。
但是,如果T本身是一个数组类型呢?如果T = U[m]是某个类型U呢?好吧,这里我们需要静态地知道sizeof(T)m的值。这是关键点。
注意,在本例中,a = new T[n]实际上是指a = new U[n][m](不,它不是U[m][n]-语法可能会混淆):T[n]T类型的n值的数组,U[n][m]U类型的m值的数组,这是一样的
最后,我们可以总结一下:在new U[n][m]中,n可以在运行时自由计算,但m必须在编译时已知。
这推广到多维数组:除了第一个维度之外的所有维度都必须静态已知。
一些编译器实现了一个非标准的(非ISO C
)扩展,允许在运行时计算m,即使这会减慢偏移量的计算。这被称为“VLA”(可变长度数组)。通常还有一个编译器标志来关闭它(-pedantic),这样就不会无意中使用它。

相关问题