在该大题中,首先我们看到&a+1,在这里指的是跨越数组a的整体地址指向最后一个元素后面的一个地址,而ptr[-1]可以看作是*(ptr1-1),即将ptr1的地址减去1个整数指针类型的地址,即前移四个字节,最后指向数组a的最后一个元素的地址。
其次我们看到(int)a+1,指的是将地址a转换成整型后+1,这里我给大家解释一下,由于visual studio默认是小端储存的原因,所以地址a的储存为 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00,即小对小,大对大,四个字节组合成一个整体,将地址a转换成整型+1实质上就是加了一个字节,也就是右移了一个字节,即本来是指向01前面,在移动后指向01后面,最后又将int类型转换为int*类型赋值给了ptr2,所以ptr2在解引用的时候要读取小端存储中指向位置后面的四个字节,即00 00 00 02,读取出来后又恢复为原来的大端存储方式,即02 00 00 00,因为2前面的0没有意义,所以去掉2前面的0,然后再后面补上一个0,即20 00 00 00,打印出来就是答案。
这里我们补充一下
大端存储是将低位字节序存放在高地址中,高位字节序存放在低地址中
小端存储是将高位字节序存放在高地址中,低位字节序存放在低地址中
地址字节从左到右字节序依次减小
该大题第一眼看上去很简单,但是大家往往会忽略一个很重要的点,就是在括号中如果有逗号,那么 要注意逗号算数符,即多个逗号组成的一组会依次运算直到最后一个逗号,然后将最后一个逗号中的值赋给指定变量。
该题中的数组a实质上存放的是 13 50 00,而p=a[0],即数组a在第一行的首元素地址赋给了p,而
p[0]=*(p+0),读取的是 1,即答案为1
该题首先补充一点,两个地址相减得到的为两个地址相距几个字节的距离,首先我们看到int(*p)[4],该处表明p的类型是数组指针,且数组中最多存放四个元素,因为a指向的数组是五个元素,每次a加1都是越过五个元素进行访问,所以&a[4][2]指向的是第五行的一维数组的第二个元素,
而因为p指向的数组是四个元素,所以每次p+1都是越过4个元素进行访问,而p+4就是越过十六个元素,(p+4)+2就是越过十八个元素进行访问,所以&p[4][2]指向的是&a[3][2].
分析完后我们看%p和%d的区别,%d就是&p[4][2]和&a[4][2]之间相差的的字节即 -4,而%p因为是读取地址所以没有正负之分,这导致了没有将&p[4][2]-&a[4][2]的数值转换成原码读取,而是直接将补码进行读取,即%d读取的是10000000000000000000000000000100,而%p读取的是111111111111111100,又因为%p读取的是地址,所以我们要将1111111111111111111111111111111100转换为十六进制即FFFFFFFC。
所以答案为 FFFFFFFC ,-4
这一题相对来说比较简单,首先我们看到&aa+1,指的是跨越整个aa地址指向最后一个元素后面的一个元素地址然后转换为整形指针类型赋值给ptr1,而*(aa+1)指的是指向数组aa第二行的首元素地址,然后转换为整形指针类型赋值给ptr2,实际上*(aa+1)不用转换类型,因为它本身就是地址,也就是整形指针类型。
然后我们看*(ptr1-1),指的是ptr1向左移动一个整型后解引用,即指向元素10
而*(ptr2-1)同理是向左移动一个整型后解引用,即指向元素5
所以答案为 10 , 5