字符溢出分析(数据类型范围以及‘\0’重新认识)
2015-09-14 17:00
453 查看
#include <iostream> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { char a[1000]; int i; for (i=0;i<1000;i++) { a[i] = -1-i; } cout<<strlen(a)<<endl; system("pause"); return 0; }
做题目的时候没有考虑到字符溢出,自然做错了
【分析】
我们知道计算机底层只认识0,1,所以任何数据到了底层都会通过计算转换成0,1,那么负数是怎样存储呢?由于“-”无法存入内存,我们把它做个标记,把基本数据类型的最高位腾出来,用来存符号,同时约定如下:如果最高位是1,表明这个数是负数,其值为除最高位以外的剩余位的值添上这个“-”号。
bool型为布尔型,占1个字节,取值0或1。 BOOL型为int型,一般认为占4个字节,取值TRUE/FALSE/ERROR。 sbyte型为有符号8位整数,占1个字节,取值范围在128~127之间。 bytet型为无符号16位整数,占2个字节,取值范围在0~255之间。 short型为有符号16位整数,占2个字节,取值范围在-32,768~32,767之间。 ushort型为无符号16位整数,占2个字节,取值范围在0~65,535之间。 int型为有符号32位整数,占4个字节,取值范围在-2,147,483,648~2,147,483,647之间。 uint型为无符号32位整数,占4个字节,取值范围在0~4,294,967,295之间。 long型为64位有符号整数,占8个字节,取值范围在9,223,372,036,854,775,808~9,223,372,036,854,775,807之间。 ulong型为64位无符号整数,占8个字节,取值范围在0~18,446,744,073,709,551,615之间。 float型为32位单精度实数,占4个字节,取值范围3.4E+10的负38次方~3.4E+10的38次方之间。 double型为64位实数,占8个字节,取值范围1.7E+10的负308次方~1.7E+10的正308次方。
for循环内,当i的值为0时,a[0]的值为-1.在计算机系统中,数值一律用补码来表示。在用两个补码的数相加时,如果最高位(符号位)有进位,则进位被舍弃。正数的补码与其原码一致;负数的补码:符号位为1,其余位为该数绝对值的原码按位取反,然后整个数+1.
-1的补码为0xff,-2的补码为0xfe……
当i的值为127时,a[127]的值为-128,而-128是char类型数据能表示的最小的负数。
当i继续增加,a[128]的值肯定不能使-129,因为这时候发生了溢出。-129需要9位(1 1000 0001)才能存储下来,而char只有8位,所以最高位被丢弃,剩下的8位是原来9位补码(1 111 1111)的低8位的值,即0x7f。当i继续增加到255时,-256的补码低8位全为0,然后当i增加到256时,-257的补码的低8位全为1,即低8位的补码为0xff,如此又开始一轮新的循环……
按照上面的分析,a[0]~a[254]里面的值都不为0,而a[255]的值我0.
‘\0’ 的ASCII值为0。
strlen函数是计算字符串长度的,并不包含字符串最后的’\0’。判断一个字符串是否结束的标志就是看是否遇到’\0’;如果遇到’\0’,则认为字符串结束。
由此分析,strlen(a)的值为255。
相关文章推荐
- Perl ASCII 字符判断
- 与ASCII码相关的C语言字符串操作函数
- 常用字符集编码详解(ASCII GB2312 GBK GB18030 unicode UTF-8)
- PHP详解ASCII码对照表与字符转换
- 趣谈Unicode、Ascii、utf-8、GB2312、GBK等编码知识
- php实现图片转换成ASCII码的方法
- vbs实现unicode和ascii编码转换
- Python中输出ASCII大文字、艺术字、字符字小技巧
- JS中把字符转成ASCII值的函数示例代码
- python UnicodeEncodeError 问题解决
- ASCII 字元表(详细讲解)
- ASCII,Unicode和UTF-8
- VB中CHR()码值对应表
- ASCII、ANSI、Unicode及UTF-8编码
- Unicode,ANSI,UTF-8的故事
- ANSI、Unicode、UTF-8、DBCS等字符集及相关数据类型、函数的区别
- C 编程实现打印 0 - 255 ASCII 码表
- Pyscripter为什么总报错?UnicodeEncodeError: 'ascii' codec
- 基于WEB的两种空格, 在做服务端处理时,要做特殊处理。