C语言若已定义"int a[3][4],(*p)[4];"下列赋值表达式中正确的是 A. p=*a

求大神解答,越详细越好A. p=*a B. p=a-1
C. p=*a+2 D. p=a+2

int (*p)[4]是一个数组指针,也就是一个指针变量,指向一个int a[4]这样的一维数组,a是随意取的名字。一般简单的认为,数组和指针是非常相似的,所以可简单粗略的认为,这是一个二维数组。
假设存在一条语句:int a[4]={1,2,3,4},*p=a;a是数组a[4]的首地址。a+0,a+1,a+2,a+3分别代表了&a[0],&a[1],&a[2],&a[3]。这样说其实我觉得很不直观。实际上就是指数组a[4]的0,1,2,3对应的地址。因为前面说了,数组和指针极度类似,a[1]指的是数组a[4]的第1个位置里面的值2。而*(a+1)也是这个值。那么&a[0]就相当于&(*(a+1)),那这不就是重复啰嗦吗。*是取(a+1)这个地址里面的值。&则是取这个值所在的地址,那么&(*(a+1))实际就是a+1。也就是说a+1是一个地址。这里感觉有点啰嗦,但实际上都是为了更好的理解下面我想类比引出的二维数组的知识。
再假设存在一条语句:int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12},**p;类比一维数组,a同样是a[3][4]的首地址,但是a+1却是二维数组第1行的首地址。a+2则是第2行的首地址。现在可以选定二维数组的第0列第n行的地址,却不能选定某m行某n列的地址。再继续类比一维数组。在一维数组中,一个*就可以取出值来,那么在二维中就需要**。但我们要明白的是,一个*在二维中的作用是什么。在我的理解中,一个*在二维中就是一个"锁定"行的作用。因为就算是(a+1)+1的地址也不是a[1][1]的地址。因为(a+1)+1与a+2没区别。所以需要先通过一个*锁定在某一行,再加值就会确定某一列,如*(a+1)+1,此时指的就是a[1][1]的地址,再来一个*就是二维数组第1行第1列的值5了,如*(*(a+1)+1)。
有了前置知识,再来理解选项会好一点。
A、*p是一维指针变量,这里需要存一个一维的地址。也就是说只能出现行,不能出现列的地址。*a可以等同为*(a+0)+0,指的是a[0][0]的地址。不行。
B、a-1不是数组a[3][4]的地址,不在范围内。
C、这个和A判断一样,*(a+2)等同于*(a+2)+0,确定了行和列。不行。
D、a+2是a[3][4]中的第2行的首地址。
其实,上面最难理解的是为什么a+1和*(a+1)+0明明在地址上是一模一样的,一个是对,另一个却是错,原因就在于(*p)[4],*p仅占一半,[4]占另一半。因为在一维数组中,[]起到了*的作用。所以我们填a+1,再加上实际的[]就构成了二维数组。如果填*(a+1)+0,再加上[]就成3维 了。大概是这样理解吧。
---------------------------------------------------------------------------------------------
讲的有点乱,第一次写回答。大概看看就行,文中应该有部分是不对的,甚至全文都走偏了,仅供参考哈。我就是这样理解的。有不对之处,还望海涵。我自己也是初学者。
温馨提示:答案为网友推荐,仅供参考
第1个回答  2019-08-05
A和c为int*类型
b范围不在数组里
选d本回答被网友采纳