多维数组索引
Multidimensional Array indexing
我在几个地方读到过,这样分配多维数组效率低下,应该避免。
int main(){
int** arr2d = malloc(3*sizeof(int*));
for(int m = 0; m < 3 ; ++m){
arr2d[m] = malloc(sizeof(int)*3);
}
for(int m = 0 ; m < 3 ; ++m){
for(int n = 0; n < 3; ++n){
arr2d[m][n] = m+n;
}
}
for(int m = 0 ; m < 3 ; ++m){
for(int n = 0; n < 3; ++n){
printf("%d,",arr2d[m][n]);
}
printf("\n");
}
for(int m = 0; m < 3 ; ++m){
free(arr2d[m]);
}
free(arr2d);
return 0;
}
另一种方法是为 m*n 分配一个足够的数组并相应地对其进行索引,给出 2D
的想法
int main(){
int* arr = malloc(9*sizeof(int));
for(int m = 0; m < 3; ++m){
for(int n = 0; n < 3; ++n){
int index = m*3+n;
arr[index] = m+n;
}
}
for(int m = 0; m < 3; ++m){
for(int n = 0; n < 3; ++n){
int index = m*3+n;
printf("%d,",arr[index]);
}
printf("\n");
}
free(arr);
return 0;
}
我想知道的是,这在资源使用和时间安排方面究竟有多大差异?
我知道在第一个示例中总共分配了 32 个字节,在第二个示例中分配了 27 个字节。在处理更大的矩阵时,我可以看到有所不同,但是时间复杂度会改变还是无关紧要,因为无论如何都要循环 m*n 次?
我应该始终遵循第二个示例作为基本标准吗?
如果你有一个矩形矩阵,即所有 m x n 值,那么使用第二个选项会更简单、内存消耗更少并且更不容易出错(尽管它可以说仍然是一个品尝者的问题.... ).
如果你没有长方形的东西,第一个选项会更有效,例如类似于不同长度的子数组的数组。
内存浪费在那里变得非常重要。
另一个例子,回到矩阵,将是一个三角矩阵,在三角形之外有 0 或其他已知值。实现可以从该属性中受益,并使用三角形外部的“无聊”或可预测值,而无需存储它们。
您可以通过直接为多维数组分配内存来两全其美:
int (*arr)[3] = malloc(3 * sizeof *arr);
for(int m = 0 ; m < 3 ; ++m){
for(int n = 0; n < 3; ++n){
arr[m][n] = m+n;
}
}
for(int m = 0 ; m < 3 ; ++m){
for(int n = 0; n < 3; ++n){
printf("%d,",arr[m][n]);
}
printf("\n");
}
free(arr);
这会像第二个示例一样在单个连续块中创建内存,从而提高读写效率,并为您提供二维数组索引,从而更易于阅读代码并让编译器找出最佳方法在内部索引内存块。
我在几个地方读到过,这样分配多维数组效率低下,应该避免。
int main(){
int** arr2d = malloc(3*sizeof(int*));
for(int m = 0; m < 3 ; ++m){
arr2d[m] = malloc(sizeof(int)*3);
}
for(int m = 0 ; m < 3 ; ++m){
for(int n = 0; n < 3; ++n){
arr2d[m][n] = m+n;
}
}
for(int m = 0 ; m < 3 ; ++m){
for(int n = 0; n < 3; ++n){
printf("%d,",arr2d[m][n]);
}
printf("\n");
}
for(int m = 0; m < 3 ; ++m){
free(arr2d[m]);
}
free(arr2d);
return 0;
}
另一种方法是为 m*n 分配一个足够的数组并相应地对其进行索引,给出 2D
的想法int main(){
int* arr = malloc(9*sizeof(int));
for(int m = 0; m < 3; ++m){
for(int n = 0; n < 3; ++n){
int index = m*3+n;
arr[index] = m+n;
}
}
for(int m = 0; m < 3; ++m){
for(int n = 0; n < 3; ++n){
int index = m*3+n;
printf("%d,",arr[index]);
}
printf("\n");
}
free(arr);
return 0;
}
我想知道的是,这在资源使用和时间安排方面究竟有多大差异? 我知道在第一个示例中总共分配了 32 个字节,在第二个示例中分配了 27 个字节。在处理更大的矩阵时,我可以看到有所不同,但是时间复杂度会改变还是无关紧要,因为无论如何都要循环 m*n 次? 我应该始终遵循第二个示例作为基本标准吗?
如果你有一个矩形矩阵,即所有 m x n 值,那么使用第二个选项会更简单、内存消耗更少并且更不容易出错(尽管它可以说仍然是一个品尝者的问题.... ).
如果你没有长方形的东西,第一个选项会更有效,例如类似于不同长度的子数组的数组。
内存浪费在那里变得非常重要。
另一个例子,回到矩阵,将是一个三角矩阵,在三角形之外有 0 或其他已知值。实现可以从该属性中受益,并使用三角形外部的“无聊”或可预测值,而无需存储它们。
您可以通过直接为多维数组分配内存来两全其美:
int (*arr)[3] = malloc(3 * sizeof *arr);
for(int m = 0 ; m < 3 ; ++m){
for(int n = 0; n < 3; ++n){
arr[m][n] = m+n;
}
}
for(int m = 0 ; m < 3 ; ++m){
for(int n = 0; n < 3; ++n){
printf("%d,",arr[m][n]);
}
printf("\n");
}
free(arr);
这会像第二个示例一样在单个连续块中创建内存,从而提高读写效率,并为您提供二维数组索引,从而更易于阅读代码并让编译器找出最佳方法在内部索引内存块。