927|13

3081

帖子

0

TA的资源

纯净的硅(高级)

第二道中兴面试题 [复制链接]

 

4.已知字符A的ASCII代码值为65,以下程序运行时若从键盘输入:B33<回车>.则
输出结果是_____

#include<stdio.h>
main()
{
   char a,b;
   a=getchar();scanf("%d",&b);
   a=a-'A'+'0';b=b*2;
   printf("%c %c\n",a,b);
   
}

运行结果

15.png
这个结果怎么得来的?谢谢

 

此帖出自stm32/stm8论坛

最新回复

昨天下午一直在研究这个问题现象,今天早早的又来开始破案了,百度了一下在Dev-C++中调用scanf函数为什么会把其他局部变量改掉的问题,没有查找到特别相近的答案,理论上来说scanf函数已经运行这么多年,应该是不会出这种BUG的,当看到有人对scanf函数的取值分析我才注意到取值类型和数据对齐的问题,以下是的我试验分析过程,大家看看对不对: 1、把局部变量a b的存储地址打印出来,可见由于电脑是64位的,所以变量的内存栈地址也是64位的,其中局部变量a地址为0x62FE1F,字节对齐,局部变量b地址为0x62FE1E,为半字对齐,位置上与a相邻。 此时输入B33,打印结果如图,输出的结果确实为"? B",对于为什么显示"?",这里我也做了实验,对于Dev-C++来说以char类型打印0xEF 0xED等可能由于没有支持相应的扩展字符,所以统一显示为"?",而不是代表变量a的值是字符"?"的数值0x3F(63)。所以我的疑问1:中兴的出题人也有想考查这一点?还要做题的人要非常了解各个开发环境能显示的字符范围?而且题目里面也没有指定是在哪个环境运行,那又有多少人知道当打印输出"?"号时,真实的16进制数据是多少? [attach]840697[/attach]     2、关于执行scanf函数之后,局部变量被修改为0的问题,这是比较神奇的问题,经过分析之后我认为在不同的平台上运行这段代码,得到的结果可能会不一样,我的分析如下: 1)从上面打印的变量地址可以看到,由于a b都是char型变量,所以在内存栈中分配的大小就是1字节,这个是正确的 2)执行getchar()函数后,确定此时变量a=’B'=66,说明取输入值无问题 3)执行scanf()函数后,此时变量a的值竟然变成了0,这是关键的点,最终影响到了后面的结果值。为什么会这样呢?我们可以看到scanf函数的参数是取一个Int型数据,传入的存储地址是变量b的地址,根据取值类型的原则,scanf函数会把从键盘输入的数值33保存到指定的地址,由于数值33是int类型,所以对应的10进制数据是0x00000021,但是变量b的地址是0x62FE1E,所以软件会从此地址开始写入int数据,即内存栈中从低地址到高地址的数据为:21 00 00 00,可见局部变量a对应地址0x62FE1F的数据变成了00,所以才出后面打印原始值时a=0的现象。另外说一点,如果这段代码放在arm单片机中,由于写入int型数据的地址不是字对齐,那就会出现字节不对齐造成的硬件错误,当然在编译器编译时可能已经会解决此问题,但是像第3)点说的,不对齐也能直接写入不报错的也可能是跟系统和编译器有关系吧。 4)为了验证3)中的推测,我现在输入B16706,其中int型数值16709=0x00004145,即低2字节对应的字符为'A'和'E',可见在执行完scanf函数后变量a变成了'A',变量b变成了'E',与存储地址上是相一致的,说明3)中的猜测是正确的,变量a的值会因为scanf的输入的类型参数而被影响。 [attach]840699[/attach]    继续验证,将变量b定义成int型,同样输入"B33",可见结果就变成了我第一次手算的结果1 B,因为把变量b定义成int型后,它是会进行双字对齐(因为是64位系统)的,可见变量b地址为0x62FE18,这样执行scanf函数之后,变量b有独立的存储空间,就不会把变量a的值给覆盖掉了,所以运行结果就会正常。 [attach]840701[/attach]   综上,我花了将近一天进行验证测试,得到这些结论,也算是有收获,至少弄清楚了问题现象出现的原理,以后在编程开发的时候需要注意这些不起眼的陷阱。   另外,我也想探讨一下中兴的面试官出此题的目的是想考查哪几个点的内容呢,我也想知道自己的这些分析是不是出题人心中的答案,如果有知晓和坛友不妨分享一二。 考点1:getchar函数的使用? 考点2:scanf函数的使用? 考点3:char类型变量在不同开发环境下的显示内容? 考点4:scanf函数执行后修改变量a值的原因? 考点5:+、-双目运算符的优先级?   详情 回复 发表于 2024-9-7 10:28
个人签名为江山踏坏了乌骓马,为社稷拉断了宝雕弓。

