首页 新闻 会员 周边

一个简单又不简单的问题

0
悬赏园豆:10 [已解决问题] 解决于 2013-10-12 16:20
#include<stdio.h>
#include<string.h>
void main()
{
    char a[1000];
    int i;
    for(i=0;i<1000;i++)
    {
        a[i]=1+i;
    }
    printf("%d",strlen(a));
}

各位你们觉得这个输出的是什么呢?对于运行结果,我不知道该怎么解释,希望懂的人解答下。。

wj704的主页 wj704 | 初学一级 | 园豆:170
提问于:2013-10-12 10:38
< >
分享
最佳答案
2

输出255.

原因:

char类别是8位,最高位用来表示符号取值范围为(-128 到 127)

当 i 为127时,a[i] = 1 + 127;已经超过最大取值范围,再加上去就是 -128(10000000)。

当 i 为128时,a[i] = 1 + (-128);已经超过最大取值范围,再加上去就是 -127(10000001)。

当 i 为255时,  a[i] = a[128] + 127 = 0;

 

strlen计算长度是以0结尾的字符串。刚好下标为255的地方是0,也就是长度255

收获园豆:5
pillarhuang | 菜鸟二级 |园豆:207 | 2013-10-12 11:28

a[i]是char型的,1+i是整型的,将1+i 赋值给a[i]后,a[i]中的类型是什么呢?我试了一下以字符形式输出a[i]中的元素,会出错,但是以整型输出的话,结果就对了,输出的结果有些不明白,第一个就是-65。

分析起来有些奇怪,char是1字节的,8位,int是4个字节,32位,char a[1000],这个是字符数组,也就是它的每一个元素都是字符char型也就是8位,现在将整型赋值给它,会截取整型的高8位,还是整型的低8位呢?

再分析一下结果,第一个本来应该是整型1的,整型“1”在内存中的表示应该是00000000 00000000 00000000 00000001,不对了,感觉高8位和低8位都不符合结果,而且输出的结果,我还是无法解释。。

我是这样让它输出

    for(i=0;i<1000;i++)
    {
        a[i]=1+i;
         printf("%d\n",a[i]);
    }

结果:

是从-65到0,1到127,-128到-24,这样的分析是下标为66的地方是0,长度就是66了?但Strlen(a)输出的是255,再分析一下strlen这个函数:

strlen判断一个字符串的结束就是以其末尾的'\0'为界限。其实现代码可以模拟为以下:
int strlen(char *p)
{
int i=0;
while(*p++)i++;
return i;
}

所以他是不包括'\0'这个字符的。

所以用Strlen(a)这个函数时,传入的a是字符数组的始地址,遍历字符数组,当'\0'时就求出了其长度。所以我认为a[i]中的每个元素还是字符型,但是为什么要用printf("%d\n",a[i]);用printf("%c\n",a[i]);输出就不行呢?

printf("%d",a[i])这样输出不有表明a[i]是一个整型吗?矛盾了。。。。

wj704 | 园豆:170 (初学一级) | 2013-10-12 13:21
其他回答(3)
0

Strlen(a)结果为1000,它的内部实现是用一个循环计算字符串的长度,直到”\0”为止。

收获园豆:1
J.Y | 园豆:205 (菜鸟二级) | 2013-10-12 11:27

运行一下看看,说不定你会有其他收获。。。

支持(0) 反对(0) wj704 | 园豆:170 (初学一级) | 2013-10-12 13:22
0

255正解,原因如楼上。

收获园豆:4
幻天芒 | 园豆:37175 (高人七级) | 2013-10-12 13:15

  解释好像说不通。。你再看下我的疑惑。。

支持(0) 反对(0) wj704 | 园豆:170 (初学一级) | 2013-10-12 13:24

@wj704: 我也理解错了,哈哈。

首先:strlen是计算字符串长度,而不是数组长度。

所以计算的长度是printf("%s",a);这串字符的长度。可以直接输出这句话来查看,即可。

支持(0) 反对(0) 幻天芒 | 园豆:37175 (高人七级) | 2013-10-12 14:07

@幻天芒: 这还是没解答我上面的问题呢?不过还是谢谢你!

支持(0) 反对(0) wj704 | 园豆:170 (初学一级) | 2013-10-12 14:33

@wj704: 

