在 C 语言中,对于大的 m 和 n 值,一个 m×n 的二维数组和一个长度为 m×n 的一维数组,在时间和空间上是否有差别?访问数组元素时,使用一维数组会更快吗?
A[row][col]
的表示方式类似于A[row*NCOLS+col]
。int getIndex(int row, int col) { return row*NCOLS+col; }
#define NROWS 10
#define NCOLS 20
这个:
int main(int argc, char *argv[]) {
int myArr[NROWS*NCOLS];
for (int i=0; i<NROWS; ++i) {
for (int j=0; j<NCOLS; ++j) {
myArr[getIndex(i,j)] = i+j;
}
}
return 0;
}
int main(int argc, char *argv[]) {
int myArr[NROWS][NCOLS];
for (int i=0; i<NROWS; ++i) {
for (int j=0; j<NCOLS; ++j) {
myArr[i][j] = i+j;
}
}
return 0;
}
虽然AraK指出,如果您频繁跳转行且行非常大,则可能会遇到许多页面错误...在这种情况下,自定义索引函数(行和列交换)可能有所帮助,但只需更改将二维数组中哪个维度视为行,哪个维度视为列即可。
罗伯特是正确的,索引表达式被编译为指针算术表达式,因此没有区别。
然而,访问顺序可以影响性能,所以您可能希望自己实现来控制访问顺序。例如,列优先和行优先形式。
在现代处理器上,以各种步幅访问大型数组可能会产生意外的性能差异。顺序访问始终最快,其他步幅可能由于缓存交互而慢至多30倍。内部维度为2的幂次方的多维数组通常具有较差的性能,因为它们与缓存联想方式的交互方式不同。要理解这些问题,真正的替代品是进行测量。
我认为两者没有任何区别。在内部,C将二维数组视为多个按顺序排列的一维数组。
然而,就性能而言,实际情况可能会有所不同。可能存在某种微妙的指针算术差异。在两种情况下运行定时测试。哪种运行更快,就采用哪种。
int **array
,然后你可以使用array = malloc(sizeof(int*)*rows); for (i = 0; i < rows; ++i) { array[i] = malloc(sizeof(int) * cols); }
来创建数组。这样做的好处是虽然访问和创建速度较慢,但添加行的速度更快。 - derobert
array[row][column]
或者array[column][row]
来选择使用哪种布局。 - derobert