问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

C语言问题求解?

发布网友 发布时间:2022-05-27 09:36

我来回答

2个回答

热心网友 时间:2023-10-14 18:09

这个问题涉及到内存分布,在这里我假设你的电脑采用小端格式存储数据(小端格式存储不了解的话先百度下)。

1、首先可以列出第一个语句 struct data d = {"", -3, 769} 赋值后的内存分布,分布如下:

00 00 00 00 00 00 00 00 fd ff ff ff 01 03 00 00

从内存分布可知前8个0就是d.str,0xfffffffd代表d.arr[0] =-3,0x00000301代表d.arr[1]=769

注:默认从左往右的地址为从低到高,符合小端格式的设定

2、执行scanf("%s", d.str);//这里输入1234abcdef 语句后的内存分布如下:

31 32 33 34 61 62 63 64 65 66 00 ff 01 03 00 00

由于"1234abcdef"的长度10超过了a.str的大小8,那么后面的2字节就会被覆盖,从内存上看,从左往右的10个字节分别对应于"1234abcdef"的ascii码;那么为什么0x66('f')后面的字节为0了呢?那是因为字符串以'\0'结尾,所以这个字节也被覆盖了。

3、执行*((char*)(&d.str) + 13) = '\0';语句后内存分布如下:

31 32 33 34 61 62 63 64 65 66 00 ff 01 00 00 00

这个语句的含义是将从d.str地址开始后的第13个字节置为'\0’,也就是0x03->0x00;注意第13个字节的下标应该从0开始算。

4、执行*(d.arr) += *(d.arr + 1) + 3;语句

*(d.arr + 1)其实就是等于d.arr[1]的值,也就是0x00000001,也就是1,那么*(d.arr + 1) + 3就等于4;*(d.arr)其实就是a.drr[0]=0xff006665,加上4就等于0xff006669;那么经过计算后的内存分布就变为:

31 32 33 34 61 62 63 64 69 66 00 ff 01 00 00 00

5、printf("%d\n", d.arr[0]);输出什么?

从上面内存分布可以看到,d.arr[0]其实就是0xff006669,其二进制可以表示为:

1111 1111 0000 0000 0110 0110 0110 1001(高位在前表示)

最高位为1,代表为负数;由于计算机存储负数是用补补码存储的,所以这里需要将补码转换成原码,也就是是补码+1再除符号位每位取反就可以了。

补码加1:1111 1111 0000 0000 0110 0110 0110 1010

除符号位取反(原码):1000 0000 1111 1111 1001 1001 1001 0101

由于最高位为1表示负数:所以上面表示 -(0000 0000 1111 1111 1001 1001 1001 0101)=-16750999

所以:这句话输出 -16750999

6、执行*d.arr = 825373492;后的内存分布

将825373492用16进制可以表示为:0x31323334(高位在前);这语句其实是对d.addr[0]进行赋值,所以就会覆盖原来的0xff006669,覆盖后的内存分布为:

31 32 33 34 61 62 63 64 34 33 32 31 01 00 00 00

7、执行d.arr[1] += 0xff;后的内存分布

执行完上面所有步骤后d.arr[1] = 0x00000001; 那么执行完d.arr[1] = d.arr[1] + 0xff后就等于256,256的16进制表示为0x00000100;所以内存分布如下:

31 32 33 34 61 62 63 64 34 33 32 31 00 01 00 00

8、printf("%s\n", d.str);输出

从语句d.str的含义可知是打印从d.str地址开始的内容,直到遇到'\0'为止(与我们理解的打印d.str有一点偏差),也就是打印31 32 33 34 61 62 63 64 34 33 32 31 00;查询ascii码可知这就是字符串"1234abcd4321";所以最后打印1234abcd4321。

综上可知:程序最后输出:

-16750999

1234abcd4321

热心网友 时间:2023-10-14 18:09

简单的说:由于你的代码是非标准方法访问变量,导致结果非常不确定,没有固定答案,不同编译器结果不一样

你这样是故意内存访问越界来计算么?为什么要研究这个呢?因为这样做非常明显的违背软件工程的
问题是这个答案是没有标准答案的,因为编译器会对结构内的内存布局稍微做调整,不同编译器和不同编译条件导致的布局都不一样,没法给你确保arr值得准确性
所以我建议是至少不要现在研究这个,等你学的深入了对内存布局及编译器优化有深刻了解在研究这个。对于初学者而言,养成良好的编程习惯很重要,这种东西还是不对的
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
奥迪Q5L发动机漏机油,发动机漏机油,发动机漏机油!!! 株两优4024基本信息 企业品种是指什么 计划品种构成是什么意思? 什么是产品品种构成 大话二什么类型的什么变身卡加敏最高是多少(神兽卡)??我问的是参战以后... 大话2中什么变身卡加强雷法?除了黄金卡以外? 遇到一个很奇怪的女孩子,求大家帮我分析分析 一个月没见女朋友,问了什么也不说,只说快疯了,什么意思 慢热女朋友对我说我也是很烦恼问她什么也不说电话也不接信息也不回女 ... 亲们啊 女生用苹果6splus还是6s?。之前用过plus觉得单手操作不方便*也不方便。有些后悔 a = str[i] - '0'什么意思啊 x>>=1;在C++里面是什么意思 iphone6s变慢了,换电池会有效吗 到底买6s还是6s plus,求大神给点意见,有财富值。 捡了个苹果6s吧友们我怎么换给他 6s Home键问题 问: 苹果6s比6好很多吗。差1300。买哪个呢。 iPhone6s贴吧,网易新闻,掉帧严重 iphone6s升级到9.35好用吗? php $str=0x31,这样定义一个16进制数据后,为什么strlen($str)返回2,为什么不能像C语言里面占一个byte 怎样在同一部手机上用两个微信!怎么才能下载另一个! 三点水加一个“眞”字念什么? c语言 想定义一个字符数组str,将str1、str2两个字符串连接存至str中并输出。这样打为什么运行不了的?? char str[30]; int i; /* gets(str);// str[30]='\0'; puts(str); */ for(i=0;i<30;i++) c语言,如何声明一字符串数组并赋值1~30?(用循环) 如何将若干字符串赋值给二位数组? "珍"字的王字旁换成三点水念什么?大神们帮帮忙 MFC 编辑通过,但是运行的时候出错debug assertion failed 求int十进制转换二进制的函数解释,此处的str[0]应该是符号位吧?str[32]才是“\0”? javascript中确认密码的代码中str.value和RegExp("^\\w{8,31}$")都是什么意思 买6S还是Se主要上网打电话,听歌。不玩游戏不看电影。 假如字符串是"123" ,然后就转换成"31 32 33" 这样,再保存到一个数组中 ,用c编写怎么做 ,求帮助 《许仲平义不苟取》结合本文说说许衡的做法对你有什么启示 许仲平义不苟取文言文断句 怎么帮宝宝走出厌奶期 文言文 许仲平义不苟取标题中的义是什么意思 什么方法可让头发成长的速度加快??? 如何让头发生长的速度更快? 有法院的调解协议,如何申请强制执行 怎样在同一部手机上用两个微信!怎么才能下载另一个! 怎么可以用两个 感冒了能吃绿豆吗 感冒了可以喝绿豆汤吗?急需求解答? 绿豆,,红豆用红糖煲粥,感冒可以喝吗? shockshadow账号 可以共享吗 魔兽世界搬沙是怎么回事? 魔兽世界中的搬沙是什么意思? WOW中的搬沙是啥东西具体解释下怎么弄的 WOW中什么叫搬沙 ?