a[i]是char型的,1+i是整型的,将1+i 赋值给a[i]后,a[i]中的类型是什么呢?我试了一下以字符形式输出a[i]中的元素,会出错,但是以整型输出的话,结果就对了,输出的结果有些不明白,第一个就是-65。

a[i]就是char类型的,第一个不应该是65,因为控制台只能显示一定长度,所以最顶上的数字被隐藏了。

分析起来有些奇怪,char是1字节的,8位,int是4个字节,32位,char a[1000],这个是字符数组,也就是它的每一个元素都是字符char型也就是8位,现在将整型赋值给它,会截取整型的高8位,还是整型的低8位呢?

整形到字符,是通过ASCII码换算的,不是所谓的截取。

支持(0) 反对(0) 幻天芒 | 园豆:37175 (高人七级) | 2013-10-12 15:27

@幻天芒:

*—*,忽视那个问题呀,真是不应该,刚查了一下字符型和整型之间的关系,清楚了一些了。字符型变量是整型的一个子集,现在搞懂了,不纠结了,谢谢啊!

支持(0) 反对(0) wj704 | 园豆:170 (初学一级) | 2013-10-12 16:18
0

你的疑问应该在这一句的行为具体是什么。

a[i]=1+i;

你要做的不是去从编译器的实现上的脑补内在的原因,你要作的是去查看C语言的标准是怎么定义的。

如果你仔细阅读了上面的C99标准, 那就应该知道你的问题其实是一个implementation-defined的行为。

在不同的编译器和不同的平台上,完全可以有不一样的结果。

不查标准靠实现来脑补的东西,很有可能换个地方就不对了。

嗷嗷 | 园豆:757 (小虾三级) | 2013-10-12 16:25

嗯,我的疑问确实是这句,不知道要怎么深究了。非常感谢你,我长知识了,不过理解得还不够。。

看到你贴的这个标准,翻译了一下,

“当一个数据类型被转换成另一个数据类型而不是布尔型,如果这个值能被新类型表示,它就没改变,

否则,如果新类型是无符号的,这个值会被重复加或减一个直到这个值在新类型范围内能够表示这种新类型的更大的值,否则,如果这种新类型是有符号的,且这个值不能被它表示,那么结果是implementation-defined的行为或有符号的implementation-defined 的行为 ”

按上面的标准理解下我的问题,1+i是个有符号的整型,a[i]是char型,而且字符型不能被整型表示,那么结果是implementation-defined的行为或有符号的implementation-defined 的行为,

implementation-defined的行为或有符号的implementation-defined 的行为又是什么呢?希望得到你的进一步解释。

支持(0) 反对(0) wj704 | 园豆:170 (初学一级) | 2013-10-12 22:01

发现自己看书看少了,也不知从哪里获取资源,希望你能推荐一些书,或者网上的学习资源,我自己再去琢磨下,真的非常感谢你,虽然这个结贴了,虽然不能给你园豆了,下次有机会再报答 *—* ……

支持(0) 反对(0) wj704 | 园豆:170 (初学一级) | 2013-10-12 22:17

@wj704: 对于a[i]=1+i;这句话,用标准来解释就是,a[i]是new type,现在是char,是一种有符号类型。1+i是value,这里1+i具体是什么类型不重要,主要是他的value是否在new type的表示范围里面。char只能表示-127+128, 1+i的值超过了就是implementation-defined。

另外一个,为什么C标准不规定char类型的情况呢,标准上没说,推测是-127和128的绝对值不一样,真要定义具体的行为,会提高C语言编译器的复杂度,所以就不规定,大家根据自己的硬件平台来具体实现好了。

支持(0) 反对(0) 嗷嗷 | 园豆:757 (小虾三级) | 2013-10-14 09:00

@wj704: 至于怎么提高,第一个建议就是不要混博问了,去混stackoverflow. 对于你的问题,我只是简单的google了一下stackoverflow convert int to char就找到线索了。

至于资源,这里面列的挺全了http://www.cnblogs.com/lua5/archive/2010/12/04/1895968.html

最重要的一点,不要用具体实现来解释问题,标准才是唯一的东西,具体实现只是用来理解标准的。

支持(0) 反对(0) 嗷嗷 | 园豆:757 (小虾三级) | 2013-10-14 09:14
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册