关于C:指针和二维数组

时间:2013-08-05 09:07:10

标签: c arrays pointers

以下是问题: 该计划的输出是什么?

#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个部分,请告诉我每个输出的原因。 谢谢!

3 个答案:

答案 0 :(得分:8)

有一个名为array decay的概念在起作用。另外,通过cdecl传递每个定义。

第二行是

  

将v声明为指向int

的数组10的指针

因此它是一个指向10个元素数组的指针。此指针初始化为A - 它指向的数组是A的第一行。

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

答案 1 :(得分:3)

  1. **v中,*v将被v[0]的值替换,这是一个地址,比如X,因此外部* }将用于表示地址X的值,即1

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

  3. *(*v+1)=2 =&gt; *(v[0] + 1) =&gt;此处指针移至下一个位置,此位置为v[0][1],类似于*(*(v+0)+1)v[0][1]的值为2

  4. *(v[0]+1)=2,同样的原因。

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

答案 2 :(得分:0)

好的,让我们首先回顾一下阵列是如何衰变的,其次是声明是如何工作的。

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

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

int (*v)[10] = A;

是一个表达式,因此A已经衰减到指向10个int的指针,因此赋值是有效的。

现在,当您查看**v时,您首先取消引用v,这意味着您将获得v指向的内容,这是您的2D数组的第一行。然后你解除引用*v,这意味着你得到第一行的第一个元素。那是1,所以你的输出是1。

当您查看**(v + 1)时,您首先在指针v中添加1。由于v指向一行,因此添加1会获得指向下一行的指针。然后你进行上面的双重解除引用,你得到下一行的第一个元素,即11。

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

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

在此之后,弄清楚剩下的可能很容易。