我在编译下面的代码时使用了 gcc 使用 -Wall -Werror
而且编译得很干净,运行得很正常;但是,我只是好奇,在 美国国家标准协会 或 ISO C 上下文中,传递一个 (double ***)
指针 (void **)
.
该 ISOIEC 9899:2017第6.6-9节说
"数组脚本
[]
和成员访问.
和->
操作员,地址&
和间接性*
单元运算符,以及 指针投掷 可用于创建地址常数,但不得通过使用这些运算符来访问对象的值"。
"关于这项建议,函数 allocateMatrix
事实上,应该是 只是 分配内存并返回相应的地址;所以,请忽略分配值的内部循环,它只是为了测试目的。
void allocateMatrix(int n, void **a) {
int i = 0, j = 0;
double **pTmp = calloc(n, sizeof(double *));
for (i = 0; i < n; i++) {
pTmp[i] = malloc(n * sizeof(double));
// following loop is inserted to make sure code runs as expected
// this does not exists in real code
for (j = 0; j < n; j++) {
pTmp[i][j] = (double)(i + 1) + (double)(j + 1) / 10.0f;
}
}
*a = pTmp;
return;
}
int main(int argc, char const *argv[]) {
int i = 0, j = 0;
int n = 5;
double **a = NULL;
// "a" is a (double **) pointer; so, "&a" is now a (double ***) pointer
allocateMatrix(n, (void **)&a);
// testing...
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
printf("%6.2lf", a[i][j]);
}
printf("\n");
}
return 0;
}
C标准允许转换为和从 void *
然而,该律师并 不 有的是 void **
.
将函数参数改为 void *
并将其适当地转码,就可以使用了。
void allocateMatrix(int n, void *a) {
...
*(double ***)a = pTmp;
}
并将函数调用中的cast改为删除。
allocateMatrix(n, &a);