C语言深度剖析自测题8解析

#include <stdio.h>

 

int  main(void) {
    int  a[5] = {1, 2, 3, 4, 5};

    int* ptr1 = (int*)(&a + 1);

    int* ptr2 = (int*)((int)a + 1);

    printf("%x, %x\n", ptr1[-1], *ptr2);

}

 

 这个题目主要是考了两个知识点一个是指针的知识,第二个是大端机和小端机的知识

首先需要明确x86是小端机,所以它的数值在各个字节中的顺序是从小到大的

比如对于int型的数值其在内存中的编码就是 1 0 0 0

在解释清楚这一点后,正式的解析下这道题目

int* ptr1 = (int*)(&a + 1);

&a 对数组名进行取地址,数组名所代表的是一个有5个int元素的数组,所以&a代表的就是一个代表有五个元素的数组的指针

所以这里的(&a + 1)实际上就是取得了a[4]也就是数字5后面的地址,这样又将其转换为一个int*指针,此时的ptr1就是一个指向

a[5]后地址的int型指针,ptr1[-1]其实就等价于*(ptr1-1)这样的运算,所以ptr1-1得到的就是a[4]的地址所以得出的第一个值就是a[4]的值

也就是5.

接下来再对第二个指针进行分析,(int)将一个指针值转换为了int值,(int)a+1就是a的地址值加上1,a是int*类型的所以a+1的话其值实际上

了4,而现在将a转换为int型的所以这样就相当于给其值加上1,这个的作用效果和(char*)a + 1是相同的.然后这里又将该值转换为一个int*类型

的指针,所以当使用*ptr2的时候就会取四个字节,并读取出其中的值.

因为是小端机所以1在4个字节中的分布是0x01 0x00 0x00 0x00, 2在4个字节中的分布是 0x02 0x00 0x00 0x00

此时ptr2指向的是a中的第二个字节所在的地址,所以当取4个字节时实际取到的是 0x00 0x00 0x00 0x02这样当将其解释出真是的值实际是

0x02 0x00 0x00 0x00 这里的输出使用的是%x所以输出的是十六进制的数字,所以输出了2000000.

C语言深度剖析自测题8解析,布布扣,bubuko.com

C语言深度剖析自测题8解析

上一篇:POSIX 线程编程(一)简介


下一篇:python的文件读写