0

您如何尊重指向数组的指针以获取存储在其中的值?例如:

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

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

我得到一个错误。谁能解释一下?

4

3 回答 3

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;
}
于 2013-06-04T20:07:58.757 回答
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);

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

int当您将此指针值视为指向testFunction. 首先,请注意您忽略了正确的运算符优先级,因此第一个取消引用是:

test[1]

由于您将test参数声明为指向 的指针的指针int,因此这会将地址递增testbysizeof(int *)并将结果视为int *. 然后,您再次取消引用:

*test[1]

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

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

(*test)[1]

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

于 2013-06-04T20:06:10.247 回答
-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]。

于 2013-06-04T20:05:47.883 回答