1.第一题:指针带有逗号表达式陷阱
这题一看这么就觉得非常简单,但不能眼高手低。
要将这题完美解答出来需要注意一个知识点:逗号表达式(结果只取最后一个数值);
乍一看,a[3][2]有六个元素分别是0,1,2,3,4,5,其实不然。分布如下图:
这里定义一个指针变量指向p,p=a[0],数组名代表首元素地址,那么p指向的是第一行的地址,又因为二维数组在内存中存放的方式就是连续的一行,所以p就指向第一个元素的地址。
所以 ,p[0]指向的就是a[0][0],值为1
2.第二题:需要掌握画图技能
分析:
这里定义指针数组p,由第87行可知,这个p是二维指针数组变量,这个指针存放啦一个二维数组。%p打印的是地址。&p[4][2]-&a[4][2]是地址之差,也可以看作指针减去指针。指针之差得到的是元素的个数,用%d打印 也就是说明相差多少个元素,理解这些是解题关键。
看到这里顿时感觉无从下手,想要学好指针最重要的是会画图,善于把题目以图的形式画出,困难也就迎刃而解了。
由图可知,p[4][2]与a[4][2]之间元素个数之差为-3,
地址之差%p打印出来的是地址,也就是将-3当作地址打印出来
如何打印?
-3的 原码:10000000000000000000000000000011
取反加一得到补码:
补码:1111111111111111111111111111111111101
用十六进制打印:FFFFFFFC
答案:
3.第三题:深入理解指针
重要的是会画图,这题就不画啦。
93行中 &aa 表示取整个数组的地址,而&aa+1,表示一整个数组为单位加一,那么就是跳过整个数组。所以这里ptr1指向的是10后面的地址。
*(aa+1)中aa是数组名,数组名表示首元素地址,注意aa是二维数组,这里首元素地址是第一行的地址。aa+1,表示第二行元素首地址,*表示解应用,那么就取到啦数组第二行首元素。
*(ptr1-1)就是原本指向10后面的指针向前移动一格,现在便指向啦10;
*(ptr2-1)原本指向第二行首元素的地址的指针向后移动一个单位,现在指向第一行最后一个元素5.
答案:
4.第四题:一道阿里旧题
分析:
char*a[]为指针数组,里面存放的是三个字符串的首字符地址。
char**pa为二级指针,指向的是a[]中的指针。
首先pa指向的是a[]中第一个指针,而这第一个指针存放的地址是“work”的地址,之后pa++;
则pa便指向a[]中第二个指针,这个指针存放存放“at”的地址;
最后对pa解应用,那么得到字符串“at”;
答案:
5.足以说明你已经掌握指针的一题:
这题虽然看起来复杂但只要一点点剖析,难度并不大。
1.首先c[]中存放的并不是四个字符串,是四个字符串首字母的地址,它是指针数组。
2.cp[]中存放的依次为“PIRST”,"POINT","NEW","ENTER"
113行中**++cpp,cpp先加1指向c+2再使用,而c+2则对应着”POINT“
114行,cpp再先加1,解应用则指向c+1对应NEW的首字母地址,这个指针再减去1后解应用指向ENTER,最后加3,则指针向右移动三个字母指向E,则第二个printf打印的是ER.
115行,*cpp[-2]表示在114行指向c+1的基础上,指针后移两个,指向cp中的c+3,再解应用,指向c[]中的FIRSTR,又因为指针加3,表示向右移动三个字母,指向ST的地址
116行中,cpp原本指向c+1,cpp[-1][-1]--->*(cpp-1)[-1]--->*(c+2-1)--->*(c+1)--->NEW,
而cpp[-1][-1]+1中还有加1,所以最后再向右移动一个字符,打印出来的是EW.
答案: