您如何尊重指向数组的指针以获取存储在其中的值?例如:
void testFunction(int **test){
printf("%d", *test[1]);
}
int main()
{ int test[10];
test[1] = 5;
testFunction(&test);
return 0;
}
我得到一个错误。谁能解释一下?
您如何尊重指向数组的指针以获取存储在其中的值?
您使用*
运算符,就像每个指针一样。(哦,注意运算符优先级!)
void foo(int (*arr)[5])
{
printf("%d\n", (*arr)[0]);
}
int main()
{
int arr[5] = { 0, 1, 2, 3, 4 };
foo(&arr);
return 0;
}
您的代码会生成有关传递给函数的不兼容类型的诊断信息。例如,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);
这会将 to 的地址传递test
给testFunction
。变量的地址对应于它在内存中的位置。这对于数组来说并没有太大的不同,但是数组变量在内存中的位置是它的第一个元素的地址。因此,&test
上面返回的地址与test
单独返回的地址相同。
int
当您将此指针值视为指向testFunction
. 首先,请注意您忽略了正确的运算符优先级,因此第一个取消引用是:
test[1]
由于您将test
参数声明为指向 的指针的指针int
,因此这会将地址递增test
bysizeof(int *)
并将结果视为int *
. 然后,您再次取消引用:
*test[1]
现在,这将获取 的值test[1]
并再次取消引用它以尝试获取int
. 但是,返回的地址与 中定义test[1]
的数组没有关系,并且您正在访问一个完全无意义的内存位置。test
main
即使您注意指向int
参数类型的指针的优先级,也会导致类似的问题。
(*test)[1]
现在,指针int[10]
被视为指向指针的指针首先int
被引用。这导致数组的第一个sizeof(int **)
字节被视为指向. 此时这已经是一个无意义的值,但数组取消引用现在将该值增加字节并取消引用该值以尝试获取.test
main
int
sizeof(int)
int
另一个用户已经举了一个例子,说明它通常是如何完成的,但如果你坚持传递一个 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]。