C 在函数中取消对数组指针的引用

C 在函数中取消对数组指针的引用,c,arrays,pointers,C,Arrays,Pointers,如何使用指向数组的指针来获取存储在数组中的值?例如: void testFunction(int **test){ printf("%d", *test[1]); } int main() { int test[10]; test[1] = 5; testFunction(&test); return 0; } 我犯了一个错误。任何人都可以解释?另一个用户给出了一个通常是如何完成的示例,但如果您坚持传递int**则由于运算符优先级,语法如下所示: vo

如何使用指向数组的指针来获取存储在数组中的值?例如:

void testFunction(int **test){
  printf("%d", *test[1]);
}

int main()
{   int test[10];
    test[1] = 5;
    testFunction(&test);
    return 0;
}

我犯了一个错误。任何人都可以解释?

另一个用户给出了一个通常是如何完成的示例,但如果您坚持传递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]更常用。

另一位用户给出了一个通常已经完成的示例,但是如果您坚持传递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]更常用。

您的代码会生成一个关于传递给函数的不兼容类型的诊断。例如,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]
的指针被解引用时,结果值是
main
中定义的数组
test
的第一个元素的地址。然后,
[]
操作访问数组的第二个元素,您将获得预期的值


如果您注意到下面的断言总是正确的,那么您可能会更确信您对数组指针使用的
int**test
是错误的:

int test[10];
assert(&test == (void *)test);
正如编译器警告所指出的,指向
int
的指针与指向
int[10]
的指针不同。指向的类型确定由解引用产生的类型

因此:

这将
test
的地址传递到
testFunction
。变量的地址对应于它在内存中的位置。这对于数组来说并没有什么不同,但是数组变量在内存中的位置是它的第一个元素的地址。因此,上面的
&test
返回的地址与
test
单独返回的地址相同

如果将此指针值视为指向
testFunction
int
的指针,则会产生灾难性的后果。首先,请注意,您忽略了适当的运算符优先级,因此第一次取消引用是:

test[1]
由于您将
test
参数声明为指向
int
的指针,这会将
test
中的地址增加
sizeof(int*)
,并将结果视为
int*
。然后,再次取消引用:

*test[1]
现在取
test[1]
的值,并再次取消对它的引用,以获取
int
。但是,
test[1]
返回的地址与
main
中定义的数组
test
没有关系,您正在访问一个完全没有意义的内存位置

即使注意指向
int
参数类型的指针的优先级,也会导致类似的问题

(*test)[1]

现在,指向
int[10]
的指针被视为指向
int
的指针,并首先被去引用。这将导致
main
test
数组的第一个
sizeof(int**)
字节被视为指向
int
的指针。此时,这已经是一个无意义的值,但数组取消引用现在将此值增加
sizeof(int)
字节,并取消引用该值以尝试获得
int

您的代码将生成有关传递给函数的不兼容类型的诊断。例如,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]
的指针被解引用时,结果值是
main
中定义的数组
test
的第一个元素的地址。然后,
[]
操作访问数组的第二个元素,您将获得预期的值


如果您注意到下面的断言总是正确的,那么您可能会更确信您对数组指针使用的
int**test
是错误的:

int test[10];
assert(&test == (void *)test);
正如编译器警告所指出的,指向
int
的指针与指向
int[10]
的指针不同。指向的类型确定由解引用产生的类型

因此:

这将
test
的地址传递到
testFunction
。变量的地址对应于它在内存中的位置。这对于数组来说并没有什么不同,但是数组变量在内存中的位置是它的第一个元素的地址。因此,上面的
&test
返回的地址与
test
单独返回的地址相同

如果将此指针值视为指向
testFunction
int
的指针,则会产生灾难性的后果。首先,请注意