使用二维数组作为一维数组是否正确?可能会导致未定义的行为左右?

Is using 2 dimensional array as 1 dimensional array correct? May cause Undefined Behaviour or so?

本文关键字:未定义 左右 一维数组 是否 二维数组      更新时间:2023-10-16

这段代码正确吗?由于某种原因,是否不推荐使用 2 维数组作为 1 维数组?

char tab1[3][3];
for(int i = 0; i < 3; i++)
for(int j = 0; j < 3; j++)
tab1[i][j] = (char)i;
printf("%c", ((char*)tab1)[3]); // == tab1[1][0]

由于某种原因,是否不推荐使用 2 维数组作为 1 维数组?

当您以现有方式使用tab1时,它会衰减为类型char (*)[3](指向 3chars 数组的指针)。它不会衰减到char*.

如果不显式强制转换,则不能将其用作char*

回复:这段代码正确吗?

它的定义很好,因为对于代码中的tab1&tab1&tab1[0]&tab1[0][0]指向内存中的同一位置,即使它们都是不同的类型。

如果没有其他原因,这很好,因为char可以根据标准为所有其他类型的别名。此外,多维数组被分配为一个连续块,因此它首先是内存中的一数组。

我们知道,tab1衰减到指向连续多维数组(数组)的第一个元素的指针,并且将该数组指针强制转换为char*(可以别名任何内容)一定没问题。

如果有疑问,您可以随时&tab1[0][0]。再次因为我们知道分配的内存是连续的。

编辑

如果这是一个整数数组(int tab1[3][3]),那么故事就有点不同了。根据我在C++17之前的理解,标准说指向正确对象类型的指针是有效的,无论它如何获得其值。这意味着强制转换为int*应该没问题,因为我们知道tab1生成的地址与第一个元素的地址相同。

但是C++17保证已被删除,因此此强制转换可能是未定义的行为

有关更多详细信息,请参阅此问题。

出于这个原因,我总是建议使用永远有效的&tab1[0][0]