在c中有一种数值型的转义字符,即’\ddd’的三位八进制转义字符和’\xdd’的两位十六进制转义字符。这两种转移字符其代表着一个字节大小的整数值字符

首先什么是转义字符,顾名思义转义字符最终是一种字符,只不过它是被转义了一下。所以它是一个字符的本质是不会变的。这也就是上面为什么说“这两种转移字符其代表着一个字节大小的整数值字符。”,因为字符是一个字节大小的。它是一个字符,但是由一个整数(三位八进制或两位十六进制)表示,正如ASCII码表中整数值48代表字符’0’一样。只不过’\000’代表整数0,其对应ASCII码表对应的字符为NULL。解释的有点拗口,但是大致的意思就是这样。

其八进制转义字符测试代码8zhuanyi.cpp如下:

01 #include

02 using namespace std;

03

04 #define b '\001'

05

06 int main()

07 {

08 cout<<"8 进制转移字符的sizeof大小:"<

09 int a = b;

10 cout<<"putchar(a): ";

11 putchar(a);

12 cout<

13

14 cout<<"putchar(b): ";

15 putchar(b);

16 cout<

17 printf("b的整数值为:%d\n", b);

18

19 system("pause");

20 return 0;

21 }

其输出打印结果如下:

结论分析:

可以看到,b是一个字符,所以cout<时输出的是一个笑脸,并且b的大小只有一个字节。根据b的内存大小就可以得知b肯定不是一个int整数,而是一个字符。并且b代表的整数值为1,对应为ASCII码表的值。

相同我们也可以看看’\xdd’的两位十六进制转义字符。

其十六进制转义字符测试代码16zhuanyi.cpp如下:

01 #include

02 using namespace std;

03

04 #define b '\x01'

05

06 int main()

07 {

08 cout<<"16 进制转移字符的sizeof大小:"<

09 int a = b;

10 cout<<"putchar(a): ";

11 putchar(a);

12 cout<

13

14 cout<<"putchar(b): ";

15 putchar(b);

16 cout<

17 printf("b的整数值为:%d\n", b);

18

19 system("pause");

20 return 0;

21 }

其输出打印结果如下:

通过上述两个演示代码,我再一次强调“这两种转移字符其代表着一个字节大小的整数值字符。”这一个原理。以下的分析测试可能与这个过程相互映衬。

问题1:超出范围(不能超过9位,即'\201',‘\’跟后数字不能超过4,否则出错,与编译器有关,要么截断,要么编译错误,VC6.0中报错!!有符号整数,-128~127且为补码存储!!)

一个字节八位,八进制转义字符中,而三位的八进制有9位(每一位八进制相当于3位二进制),所以说'\ddd'表示的范围已经超出了一个字节的表示范围!然而这会发生什么了,不妨做一个实验。

将8zhuanyi.cpp中第4行的代码#define b '\001'换成#define b '\401'

其输出如下:

通过对比输出可以看到,输出时没有任何变化的。为什么'\001'和'\401'的输出是一样的?我们将其转换为二进制来看一看。

'\001' 000 000 001

'\401' 100 000 001

而一个字符只有8位,转义字符'\001'和'\401'都有9位,于是我们情不自禁的就想到“截断”。如果真是截断,那么'\001'和'\401'所表示的字符的值就是一样的,舍弃了最高位的情况下,所以输出都是1,打印内容一样。

而十六进制转义字符两位十六进制刚好对应8位二进制,表示一个字符的范围,所以不会出现上述问题。

问题2:转义字符是否是有符号字符(有符号!!)

关于这个问题只需将最高位,即8位置1,观察打印出来的数是否为正数就可以得到答案。修改将8zhuanyi.cpp中第4行的代码#define b '\001'换成#define b '\201'

其输出如下:

可见八进制转移字符是有符号的字符!(包括十六进制转义字符也一样)

问题3:由于八进制中只有“0——7”,如果转义字符中出现“非合法数字”8和9会怎么办?同样的问题是,’\xdd’十六进制中只有“0——9和 A|a——F|f”,如果转义字符中出现了诸如‘G’之类的字符会是什么情况?

这个问题最好的办法就是做一个测试。修改将8zhuanyi.cpp中第4行的代码#define b '\001'换成#define b '\008'

其输出如下:

这个测试的结果就有点异常!首先转义字符的内存大小sizeof变为4而不是1,和int的大小一样。从某种意义上来说'\008'已不再是表示一个字符了,而是一个整数。

