开始:所有的题目都将画图,加深理解
指针实例:
1.
解析:首先a是一个二维数组,每行有五个元素,因为数组在内存中是连续存放的,所以我们画图画成这样,便于理解,题中p是个数组指针,指向的每个数组有四个元素,所以p在图中每次会跳过四个整形元素,而a是数组首元素地址,每次跳过五个整形,最后看到 &p[4][2] 和 &a[4][2]之间相差四个元素,而我们知道数组元素地址是从低到高排列的,所以p指向的地址比a的小,因此最后结果应该是-4。
接下来说一下打印结果:
%d打印-4就是-4,而%p可是地址打印符,他要打印-4在内存中的补码,所以我们还需要在花点心思
上代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{
//前提得在x86环境下,x64得到的地址会更长一些
printf("%p",-4);
/*-4
10000000000000000000000000000100 原
11111111111111111111111111111011 反 符号位不变按位取反
11111111111111111111111111111100 补 +1
结果:FFFFFFFC*/
return 0;
}
%p按十六进制打印出来-4的补码就是FFFFFFFC,那么这道题就完事啦!
做题结论:这道题主要考察我们对数组指针的引用和熟悉,还有对原反补和进制的熟练程度
2.
解析:这道题也是看我们能不能对二维数组也把指针运用的很熟练,aa是一个二维数组,ptr1拿到它数组的指针然后加1,跳过了整个数组,而ptr2拿到的是数组首元素地址,也就是数组第一行的地址,这时加1,跳过第一行来到第二行6的地址,打印的时候分别减1,都得到前一个元素的地址
打印结果: 10 5
本人理解:指针的解引用或者指针加减整数等等这些运算,都是看指针本身的类型!
3.
解析:这道题不是很难,a是一个字符指针数组,二级指针pa指向它,pa++,相当于指向了a[2],也就是at,因为占位符是%s,打印字符串,所以沿着a的地址一直打印知道遇到\0结束!
打印结果:at
较难指针实例:
解析:这道题还是比较难的,需要细心画图,首先看他们的关系,cpp指向cp,cp指向c,然后在看需要运算的式子
第一个:**++cpp,先将cpp指向的cp+1,指向了c+2,然后两个解引用符号(*),先取到c+2的地址,在取c+2所指向的POINT的地址,最后打印出POINT。
第二个:* -- * ++cpp +3,因为++优先级高,所以先算++,再看*,最后才是+3,所以这个顺序就是,++cpp,因为之前cpp已经自加了一次,指向了c+2,所以我们这次加是从c+2开始的,c+2再加1指向了c+1,然后解引用取到c+1,在自减1,变成了c,再解引用,取到c所指向的地址ENTER,最后+3跳过三个字符,打印出ER。
第三个:*cpp[-2]+3中的*cpp[-2]可以看做*(*(cpp-2)),我们这次还是从图中由c+1已经变成c的位置开始,首先cpp减2指向了c+3的地址然后解引用取到c+3,解引用取到c+3指向的FIRST,最后加3跳过三个字符,指向了S的位置,打印出ST。
第四个:cpp[-1][-1]+1就相当于,*(*(cpp-1)-1)+1,那么还是从图中由c+1已经变成c的位置开始,cpp减1指向了c+2,解引用取到c+2,然后c+2在减1变成了c+1在解引用取到c+1所指向的NEW的地址,最后计算+1,跳过一个字符,打印出EW。
做题结论:本题需要非常细心的去做,并且还考察我们是否记得++或--这种带有副作用的操作符!