回复
举报

1

帖子

0

TA的资源

一粒金砂(初级)

这个可以,好!

此帖出自stm32/stm8论坛

回复

385

帖子

7

TA的资源

纯净的硅(初级)

#在这里快速回复#getchar赋值字符变量a=66;scanf赋值字符变量b=33,打印出的值不是"1 B"吗?
此帖出自stm32/stm8论坛

点评

知道了。 用DEVC++显示?B 用VC++显示1 B  详情 回复 发表于 2024-9-5 11:11
a输入B,然后-'A'+'0'  详情 回复 发表于 2024-9-5 09:45
b=66  详情 回复 发表于 2024-9-5 09:43
是?B  详情 回复 发表于 2024-9-5 09:42

回复

3081

帖子

0

TA的资源

纯净的硅(高级)

lansebuluo 发表于 2024-9-5 08:33 #在这里快速回复#getchar赋值字符变量a=66;scanf赋值字符变量b=33,打印出的值不是"1 B"吗?

是?B

此帖出自stm32/stm8论坛
个人签名为江山踏坏了乌骓马,为社稷拉断了宝雕弓。

回复

3081

帖子

0

TA的资源

纯净的硅(高级)

lansebuluo 发表于 2024-9-5 08:33 #在这里快速回复#getchar赋值字符变量a=66;scanf赋值字符变量b=33,打印出的值不是"1 B"吗?

b=66

此帖出自stm32/stm8论坛

点评

b本来是33,乘以2变成66  详情 回复 发表于 2024-9-5 09:44
个人签名为江山踏坏了乌骓马,为社稷拉断了宝雕弓。

回复

3081

帖子

0

TA的资源

纯净的硅(高级)

b本来是33,乘以2变成66

此帖出自stm32/stm8论坛
个人签名为江山踏坏了乌骓马,为社稷拉断了宝雕弓。

回复

3081

帖子

0

TA的资源

纯净的硅(高级)

lansebuluo 发表于 2024-9-5 08:33 #在这里快速回复#getchar赋值字符变量a=66;scanf赋值字符变量b=33,打印出的值不是"1 B"吗?

a输入B,然后-'A'+'0'

此帖出自stm32/stm8论坛
个人签名为江山踏坏了乌骓马,为社稷拉断了宝雕弓。

回复

3081

帖子

0

TA的资源

纯净的硅(高级)

lansebuluo 发表于 2024-9-5 08:33 #在这里快速回复#getchar赋值字符变量a=66;scanf赋值字符变量b=33,打印出的值不是"1 B"吗?

知道了。

用DEVC++显示?B

用VC++显示1 B

此帖出自stm32/stm8论坛

点评

DEVC++是什么软件,没有听说过啊,很常用吗  详情 回复 发表于 2024-9-6 08:20
个人签名为江山踏坏了乌骓马,为社稷拉断了宝雕弓。

回复

2

帖子

0

TA的资源

一粒金砂(初级)

此帖出自stm32/stm8论坛

回复

385

帖子

7

TA的资源

纯净的硅(初级)

chenbingjy 发表于 2024-9-5 11:11 知道了。 用DEVC++显示?B 用VC++显示1 B

DEVC++是什么软件,没有听说过啊,很常用吗

此帖出自stm32/stm8论坛

点评

百度  详情 回复 发表于 2024-9-6 08:22

回复

3081

帖子

0

TA的资源

纯净的硅(高级)

lansebuluo 发表于 2024-9-6 08:20 DEVC++是什么软件,没有听说过啊,很常用吗

百度

此帖出自stm32/stm8论坛
个人签名为江山踏坏了乌骓马,为社稷拉断了宝雕弓。

回复

4588

帖子

19

TA的资源

版主

你输入B33 估计会错

应该是输入 B 33 回车

结果应该是1B

B是55 A是65 减去等于1 假设0的ASCII码是48 等于49 对应‘1’

33数字%d嘛,乘以2是66

66的%c字符就是大写的字母‘B’

结果是

1 B

 

 

此帖出自stm32/stm8论坛

回复

1971

帖子

1

TA的资源

五彩晶圆(初级)

