关于c语言三位八进制数越界的探讨
2017-01-04 21:47
274 查看
1:\ddd;我们知道,\ddd是对用三位八进制数转义表示任意字符的形象化描述,但对d的取值限定在0-7之间,那么我们不禁要问,如果超过了这个范围会输出些什么,随机数?开始我也是这么觉得的,后来用vc6.0调试知两次输出同一个越界转义字符得到的是同一个字符,所以觉得有必要深究一下:
(1) \ddd代表着一个字节大小的整数值字符,一个字节八位(即'\201',‘\’跟后数字不能超过4,否则出错,与编译器有关,要么截断,要么编译错误,VC6.0中报错),八进制转义字符中,而三位的八进制有9位(每一位八进制相当于3位二进制),所以说'\ddd'表示的范围已经超出了一个字节的表示范围,然而这会发生什么
\001' 000 000 00'\401' 100 000 001
而一个字符只有8位,转义字符'\001'和'\401'都有9位,于是我们情不自禁的就想到“[b]截断”。如果真是截断,那么'\001'和'\401'所表示的字符的值就是一样的,舍弃了最高位的情况下,所以输出都是1,打印内容一样。而十六进制转义字符两位十六进制刚好对应8位二进制,表示一个字符的范围,所以不会出现上述问题。[/b]
(2)转义字符是有符号的字符,关于这个问题只需将最高位,即8位置1,观察打印出来的数是否为正数就可以得到答案,
printf("%d\t",'\201');输出-127,可证.
2 越界探讨
从某种意义上来说'\008'已不再是表示一个字符了,而是一个整数。其次'\008'的整数值为56,很显然读的是字符’8’的ASCII码中的整数值56。而不是像“合法”情况下那样,直接读取的该整数值。所以这里面有一个更深层次也更隐晦的问题,就是'\008'中的8不再表示3位二进制,而是表示8位二进制。因为系统将8作为一个字符’8’来处理了。那8之前的两个0怎么办呢,由于系统读取到0尚未识别到该转义字符非法,所以0依旧是按八进制“000”存储,只不过在给8分配一个整字节后再给第一个0的“000”左补符号位(这里是0),给第二个0统一右补0;那么我们不禁又要问,如果‘\080’会如何,答案是,第一个0同上,第二个0(ASCII码值48)换成8位二进制“0011
0000”,这里可能出现了数字不是以整字节存储的,但实际就是这样
实验: printf("%d\t",'\108');会输出什么呢?
1 0001
0 0000
8(ASCII值56) 0011 1000
所以最终‘\108’在内存中存储形式为 0001 0000 0011 1000 十进制为 2104
printf(“%d\t”,’\080’); 0 0000
8(ASCII值56) 0011 1000
0(ASCII值48) 0011 0000
所以最终’\080’存储形式为 0000 0011 1000 0011 0000 十进制为14384
作者 中南大学通信1602肖涛
(1) \ddd代表着一个字节大小的整数值字符,一个字节八位(即'\201',‘\’跟后数字不能超过4,否则出错,与编译器有关,要么截断,要么编译错误,VC6.0中报错),八进制转义字符中,而三位的八进制有9位(每一位八进制相当于3位二进制),所以说'\ddd'表示的范围已经超出了一个字节的表示范围,然而这会发生什么
\001' 000 000 00'\401' 100 000 001
而一个字符只有8位,转义字符'\001'和'\401'都有9位,于是我们情不自禁的就想到“[b]截断”。如果真是截断,那么'\001'和'\401'所表示的字符的值就是一样的,舍弃了最高位的情况下,所以输出都是1,打印内容一样。而十六进制转义字符两位十六进制刚好对应8位二进制,表示一个字符的范围,所以不会出现上述问题。[/b]
(2)转义字符是有符号的字符,关于这个问题只需将最高位,即8位置1,观察打印出来的数是否为正数就可以得到答案,
printf("%d\t",'\201');输出-127,可证.
2 越界探讨
从某种意义上来说'\008'已不再是表示一个字符了,而是一个整数。其次'\008'的整数值为56,很显然读的是字符’8’的ASCII码中的整数值56。而不是像“合法”情况下那样,直接读取的该整数值。所以这里面有一个更深层次也更隐晦的问题,就是'\008'中的8不再表示3位二进制,而是表示8位二进制。因为系统将8作为一个字符’8’来处理了。那8之前的两个0怎么办呢,由于系统读取到0尚未识别到该转义字符非法,所以0依旧是按八进制“000”存储,只不过在给8分配一个整字节后再给第一个0的“000”左补符号位(这里是0),给第二个0统一右补0;那么我们不禁又要问,如果‘\080’会如何,答案是,第一个0同上,第二个0(ASCII码值48)换成8位二进制“0011
0000”,这里可能出现了数字不是以整字节存储的,但实际就是这样
实验: printf("%d\t",'\108');会输出什么呢?
1 0001
0 0000
8(ASCII值56) 0011 1000
所以最终‘\108’在内存中存储形式为 0001 0000 0011 1000 十进制为 2104
printf(“%d\t”,’\080’); 0 0000
8(ASCII值56) 0011 1000
0(ASCII值48) 0011 0000
所以最终’\080’存储形式为 0000 0011 1000 0011 0000 十进制为14384
作者 中南大学通信1602肖涛
相关文章推荐
- 关于C语言中函数调用和参数传递机制的探讨
- 关于C语言判断文件尾问题的探讨
- 关于C语言中函数调用和参数传递机制的探讨
- C语言关于回调函数和this指针探讨
- 关于C语言中交换两个数的代码探讨
- 关于C语言中函数调用和参数传递机制的探讨(ZZ)
- 关于C语言的文件型指针和移位操作中的一些有趣问题的探讨
- C语言关于回调函数和this指针探讨
- 关于C语言中函数调用和参数传递机制的探讨
- 关于C语言指针和数组的深入探讨
- 关于C语言结构体对齐问题的探讨
- 关于C语言中函数调用和参数传递机制的探讨 (转)
- 关于C语言中'\0'结束符的探讨
- 关于C语言的函数调用过程和数组越界
- 转载-关于C语言中函数调用和参数传递机制的探讨
- 关于C语言中函数调用和参数传递机制的探讨(二 .传递一个参数)
- 关于Linux C语言开发字符越界的问题
- 关于C语言数组越界的演示程序
- 关于C语言中函数调用和参数传递机制的探讨--汇编
- 关于C语言中函数调用和参数传递机制的探讨