以下是问题: 该计划的输出是什么?
#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个部分,请告诉我每个输出的原因。 谢谢!
答案 0 :(得分:8)
有一个名为array decay的概念在起作用。另外,通过cdecl传递每个定义。
第二行是
将v声明为指向int
的数组10的指针
因此它是一个指向10个元素数组的指针。此指针初始化为A
- 它指向的数组是A
的第一行。
然后,v+1
是另一个指向10个元素数组的指针,跟随第一个元素。因此,它是A
的第二行。
答案 1 :(得分:3)
在**v
中,*v
将被v[0]
的值替换,这是一个地址,比如X
,因此外部*
}将用于表示地址X
的值,即1
。
在**(v+1)
中,*(v+1)
将成为v[1]
,这又是一个地址,比如Y
,外部星号将在地址处给出值Y
,11
。
*(*v+1)=2
=&gt; *(v[0] + 1)
=&gt;此处指针移至下一个位置,此位置为v[0][1]
,类似于*(*(v+0)+1)
。 v[0][1]
的值为2
。
*(v[0]+1)=2
,同样的原因。
*(v[1])=11
,v[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)
指向第一行的第二个元素。
在此之后,弄清楚剩下的可能很容易。