这段代码是否合适?出于某种原因使用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]
答案 0 :(得分:0)
出于某种原因,是否将二维数组用作1维?
当你使用tab1
的方式时,它会衰减到类型为char (*)[3]
的指针(指向3 char
s的数组的指针)。它不会衰减到char*
。
如果没有明确地投射它,就不能将它用作char*
。
回复:这段代码是否合适?
很明确,因为对于代码中的tab1
,&tab1
,&tab1[0]
和&tab1[0][0]
指向内存中的相同位置,即使它们都是不同的类型
答案 1 :(得分:0)
如果没有其他原因,这很好,因为char
可以根据标准对所有其他类型进行别名。此外,多维数组被分配为一个连续的块,因此它是内存中的一维数组。
我们知道tab1
衰减到指向连续多维数组(这是一个数组)的第一个元素的指针,并将数组指针强制转换为char*
(哪个可以别名)必须没问题。
如果有疑问,你可以随时&tab1[0][0]
。再次,因为我们知道分配的内存是连续的。
修改强>
如果这是一个整数数组(int tab1[3][3]
),那么故事就会有所不同。根据我的理解 C++17
之前的标准,标准表示指向正确对象类型的指针有效无论如何获得其值。这意味着转换为int*
应该没问题,因为我们知道tab1
产生的地址与第一个元素的地址相同。
然而 C++17
后保证已被删除,因此此广播可能未定义的行为。
See THIS question了解详情。
出于这个原因,我总是建议使用始终有效的&tab1[0][0]
。