&a中a代表的是整个数组,&a+1是跳过a数组的数组地址,将其强制类型转换为整形指针ptr,ptr-1即为向前跳过一个整型元素的整型指针。
a代表数组首元素地址,a+1为跳过一个整型元素的整型指针。
所以答案为2,5.
struct Test的类型变量大小为20字节,是因为int是4个字节,char*在x86的环境下是4个字节,short是两个字节,char [2]数组是2*1个字节,short[4]数组是4*2个字节相加的结果。
a. p+0x1 - -->p+1 是跳过一个20字节的struct Test变量的地址--->0x100000+(十进制的)20=0x100014
b.(unsigned long)p+0x1
第一步,将p强制类型转换,值不变,类型由struct Test*转换为unsigned long。
第二步,0x1换算为十进制的1。
第三步,(unsigned long)p+(unsigned long)1 -->0x100001
c.(unsigned int*)p + 0x1
第一步,将p强制类型转换,值不变,类型由struct Test*转换为int *。
第二步,0x1换算为十进制的1。
第三步,(int *)p+1 -->p跳过一个整型变量的地址-->0x100000+4-->0x100004
这里会涉及到我下次要发布的内容,关于整数在内存中的存储方式大小端。
先简单地了解一下把!
小端存储:低字节的内容存储在低地址处,高字节的内容存储在高地址处。
大端存储:低字节的内容存储在高地址处,高字节的内容存储在低地址处。
由于我使用的vs2019是小端存储,所以该题的角度是站在小端存储的角度去思考的。
ptr1[-1] -->*(ptr1-1)-->4
a代表数组首元素的地址,(int)a将a强制类型转换,值不变,类型由int* 转变为int。a+1是整型间加减,再计算(int*)((int)a+1)强制类型转换a+1,值不变,类型由int型转变为int*。注意:以上加1由于不在int*范围内,不再代表跳过一个整型变量(4个字节),而是整型数值间加减并无其他效果。当将其强制类型转换为int*时等同于跳过一个字节的效果。
在读取十六进制数值时,是自指针起访问4个字节的空间,在将其逆序。这里要考虑到存储是小端存储方式,但是读取是自低字节位向高字节位读起。
数组a的初始化的元素分别为(0,1),(2,3),(4,5),其实是1,3,5三个数字,其余三个数字为0。
像(0,1)这样的表达式是逗号表达式,结果为最后一个算式的结果。
p[0]--> *(p+0) --> *p --> *a[0] --->*&a[0][0] ---> a[0][0]
所以,答案为1。
&p[4][2]--->&*(p[4]+2) --->&*(*(p+4)+2))
p现在是代表a数组首元素的地址,即&a[0]
因为p是int(*)[4] 类型的数组指针,p+4只能是跳过四个含四个整型变量的数组(16个字节)
*(p+4)访问p+4所指向的空间,即p[4]数组
第一个所求为%p 指针与指针的差值为两指针间所包含的元素个数(指针在前减去指针在后为负,指针在后减去指针在前为正),&p[4][2]指针在前,且其与&a[4][2]包含4个元素,再将-4转换为补码打印出
第二个所求为%d 指针与指针的差值为两指针间所包含的元素个数(指针在前减去指针在后为负,指针在后减去指针在前为正),&p[4][2]指针在前,且其与&a[4][2]包含4个元素,答案为-4
所以,答案为:FFFFFFFC ,-4
零碎知识点:%p 打印补码 %u 打印补码 %d 打印原码
由于这道题比较简单,雷同于以上的解题思路,所以不再做解释。
要注意的是 aa代表数组首元素地址,即&aa[0];aa+1跳过一个含五个整型的数组的地址
答案为:10,5。
pa++ 等同于 pa = pa+1 ,pa+1跳过一个char*x型变量的指针。
*pa访问pa所指向的空间,由于该题中*pa访问的是“at”的地址
%s,打印字符串,在找到字符串首字符地址,计算机自动访问'\0'前的字符打印、
所以,答案为:"at"
8.
第八道题是本次题目讲解中,最难的这道题,如果朋友可以理解,那么这些题目你就搞清楚啦。
第一问 **++cpp
cpp=cp 这里cp是数组首元素地址,相当于&cp[0]
++cpp等同于cpp=cpp+1,是在本质上使得cpp发生数值改变。cpp+1跳过一个char*变量的地址,即&cp[1]
**cpp先进行第一次解引用操作,访问cpp即&cp[1]指向的空间的内容,得*(c+2)
再进行第二次解引用操作,访问c+2所指向的空间的内容,得到POINT的首字符地址
打印得"POINT"
第二问
cpp=cp 这里cp是数组首元素地址,相当于&cp[1]
++cpp等同于cpp=cpp+1,是在本质上使得cpp发生数值改变。cpp+1跳过一个char*变量的地址,即&cp[2]
*cpp先进行第一次解引用操作,访问cpp即&cp[1]指向的空间的内容,得c+1
--(c+1) 令m=c+1 得 m=m-1;m=(c+1)-1 =c。 这里m=cp[2],cp[2]的数值也发生了彻底的变化。cp[2]=c
*c进行第二次解引用,访问c指向的空间,得到ENTER的首字符地址。在这基础上再加3,意味着跳过3个字符的地址,即ENTER中第二个E的地址。
打印得ER
第三问
此时cpp=&cp[2]
cp[2]=c
cpp[-2]=*(cpp-2)-->*&cp[0]--->cp[0]-->c+3
*(c+3)访问c+3所指向的空间,即FIRST。在这基础上再加3,意味着跳过3个字符的地址,即FIRST中S的地址。
打印得ST
第四问
此时cpp=&cp[2]
cp[2]=c
cpp[-1][-1]-->*(cpp[-1]-1)-->*(*(cpp-1)-1)
*(cpp-1)=cp[1]=c+2
c+2-1=c+1
*(c+1)访问c+1指向的空间,得到"NEW"的首字符地址。在这基础上再加1,意味着跳过1个字符的地址,即NEW中E的地址。
打印得EW