C/C++字符常量解析规则

一、问题描述:

错误的使用ASCII码给char赋值时,会出现只截取最后一位的特殊情况。例如:
char a='1';//正确
char b='12';//正确
char c='123';//正确
char d='1234';//正确
char e='12345';//长度过长,报错

输出的结果分别是:

cout<<a;//输出1
cout<<b;//输出2
cout<<c;//输出3
cout<<d;//输出4
printf("%\n,a);//输出49(即’1‘的ASCAII码)
printf("%\n,b);//输出50(即’2‘的ASCAII码)
printf("%\n,c);//输出51(即’3‘的ASCAII码)
printf("%\n,d);//输出52(即’4‘的ASCAII码)

注意:将数字换成其他字符也是可行的,这里使用数字是为了方便发现问题。

这里可以得到第一个结论:即输出字符常量时,cout输出的该字符常量,printf输出的是该字符常量对应的ASCAII码。

通过进一步的分析发现,直接使用cout或printf输出长度较长的字符常量会产生出乎意料的结果。

cout<<'1';//输出1
cout<<'12';//输出12594
cout<<'123';//输出32224115
cout<<'1234';//输出825373492
printf("%\n",'1');//输出49
printf("%\n",'12');//输出12594
printf("%\n",'123')//输出3224115
printf("%\n",'1234')//输出825373492

通过比较cout和printf和多次执行发现结果均保持不变,并且随着字符常量的长度不同,输出的结果也不同。因此可以排除是乱码所致,并可以基本上确定这是由于某种固定的解析规则所产生的固定的结果。

以下是在VS2019中的执行结果:
在这里插入图片描述

二、原因分析

为什么输入字符常量的长度可以有多位?为什么长度超过4位才报错?

合理的解释为:

当解析字符常量时,首先要将其转换为int类型。而一个int对应着4个字节,所以首先将字符常量对应的ASCII码分别存储到int的四个字节中,再根据int的值产生最终的结果。

例如:

'1’解析为int的结果为(’1’的ASCII码值为49):图1
因此最终printf的结果为49;而cout则输出ASCII码对应的字符,即‘1‘;

'12’解析为int的结果为:
在这里插入图片描述
因此最终printf的结果为49×28+50;而49×28+50不对应任何字符,因此cout的结果也是49×28+50;

‘123’解析为int的结果为:
在这里插入图片描述
因此最终printf和cout的结果为49×216+50×28+51

'1234’的解析为int的结果为:
在这里插入图片描述
因此最终printf和cout的结果为:49×24+50×216+51×28+52;

而当长度大于4时就超出了int所对应的4个字节,因此会报错。

三、得出结论

  1. 输出字符常量时,cout输出的该字符常量,printf输出的是该字符常量对应的ASCAII码
  2. 编译器在解析字符常量时,首先将其转换为int,而int一般对应4个字节,所以字符常量的长度最长为4个字节(具体的长度由int对应的字节数决定)
  3. 使用char x='1234’这种方式赋值时,由于char只对应一个字节,因此只取解析为int后的最低的一个字节。因此看起来就好像是只截取了最后的一个字符。
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路漫漫其修远兮?

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值