鱼C论坛

 找回密码
 立即注册
查看: 1917|回复: 0

[技术交流] 关于《带你学c带你飞》第39节留的课后题

[复制链接]
发表于 2017-7-27 16:22:41 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 人之初 于 2017-7-27 16:46 编辑


废话不多说,先上原代码!
[code]#include <stdio.h>

int main()
{
        char a=0,b=0;                                // 声明两个字符型变量并初始化为0
        int *ptr=(int *)&b;                        //将b的地址给ptr,这里用int *强制转换
        *ptr=258;                                //将258赋值给*ptr,也就是字符变量b
        printf("a=%d,b=%d\n",a,b);        //输出a和b的值。

        return 0;
}
输出的结果值是:a=1,b=2.

可能很多朋友会认为输出的结果令人匪夷所思,那么接下来我帮大家分析一下吧,正好检验我学的怎么样!
1.首先,a和b是两个初始化过的字符型局部变量,在内存中他们两个的地址是相连的而且a的地址比b的地址大,所以有&a-&b=1字节(个人觉得相连是因为系统知道他的空间大小,而且在一起声明的,所以系统直接进行分配,节约环保。至于a为什么比b的地址值大,这是因为局部变量是存放在栈中的,栈的发展方向是由高到低的,在39课视频中甲鱼哥给的那张《c语言的内存分布规律》图中查到,在介绍栈的时候也说过局部变量存放在栈中)。
2.ptr是指向整型的指针变量,其指向的数据类型占sizeof(int)的字节空间,我的机器上是4个字节,而b只占1个字节,当int *ptr=(int*)&b的时候,实际上是告诉我们ptr指向的是从&b开始的一个整型数据空间。
3.258的二进制形式是00000000 00000000 00000001 00000010  二进制8位代表一字节,内存中数据的存放是由低位到高位的(以前的课程中也讲到过)所以,ptr中存放的地址实际上是00000010的地址,而prt=&b;所以效果等同于将258存放到由&b开始的4个字节大小的空间中去,这样一来,数据便覆盖了&b+1,&b+2,&b+3这三个字节空间的数据,而&a-&b=1字节,所以变量a的内容被覆盖变成00000001,十进制就是1,而此时的b是00000010,也就是十进制的2.所以才会出现最终的输出结果a=1,b=2。
简单来讲就是数据溢出覆盖了变量a造成的。
这个例题考察我们对以下几点的掌握:
1.变量在内存中分布规律
2.数据在内存中的存储(由低到高)
3.数据溢出


文中如果出现什么不足或者错误,希望大家积极帮我指出,共同学习!!!


一切超越都源自于模仿

评分

参与人数 1荣誉 +1 鱼币 +1 贡献 +1 收起 理由
Daniel_Zhang + 1 + 1 + 1 无条件支持楼主!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-14 18:42

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表