乱入的'\0'

看这个题之前,先来回忆一下strlen函数的工作机制:
strlen所作的仅仅是一个计数器的工作,它从内存的某个位置(可以是字符串开头,中间某个位置,甚至是某个不确定的内存区域)开始扫描,每碰到一个非’\0’的字符,计数器的值加1,直到碰到第一个字符串结束符’\0’为止,然后返回计数器值(长度不包含’\0’)。

#include <stdio.h>

int main()
{
    char a[1000];
    int i;
    for(i=0; i<1000; i++)
    {
        a[i] = -1-i;
    }
    printf("%d",strlen(a));
    return 0;
}

第一眼看到题目是不是觉得太简单了一点,有一种把1000脱口而出的欲望,这么简单我会出给你?想太多了吧!
且不说这儿数组的类型是char,就算它的类型是int,程序就会输出1000?想想上面对strlen的定义是怎么说的?遇到’\0’才结束统计,你能保证数组后面的空间第一个字符就存储的是’\0’吗?不能吧!因此不要轻易给出答案。

运行后,输出的答案是这样的,是不是有点讶异,整个人突然懵了?大大的问号突然充斥着你。

这里写图片描述

分析一下,这个题其实无非也就以下几个考点:
1、负数在内存中的存储方式;
2、char型数据占空间大小;
3、0其实就是’\0’
4、strlen函数什么时候结束统计;

负数在内存中是以其补码存储的,那么问题又来了,什么是补码?正数的补码是其原码,负数的补码是其原码取反加1,连原码都不知道的可以去看看补补了。
因为a[i] = -1 - i; 而-1 - i的值一定是负数,本来也没什么,但你要知道我们的数组元素是char型的,那么它就只占一个字节,即8个bit,所以,当-1 - i的值小到-129时,a[i]里面存的值就不是我们想象的值了,而当 -1 - i的值小到-256时,a[i]里面存的值会吓你一跳。看看下面这张图:

这里写图片描述

可以看见当i = 255时,a[i] = 0,而我们知道0其实就是’\0’,因为’\0’的ASCII是0,而strlen函数是遇到’\0’停止统计的,且不统计’\0’,也就是说它只统计a[255]前面的元素个数,而我们知道数组下标是从0开始的,所以a[255]前面的元素个数为255个,那么输出为255就很好解释了。

这个题仔细分析其实很简单,但是一不小心就上当了,因此,我们在看待问题是一定要考虑全面,不要轻易下结论。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值