C99 对多维数组的一维访问:它是定义良好的行为吗?
我想我们都同意,通过以一维方式解引用指向其第一个元素的指针(可能是偏移量),访问真正的多维数组被视为惯用C,例如:C99 对多维数组的一维访问:它是定义良好的行为吗?,c99,c,pointers,multidimensional-array,standards,language-lawyer,C99,C,Pointers,Multidimensional Array,Standards,Language Lawyer,我想我们都同意,通过以一维方式解引用指向其第一个元素的指针(可能是偏移量),访问真正的多维数组被视为惯用C,例如: void clearBottomRightElement(int *array, int M, int N) { array[M*N-1] = 0; // Pretend the array is one-dimensional } int mtx[5][3]; ... clearBottomRightElement(&mtx[0][0], 5, 3); 然
void clearBottomRightElement(int *array, int M, int N)
{
array[M*N-1] = 0; // Pretend the array is one-dimensional
}
int mtx[5][3];
...
clearBottomRightElement(&mtx[0][0], 5, 3);
然而,我身上的语言律师需要让我相信这实际上是定义良好的C!特别是:
struct {
int row[3]; // The object in question is an int[3]
int other[10];
} foo;
int *p = &foo.row[7]; // ERROR: A crude attempt to get &foo.other[4];
int mtx[5][3];
int (*row)[3] = &mtx[0]; // The object in question is still an int[3]
int *p = &(*row)[7]; // Why is this any better?
因此,根据同样的规则,人们会认为以下内容是未定义的:
struct {
int row[3]; // The object in question is an int[3]
int other[10];
} foo;
int *p = &foo.row[7]; // ERROR: A crude attempt to get &foo.other[4];
int mtx[5][3];
int (*row)[3] = &mtx[0]; // The object in question is still an int[3]
int *p = &(*row)[7]; // Why is this any better?
那么,为什么要定义这一点呢
int mtx[5][3];
int *p = &(&mtx[0][0])[7];
- 您在
中所做的操作是有效的clearBottomRightElement
int*p=&foo.row[7]代码>未定义
inti=mtx[0][5]代码>未定义
int*p=&row[7]代码>未编译(gcc同意我的意见)
int*p=&mtx[0][0])[7]代码>处于灰色区域(上次我查看类似这样的详细信息时,我考虑了无效的C90和有效的C99,可能是这里的情况,也可能是我遗漏了一些内容)
- 您在
中所做的操作是有效的clearBottomRightElement
int*p=&foo.row[7]代码>未定义
inti=mtx[0][5]代码>未定义
int*p=&row[7]代码>未编译(gcc同意我的意见)
int*p=&mtx[0][0])[7]代码>处于灰色区域(上次我查看类似这样的详细信息时,我考虑了无效的C90和有效的C99,可能是这里的情况,也可能是我遗漏了一些内容)
- 我对的理解是,不要求多维数组必须在内存中按连续顺序排列。遵循我在标准中找到的唯一相关信息(每个维度保证是连续的)
如果您想使用x[COLS*r+c]访问,我建议您坚持使用一维数组
数组下标
连续的下标运算符指定多维数组对象的元素。
如果E是n维数组(n≥ 2) 尺寸为i×j×。x k,然后E(用作
而不是左值)转换为指向(n)的指针− 1) 二维数组
尺寸j×。×k。如果一元*运算符显式应用于此指针,或
作为订阅的隐式结果,结果是指向(n)的− 1) -维数组,
如果用作左值以外的值,则其本身将转换为指针。由此而来
数组按行主顺序存储(最后一个下标变化最快)
数组类型
-数组类型描述了一组连续分配的非空对象,其中
特定的成员对象类型,称为元素类型。
36)
数组类型为
以其元素类型和数组中元素的数量为特征。一
数组类型称为从其元素类型派生,如果其元素类型为T,则
数组类型有时称为“T的数组”。从中构造数组类型
元素类型称为“数组类型派生”。我的理解是,不要求多维数组必须在内存中按连续顺序排列。遵循我在标准中找到的唯一相关信息(每个维度保证是连续的)
如果您想使用x[COLS*r+c]访问,我建议您坚持使用一维数组
数组下标
连续的下标运算符指定多维数组对象的元素。
如果E是n维数组(n≥ 2) 尺寸为i×j×。x k,然后E(用作
而不是左值)转换为指向(n)的指针− 1) 二维数组
尺寸j×。×k。如果一元*运算符显式应用于此指针,或
作为订阅的隐式结果,结果是指向(n)的− 1) -维数组,
如果用作左值以外的值,则其本身将转换为指针。由此而来
数组按行主顺序存储(最后一个下标变化快)
(mtx[0] + 3) + 2