其次'\008'的整数值为56,很显然读的是字符’8’的ASCII码中的整数值56。而不是像“合法”情况下那样,直接读取的该整数值。所以这里面有一个更深层次也更隐晦的问题,就是'\008'中的8不再表示3位二进制,而是表示8位二进制。因为系统将8作为一个字符’8’来处理了。

为了验证这一点,再做一个测试。修改将8zhuanyi.cpp中第4行的代码#define b '\008'换成#define b '\018'

其输出如下:

对比前后两个输出,不经会发现一个问题。'\018'和'\018',putchar()都是8。但是其代表的整数值一个是312,而一个是56,这是为什么?

既然都是占4个字节,不妨转化为二进制来看一看。

'\018' 3120000 0000 0000 0000 0000 0001 0011 1000

'\008' 560000 0000 0000 0000 0000 0000 0011 1000

这样我们就不难发现,putchar()函数是输出一个八位二进制的字符,是一个字节。而'\018'和'\008'都是四个字节,所以在调用putchar()函数时,系统会将其截断,取低8位。所以调用putchar()函数输出的结果都是一样。

这就说明一个问题,当转义字符中出现“非法”的字符8或9时,系统将会视为ASCII码的八位二进制来处理,因为它会当一个字符来处理,而不是一个数字来处理。而不再是“合法”情况下三位二进制处理。所以这个’8’可以是任意一个字符,诸如’A’等等。

但是上面的输出还有一个问题,解释不了。那就是'\018'中为什么1“合法”当数字处理,整数值为1;而8“非法”当字符处理,整数值为56。我们可以这样猜测,系统一开始并不知道转义字符中包含“非法”字符,所以系统“从左往右”读取转移字符时,先是按照正常的,合法的流程处理。先处理0,合法,值为0;接着处理1,也合法,值为1;最后处理8,不合法,所以值为56。拼在一起就是上面的结果

'\018' 3120000 0000 0000 0000 0000 0001 0011 1000

按照这种逻辑下去,又有一个问题需要解释。假设有一种情况'\081',这个1是当“合法”数值处理,还是“不合法”当字符处理,测试一下。

修改将8zhuanyi.cpp中第4行的代码#define b '\018'换成#define b '\081'

其输出如下:

转换为二进制看一看:

'\081' 143850000 0000 0000 0000 0011 1000 0011 0001

56(‘8’) 49(‘1’)

这样可以得知,1是当做“不合法”当字符处理。所以可以得出一个结论,当转移字符中出现了非法字符时,转义字符变为一个4个字节的整数,从左至右,从第一个非法字符开始一直往右的所有字符都被当成“非法”字符处理。包括诸如1,2之类。这样也主要是因为,其性质已经变了,变成了4个字节大小了。

问题三得出的所有结论,同样适应于十六进制转义字符。因为没有异议,所以就不再做演示代码了。我测试的过程中,两者的结果都是一样的。

问题4:输入的转义字符不是规定的长度,比如’\00’会是什么情况。

对于八进制转义字符而言,不足会补0,超过的话就变为4字节。(char c='\11';printf("%d\n",c);会打印9)

对于十六进制转义字符而言,不足会补0,超过的话也不会变为4字节,它会取最后两位。始终大小为1,除了碰到“非法”字符之外。

char a='\xAG';//正确,将字符'G'赋值给a,去掉G保留A打印整数10,保留G去掉A编译出错!!!!
char a='\xGA';//范围超出,编译出错
printf("%d",a);//打印整数71
cout<<a<<endl;//打印字符G

转自:http://blog.chinaunix.net/uid-23552868-id-191223.html

