prev up next   top/contents search

comp.lang.c FAQ 列表· 问题 6.20

Q在将静态分配和动态分配的多维数组传递给函数时,如何才能互换使用它们?


A没有单一的完美方法。鉴于声明

	int array[NROWS][NCOLUMNS];
	int **array1;			/* ragged */
	int **array2;			/* contiguous */
	int *array3;			/* "flattened" */
	int (*array4)[NCOLUMNS];

int (*array5)[NROWS][NCOLUMNS];
以及指针初始化方式如问题 6.16 中的代码片段所示,以及声明为
	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);
其中f1af1b接受传统的二维数组,f2接受一个“展平”的二维数组,并且f3接受一个指针的指针,模拟数组(另见问题 6.186.19),以下调用应该可以按预期工作
	f1a(array, NROWS, NCOLUMNS);
	f1b(array, NROWS, NCOLUMNS);
	f1a(array4, nrows, NCOLUMNS);
	f1b(array4, nrows, 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);
以下调用可能在大多数系统上运行,但涉及可疑的类型转换,并且仅在动态ncolumns与静态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 中的array1array2一样分配——那么所有函数都可以这样编写:f3.

其他链接: 示例源代码(“压力测试”)说明了所有这些技术


prev up next   contents search
关于此 FAQ 列表   关于 Eskimo   搜索   反馈   版权

Eskimo North 托管