博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一个小问题
阅读量:5997 次
发布时间:2019-06-20

本文共 1468 字,大约阅读时间需要 4 分钟。

这是《深度C语言》上面的一个小程序,看看大家会认为结果是多少?

1 int main() 2  3 {     4  5 char a[1000];     6  7 int i;     8  9 for(i=0; i<1000; i++)    10 11 {     a[i] = -1-i;     }    12 13 printf("%d",strlen(a));    14 15 return 0;16 17 }

 

此题看上去真的很简单,但是却鲜有人答对。答案是255

       for 循环内,当i 的值为0 时,a[0]的值为-1。关键就是-1 在内存里面如何存储。 我们知道在计算机系统中,数值一律用补码来表示(存储)。主要原因是使用补码,可    以将符号位和其它位统一处理;同时,减法也可按加法来处理。另外,两个用补码表示的数 相加时,如果最高位(符号位)有进位,则进位被舍弃。正数的补码与其原码一致;负数的     补码:符号位为1,其余位为该数绝对值的原码按位取反,然后整个数加1。 按照负数补码的规则,可以知道-1 的补码为0xff,-2 的补码为0xfe……当i 的值为127     时,a[127]的值为-128,而-128 是char 类型数据能表示的最小的负数。当i 继续增加,a[128] 的值肯定不能是-129。因为这时候发生了溢出,-129 需要9 位才能存储下来,而char 类型     数据只有8 位,所以最高位被丢弃。剩下的8 位是原来9 位补码的低8 位的值,即0x7f。 当i 继续增加到255 的时候,-256 的补码的低8 位为0。然后当i 增加到256 时,-257 的补     码的低8 位全为1,即低八位的补码为0xff,如此又开始一轮新的循环…… 按照上面的分析,a[0]到a[254]里面的值都不为0,而a[255]的值为0。

     strlen 函数是计 算字符串长度的,并不包含字符串最后的‘\0’。而判断一个字符串是否结束的标志就是看 是否遇到‘\0’。如果遇到‘\0’,则认为本字符串结束。         分析到这里,strlen(a)的值为255 应该完全能理解了。这个问题的关键就是要明白char 类型默认情况下是有符号的,其表示的值的范围为[-128,127],超出这个范围的值会产生溢     出。另外还要清楚的就是负数的补码怎么表示。弄明白了这两点,这个问题其实就很简单了。

……………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………

完成这些,我们要考虑一个简单的问题,最后的结果a[255]的结果是0,而不是‘\0’啊,怎么说是\0呢,其实这就是C语言里面一个转义字符的问题了,首先来了解一下什么是转义字符。

所有的ASCII码都可以用“\”加数字(一般是8进制数字)来表示。而C中定义了一些字母前加"\"来表示常见的那些不能显示的ASCII字符,如\0,\t,\n等,就称为转义字符,因为后面的字符,都不是它本来的ASCII字符意思了。

这些字符在通过编译器的时候会直接转化为其对应的ASCII里面的值,例如\n,表示换行符,程序运行的时候在内存就直接用他的ASCII码值10来表示\n了,\0的意义就是空字符,而他的十进制ASCII码值就是0。

转载于:https://www.cnblogs.com/greyfox/archive/2012/08/11/2633480.html

你可能感兴趣的文章
最快排序和搜索算法的最简代码实现_转
查看>>
tensorflow 卷积/反卷积-池化/反池化操作详解
查看>>
Aria2 懒人安装教程
查看>>
正确理解Spring事务和数据库事务和锁
查看>>
Android Error:Execution failed for task ':app:compileDebugJavaWithJavac' 解决方案
查看>>
细节问题思考
查看>>
使用Boolean类型同步锁引起异常的分析
查看>>
C#中Dynamic关键字
查看>>
空手套白狼,硬阅java字节码class文件
查看>>
C#: Get current keyboard layout\input language
查看>>
Android Studio 通过一个登录功能介绍SQLite数据库的使用
查看>>
C# Base64Helper
查看>>
Docker安装和常用命令
查看>>
Spring Security 之方法级的安全管控
查看>>
深入理解Java的接口和抽象类
查看>>
马的遍历进阶版--骑士巡游(添加了评估函数)[Teaks & xgluxv & r]
查看>>
给石头的诗
查看>>
T-SQL朝花夕拾(五) 动态T-SQL语句语法
查看>>
CGI编程读书笔记
查看>>
a标签的link、visited、hover、active的顺序
查看>>