这个有点意思,其中考查了几个点,我第一次手算是1 B,但是看后面给的答案是? B,我想不通,然后使用Dev-c++进行编程验证,还发现新的问题,大佬们来看看该如何解释?

image.png  

此帖出自stm32/stm8论坛

回复

1971

帖子

1

TA的资源

五彩晶圆(初级)

昨天下午一直在研究这个问题现象,今天早早的又来开始破案了,百度了一下在Dev-C++中调用scanf函数为什么会把其他局部变量改掉的问题,没有查找到特别相近的答案,理论上来说scanf函数已经运行这么多年,应该是不会出这种BUG的,当看到有人对scanf函数的取值分析我才注意到取值类型和数据对齐的问题,以下是的我试验分析过程,大家看看对不对:

1、把局部变量a b的存储地址打印出来,可见由于电脑是64位的,所以变量的内存栈地址也是64位的,其中局部变量a地址为0x62FE1F,字节对齐,局部变量b地址为0x62FE1E,为半字对齐,位置上与a相邻。

此时输入B33,打印结果如图,输出的结果确实为"? B",对于为什么显示"?",这里我也做了实验,对于Dev-C++来说以char类型打印0xEF 0xED等可能由于没有支持相应的扩展字符,所以统一显示为"?",而不是代表变量a的值是字符"?"的数值0x3F(63)。所以我的疑问1:中兴的出题人也有想考查这一点?还要做题的人要非常了解各个开发环境能显示的字符范围?而且题目里面也没有指定是在哪个环境运行,那又有多少人知道当打印输出"?"号时,真实的16进制数据是多少?

image.png    

2、关于执行scanf函数之后,局部变量被修改为0的问题,这是比较神奇的问题,经过分析之后我认为在不同的平台上运行这段代码,得到的结果可能会不一样,我的分析如下:

1)从上面打印的变量地址可以看到,由于a b都是char型变量,所以在内存栈中分配的大小就是1字节,这个是正确的

2)执行getchar()函数后,确定此时变量a=’B'=66,说明取输入值无问题

3)执行scanf()函数后,此时变量a的值竟然变成了0,这是关键的点,最终影响到了后面的结果值。为什么会这样呢?我们可以看到scanf函数的参数是取一个Int型数据,传入的存储地址是变量b的地址,根据取值类型的原则,scanf函数会把从键盘输入的数值33保存到指定的地址,由于数值33是int类型,所以对应的10进制数据是0x00000021,但是变量b的地址是0x62FE1E,所以软件会从此地址开始写入int数据,即内存栈中从低地址到高地址的数据为:21 00 00 00,可见局部变量a对应地址0x62FE1F的数据变成了00,所以才出后面打印原始值时a=0的现象。另外说一点,如果这段代码放在arm单片机中,由于写入int型数据的地址不是字对齐,那就会出现字节不对齐造成的硬件错误,当然在编译器编译时可能已经会解决此问题,但是像第3)点说的,不对齐也能直接写入不报错的也可能是跟系统和编译器有关系吧。

4)为了验证3)中的推测,我现在输入B16706,其中int型数值16709=0x00004145,即低2字节对应的字符为'A'和'E',可见在执行完scanf函数后变量a变成了'A',变量b变成了'E',与存储地址上是相一致的,说明3)中的猜测是正确的,变量a的值会因为scanf的输入的类型参数而被影响。

image.png    继续验证,将变量b定义成int型,同样输入"B33",可见结果就变成了我第一次手算的结果1 B,因为把变量b定义成int型后,它是会进行双字对齐(因为是64位系统)的,可见变量b地址为0x62FE18,这样执行scanf函数之后,变量b有独立的存储空间,就不会把变量a的值给覆盖掉了,所以运行结果就会正常。

image.png  

综上,我花了将近一天进行验证测试,得到这些结论,也算是有收获,至少弄清楚了问题现象出现的原理,以后在编程开发的时候需要注意这些不起眼的陷阱。

 

另外,我也想探讨一下中兴的面试官出此题的目的是想考查哪几个点的内容呢,我也想知道自己的这些分析是不是出题人心中的答案,如果有知晓和坛友不妨分享一二。

考点1:getchar函数的使用?

考点2:scanf函数的使用?

考点3:char类型变量在不同开发环境下的显示内容?

考点4:scanf函数执行后修改变量a值的原因?

考点5:+、-双目运算符的优先级?

此帖出自stm32/stm8论坛

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

猜你喜欢
随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表