我从朋友那里听说C中的二维数组只能在语法上得到支持.
他告诉我要更好地使用,float arr[M * N]
而不是float[M][N]
因为像gcc这样的C编译器不能保证在每个系统/平台上数据都在内存中串联.
我想在我的硕士论文中用它作为论据,但我没有任何参考.
所以第一个问题:
他说的是对的吗?
第二个问题:
你知道是否有书或文章在哪里可以找到这个陈述?
谢谢+问候
Car*_*rum 13
不,他错了.
看看C标准.一些相关的位(大胆强调我的):
6.2.5类型20
一个阵列型描述了一种连续地分配与特定的成员对象类型的非空的对象集,被称为元素类型.
6.7.6.2数组声明符3(注释142)
当几个"数组"规范相邻时,声明了一个多维数组.
6.5.2.1数组下标3
连续的下标运算符指定多维数组对象的元素.......由此得出,数组以行主要顺序存储(最后一个下标变化最快).
也许最明确的是,6.5.2.1数组下标中的例子4:
示例考虑声明定义的数组对象
int x[3][5];
这
x
是一个3×5的int
s 数组 ; 更精确地,x
为三个元素对象,其每一个是五个数组的数组int
小号.在表达式中x[i]
,它等效于(*((x)+(i)))
,x
首先转换为指向初始数组为5int
的指针.然后i
根据类型调整x
,其在概念上需要乘以i
指针所指向的对象的大小,即五个int
对象的数组.添加结果并应用间接以产生五秒int
的数组.在表达式中使用时x[i][j]
,该数组又转换为指向第x[i][j]
一个int 的指针,因此产生一个int.
C中的多维数组只是"数组数组".它们工作正常,100%由标准定义.
您可能还会发现在comp.lang.c FAQ中阅读第6节"数组和指针"很有帮助.
问题比其他答案听起来更微妙:
虽然多维数组(在语义上,可能不是物理上)是连续的,但只有当你保持在指针最初引用的数组的范围内时,才会定义指针算术(实际上,你可以超过上限1个元素,但仅限于你不要取消引用).
这意味着语言语义禁止从头到尾遍历多维数组,并且C语言的边界检查实现(原则上可能但由于性能原因很少见到)可能会引发段错误,打印当您穿过子阵列的边界时,诊断或使恶魔从鼻子飞出.
我不确定编译器是否将此信息用于优化目的,但原则上他们可以.例如,如果你有
float *p = &arr[2][3];
float *q = &arr[5][9];
Run Code Online (Sandbox Code Playgroud)
然后p + x
和q + y
千万别别名,不管值的x
和y
.