正确的赋值方法p = a;或者p = &a[0];
我之所以有题目的想法是建立在:
a存放的是a[0]的地址 a[0]存放a[0][0]的地址;
因为p = a,所以*p 等价于a[0]
或者因为:*和&符号互逆 根据p = &a[0]所以*p = *&a[0]所以*p = a[0]
你看一下我对上一个答主的反驳,没问题的话我就采纳你了
追答采纳谁是你的事。但人家答“因为p = a,所以*p 等价于a[0]”这一点都不错,是说有了p = a;,*p 就是a[0]——而我的回答是说不能*p=a[0];,这原因不是因为*p不等于a[0](它们是相等的,有了p = a;后*p就已经等于a[0]了),而是因为*p是常指针,不能为其赋值。别说赋a[0],赋什么都不行;你可以试一下给a[0]赋一个值就不行,既然*p就是a[0],当然也不能给*p赋值了。因为常数不能作左值。当你**p时就是a[0][0],a[0][0]是个允许变更的元素(const修饰的除外),所以**p也是可以赋值的。所以采纳谁不重要,重要的是把“数组与指针”搞清楚——这里确实有点难度,但理解了指针的实质就并不复杂。所以我们的回答并不相悖。多说两句:声明int a[3][4];后,凡是a[x][y](0<=x<3,0<=y<4)都可以重新赋值,但a[x]是不能重新赋值的,因为它们是常指针(数组名)。那么,有了p=a;后,*p就是a[0],既然a[0]不能重新赋值,换个写法*p若能重新赋值那不乱套了?
麻烦答主再看一下第二个回答(看到第二个句号就可以了),你们两的回答都能解释,但是理解好像是相悖的。
我认同他的解释,因为按照你的理解,那么我是不是可以直接打印*p,但是直接打印*p会警告,忽略警告打印错误(应该是十进制的地址)而打印**p是没有警告的而且能出正确答案
我按你说的样子写了一个例子,运行出来的(a[3][4])内存片段如下:0x0036FC1C 00 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00 0a 00 00 00 0b 00 00 00 0c 00 00 00 0d 00 00 00 14 00 00 00 15 00 00 00 16 00 00 00 17
以上为16进制,翻译一下就是:0 1 2 3 10 11 12 13 20 21 22 23
可以看出,从a开始,a[0][0]--->a[3][4]是依次排列的,而且里面没有存放指针地址,而是直接存放的数据内容,所以你一开始的命题(a存放的是a[0]的地址 a[0]存放a[0][0]的地址;)就已经错了。