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.

转载于:https://www.cnblogs.com/coder-zhang/p/3733910.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值