-5

这是一个问题:程序的输出是什么?

#include<stdio.h>
int main()
{
int  A[2][10]={{1,2,3,4,5,6,7,8,9,10},{11,12,13,14,15,16,17,18,19,20}   };
int (*v)[10]=A;

printf("**v=%d\n",**v);
printf("**(v+1)=%d\n",**(v+1));
printf("*(*v+1)=%d\n",*(*v+1));
printf("*(v[0]+1)=%d\n",*(v[0]+1));
printf("*(v[1])=%d\n",*(v[1]));
}

输出:

**v=1
**(v+1)=11
*(*v+1)=2
*(v[0]+1)=2
*(v[1])=11

特别是*v 是如何将数组A 分成10 个部分的,我不是很清楚,请告诉我每个输出的原因。谢谢!

4

3 回答 3

8

有一个叫做阵列衰减的概念在起作用。此外,通过cdecl传递每个定义。

第二行是

将 v 声明为指向 int 数组 10 的指针

因此它是一个指向 10 个元素的数组的指针。这个指针被初始化A——它指向的数组是A.

然后,v+1是另一个指向 10 个元素的数组的指针,位于第一个元素之后。因此,它是第二行A

于 2013-08-05T09:13:15.753 回答
3
  1. 在 中**v*v将被替换为 的值v[0],这是一个地址,例如X,因此外部*将用于指示地址的值X,即1

  2. 在 中**(v+1)*(v+1)将变为v[1],这又是一个地址,例如Y,外部星号将给出地址处的值Y,即11

  3. *(*v+1)=2=> *(v[0] + 1)=> 这里指针移动到下一个位置,这个位置是v[0][1],类似于*(*(v+0)+1)v[0][1]的值为2

  4. *(v[0]+1)=2,同理。

  5. *(v[1])=11,v[1]保存第二行的基地址,即第二行0第列的起始地址,该位置的值为11

于 2013-08-05T09:36:15.863 回答
0

好的,让我们首先回顾一下数组是如何衰减的,其次是声明是如何工作的。

A被声明为二维数组。当A在任何表达式中使用时,它将“衰减”为指向其第一个元素的指针。在 C 中,一个 2D 数组由两个 1D 数组组成。所以二维数组的元素是一维数组。因此,当A在任何表达式中使用时,它将衰减为指向 的第一行的指针A,这是一个 10 个整数的数组。

int (*v) [10]表示这v是一个指向 10 个整数数组的指针。那作业

int (*v)[10] = A;

是一个表达式,所以A也有一个指向 10 个整数的指针,所以赋值是有效的。

因此,现在当您查看 时**v,您首先取消引用v,这意味着您正在获取哪些v点,这是您的二维数组的第一行。然后你正在取消引用*v,这意味着你正在获取第一行的第一个元素。那是 1,所以你的输出是 1。

当您查看时**(v + 1),您首先将 1 添加到指针v。因为v指向一行,所以加 1 可以获得指向下一行的指针。然后像上面那样进行双重取消引用,得到下一行的第一个元素,即 11。

当您查看 时*(*v + 1),您首先取消引用v,这意味着您获得了第一行。然后将 1 加到其中,这将获得指向该行的下一个元素的指针。然后你取消引用它,得到第二个元素 2。

总结:v指向整个第一行。*v指向第一行的第一个元素。(v + 1)指向整个第二行。(*v + 1)指向第一行的第二个元素。

在此之后,弄清楚其余部分可能很容易。

于 2013-08-05T09:44:47.370 回答