Q在将静态分配和动态分配的多维数组传递给函数时,如何才能互换使用它们?
A没有单一的完美方法。鉴于声明
int array[NROWS][NCOLUMNS]; int **array1; /* ragged */ int **array2; /* contiguous */ int *array3; /* "flattened" */ int (*array4)[NCOLUMNS];以及指针初始化方式如问题 6.16 中的代码片段所示,以及声明为
int (*array5)[NROWS][NCOLUMNS];
void f1a(int a[][NCOLUMNS], int nrows, int ncolumns); void f1b(int (*a)[NCOLUMNS], int nrows, int ncolumns); void f2(int *aryp, int nrows, int ncolumns); void f3(int **pp, int nrows, int ncolumns);其中f1a和f1b接受传统的二维数组,f2接受一个“展平”的二维数组,并且f3接受一个指针的指针,模拟数组(另见问题 6.18 和 6.19),以下调用应该可以按预期工作
f1a(array, NROWS, NCOLUMNS); f1b(array, NROWS, NCOLUMNS); f1a(array4, nrows, NCOLUMNS); f1b(array4, nrows, NCOLUMNS);以下调用可能在大多数系统上运行,但涉及可疑的类型转换,并且仅在动态ncolumns与静态NCOLUMNS:
f1(*array5, NROWS, NCOLUMNS);
f2(&array[0][0], NROWS, NCOLUMNS); f2(*array, NROWS, NCOLUMNS); f2(*array2, nrows, ncolumns); f2(array3, nrows, ncolumns); f2(*array4, nrows, NCOLUMNS);
f2(**array5, NROWS, NCOLUMNS);
f3(array1, nrows, ncolumns); f3(array2, nrows, ncolumns);
f1a((int (*)[NCOLUMNS])(*array2), nrows, ncolumns); f1a((int (*)[NCOLUMNS])(*array2), nrows, ncolumns); f1b((int (*)[NCOLUMNS])array3, nrows, ncolumns); f1b((int (*)[NCOLUMNS])array3, nrows, ncolumns);
匹配时才有效。可以注意到,只有f2可以方便地与静态分配和动态分配的数组一起使用,尽管它*不*适用于传统的“不规则”数组实现,array1。然而,还必须指出,传递&array[0][0](或等效地,*array)给f2不完全符合规范;参见问题 6.19。
如果你能理解以上所有调用为何能工作以及它们的写法,并且理解为什么未列出的组合不起作用,那么你对 C 语言中的数组和指针有非常好的理解。
与其担心所有这些,不如采用一种方法来使用各种大小的多维数组,那就是让它们*全部*动态化,如问题 6.16 所示。如果不存在静态多维数组——如果所有数组都像问题 6.16 中的array1或array2一样分配——那么所有函数都可以这样编写:f3.
其他链接: 示例源代码(“压力测试”)说明了所有这些技术