C中八进制和十六进制转义字符揭秘相关推荐

  1. c语言中八进制和十六进制

    c语言中八进制和十六进制的全称是:八进制整数和十六进制整数.和int一样都属于整数,自然不是实数(浮点型) 因此以下代码错误 1. double a=0x12.4; 2. 也不能输入一个十六进制或八进 ...

  2. C语言转义字符\数字 八进制和十六进制学习

    C语言转义字符\数字 八进制和十六进制学习 c语言转义字符 \数字 ,这数字是八进制还是十进制的?还有这转移字符代表的是什么?_百度知道https://zhidao.baidu.com/questio ...

  3. 浅谈八进制转义字符和十六进制转义字符

    这首先要从字符常量说起...... 字符常量在计算机中存储占一个字节,8个位,256种组合方式,标准ASCII码表使用前7位,故一共有128个字符,扩展ASCII码用上了第八位,这里不予讨论.标准AS ...

  4. python中的二进制、八进制、十六进制的相互转换

    1 二进制.八进制.十六进制 转到 十进制 使用int(str, n)即可完成二进制.八进制.十六进制到十进制的转换: str:是要转换的进制具体数,类型字符串 n:是要转换的进制,类型整型 1.1 ...

  5. C++中输入输出的十六进制八进制

    1.数的进制 默认进制: 默认状态下,数据按十进制输入输出.如果要求按八进制或十六进制输入输出,在cin或cout中必须指明相应的数据形式,oct为八进制,hex为十六进制,dec为十进制. 1 in ...

  6. 二进制、八进制、十六进制和十进制的相互转换,原码反码补码计算以及Java中数字的存储

    1. Java中数字默认是十进制,二进制.八进制以及十六进制的表示如下 2. 二进制.八进制.十六进制和十进制的相互转换 2.1 为了不累赘描述,本文以百度的二进制小数转换为十进制小数为例,如下图 2 ...

  7. C语言中的二进制、八进制和十六进制的表示

    二进制数.八进制数和十六进制数的表示 一个数字默认就是十进制的,表示一个十进制数字不需要任何特殊的格式.但是,表示一个二进制.八进制或者十六进制数字就不一样了,为了和十进制数字区分开来,必须采用某种特 ...

  8. c语言中十进制与十六进制转换_小猿圈分享-java-十进制、八进制、十六进制数互相转换...

    给大家分享一个可以节约我们时间的小程序,十进制.八进制.十六进制的互相转换,记得收藏哦. public class JZTurn { public static void main(String[] ...

  9. 计算机系统中常用的进制,计算机中常用 二进制 八进制 十进制 十六进制的特点...

    计算机中常用的计数制 用若干数位(由数码表示)的组合去表示一个数,各个数位之间是什么关系,即逢"几"进位,这就是进 位计数制的问题.也就是数制问题.数制,即进位计数制,是人们利用数 ...

最新文章

  1. linux db2 修改日志路径,db2中更改日志文件大小及其个数
  2. Visual Studio Remote Debugger(for 2005/2008) .net远程调试转
  3. Science首发奥密克戎突刺蛋白分子水平分析,揭秘2大传染性增强原因,柳叶刀:全球大流行有望3月结束...
  4. 第十二课.sklearn决策树实验
  5. VNC下安装Oracle报错--Could not execute auto check for display colors
  6. docker网络配置方法总结
  7. java文件全是数字编码_批量将Java源代码文件的编码从GBK转为UTF-8
  8. Java输出箭头_java基于XSSF 导出带箭头的直线
  9. 检测提取图像中的直线(基于霍夫变换)
  10. svn使用过程中遇到的问题
  11. 漫画微信小程序源码 全开源 商业版
  12. 分期手续费率转换成年利率
  13. 【智能优化算法】基于混合布谷鸟算法和灰狼算法求解带单目标优化问题附matlab代码
  14. 【图书推荐】中国首部敏捷开发案例集《敏捷开发一千零一夜》
  15. 计算机上怎么计算x的n次方,计算x的n次方
  16. 全球及中国毛巾产品市场盈利前景与供需调查分析报告2022版
  17. 【JZOJ 4816】label
  18. golang操作chromedp模拟浏览器基础入门
  19. python画出的图_Python 画出来六维图
  20. 服务器数据盘不显示,云服务器不显示数据盘

热门文章

  1. 对比噪声比cnr_CINR、CNR、SNR、SINR和Eb/No的区别
  2. android美团底部栏实现,仿美团APP的底部滑动菜单实现
  3. 从高宏伟处借来的HOOK API代码
  4. chan-vese模型
  5. 【python】准点跑路人必备小程序~ 不信你用不到
  6. 【LeetCode】1518. 换酒问题(Java)
  7. [CF538F]A Heap of Heaps 持久化线段树
  8. 一个人总要走陌生的路,看陌生的风景,听陌生的歌
  9. rk3288做云服务器性能怎么样,十个问题秒懂RK3288处理器平板(上)
  10. 重温FPGA之4bit信息位 汉明编码器 verilog实现