如何取消引用指向数组的指针以获取存储在其中的值?例如:
void testFunction(int **test){
printf("%d", *test[1]);
}
int main()
{ int test[10];
test[1] = 5;
testFunction(&test);
return 0;
}
我收到错误。谁能解释一下?
答案 0 :(得分:3)
如何使用指向数组的指针来获取存储在其中的值?
您使用*
运算符,与每个指针一样。 (哦,注意运营商的优先权!)
void foo(int (*arr)[5])
{
printf("%d\n", (*arr)[0]);
}
int main()
{
int arr[5] = { 0, 1, 2, 3, 4 };
foo(&arr);
return 0;
}
答案 1 :(得分:2)
您的代码会生成有关传递给函数的不兼容类型的诊断信息。例如,GCC抱怨:
prog.c: In function 'main':
prog.c:9: warning: passing argument 1 of 'testFunction' from incompatible pointer type
您应该注意编译器发出的所有诊断信息,并确保理解它们,并采取适当的措施来解决它们。对于这个特定的一个,如果你打算传入一个指向数组的指针,你需要编写你的函数来接受这样的事情。然后,当您取消引用指针时,您有一个数组。所以,你可以像访问它一样访问它。
void testFunction(int (*test)[10]){
printf("%d", (*test)[1]);
}
[]
的优先级高于*
,因此括号既需要函数参数参数,也需要访问printf()
中的值。当指向int[10]
的指针被引用时,结果值是test
中定义的数组main
的第一个元素的地址。然后[]
操作访问数组的第二个元素,并获得您期望的值。
如果您注意到下面的断言始终为真,您可能更确信使用int **test
对指向数组的指针是错误的:
int test[10];
assert(&test == (void *)test);
如编译器警告所示,指向int
的指针与指向int[10]
的指针不同。指向的类型确定取消引用所产生的类型。
所以:
int test[10] = { [1] = 5 };
testFunction(&test);
这会将test
的地址传递给testFunction
。变量的地址对应于它在内存中的位置。这对于数组来说并没有那么不同,但是数组变量的内存中的位置是其第一个元素的地址。因此,上面&test
返回的地址与test
单独返回的地址相同。
当您将此指针值视为指向int
中testFunction
指针的指针时,会产生灾难性后果。首先,请注意您忽略了正确的运算符优先级,因此第一个取消引用是:
test[1]
由于您声明test
参数是指向int
指针的指针,因此test
中sizeof(int *)
的地址增加int *
,并将结果视为{ {1}}。然后,再次取消引用:
*test[1]
现在取test[1]
的值并再次取消引用它以尝试获得int
。但是,test[1]
返回的地址与test
中定义的数组main
没有任何关系,并且您正在访问一个完全没有意义的内存位置。
即使您注意指针指向int
参数类型的指针的优先级,也会产生类似的问题。
(*test)[1]
现在,指向int[10]
的指针被视为指向int
指针的指针首先被引导。这会导致sizeof(int **)
中test
数组的前main
个字节被视为指向int
的指针。此时这已经是一个荒谬的值,但是现在数组解除引用会将此值增加sizeof(int)
个字节,并在尝试获取int
时取消引用该值。
答案 2 :(得分:-1)
另一个用户给出了一个如何通常已经完成的示例,但是如果你坚持传递一个int **,那么由于运算符优先级,语法就像:
void testFunction(int **test){
printf("%d", (*test)[1]);
}
int main()
{ int test[10];
test[1] = 5;
int *testptr= &test[0]; // or int *testptr= test;
testFunction(&testptr); // this passes an int **
return 0;
}
但是在c中,数组的名称是指向数组元素的指针,因此更常用int * ptrtest和ptrtest [1]。