使用 (void **) 传递 (double ***) 指针是否可以?
Is it OK to pass (double ***) pointers using (void **)?
我使用 gcc 使用 -Wall -Werror
编译下面的代码,它编译得很干净,按预期运行;但是,我只是好奇在 ANSI and/or ISO C 上下文中是否可以传递 (double ***)
指针通过 (void **)
.
ISO/IEC9899:2017,第 6.6-9 节说:
"The array-subscript []
and member-access .
and ->
operators,
the address &
and indirection *
unary operators, and pointer
casts may be used in the creation of an address constant, but the
value of an object shall not be accessed by use of these operators."
关于这个建议,函数allocateMatrix
实际上应该只是分配内存和return相应的地址;所以,请忽略分配值的内部循环,它仅用于测试目的。
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 **
。
not 存在 lattitute
将函数参数更改为 void *
并适当地转换它,它将起作用。
void allocateMatrix(int n, void *a) {
...
*(double ***)a = pTmp;
}
并更改从函数调用中删除强制转换:
allocateMatrix(n, &a);
我使用 gcc 使用 -Wall -Werror
编译下面的代码,它编译得很干净,按预期运行;但是,我只是好奇在 ANSI and/or ISO C 上下文中是否可以传递 (double ***)
指针通过 (void **)
.
ISO/IEC9899:2017,第 6.6-9 节说:
"The array-subscript
[]
and member-access.
and->
operators, the address&
and indirection*
unary operators, and pointer casts may be used in the creation of an address constant, but the value of an object shall not be accessed by use of these operators."
关于这个建议,函数allocateMatrix
实际上应该只是分配内存和return相应的地址;所以,请忽略分配值的内部循环,它仅用于测试目的。
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;
}
并更改从函数调用中删除强制转换:
allocateMatrix(n, &a);