为什么报告的字符串长度减一?

时间:2013-02-14 06:05:11

标签: c pointers

我在理解这段代码时遇到了一些麻烦。为什么长度为3?如果我输入hi,则长度为1。

#include <stdlib.h>
#include <stdio.h>

int len(char *s)  
{
    int i = 0; 
    while(*(++s) != '\0') 
        i++; 
    printf("%d", i);
    return i; 
} 

int main()
{
    len("this");
    getchar();
}

4 个答案:

答案 0 :(得分:1)

不仅长度减去1,而且如果你给它一个空字符串作为参数,你希望它返回0,你最终可能会违反访问权限(尽管大部分时间你都赢了' t因为零字节在未初始化的内存中很常见,或者是一个随机数(基本上它会返回在c字符串空字符串常量后面1个字节存储的非零字节数。

长度偏离1,因为您正在使用前缀增量运算符,该运算符被评估为行中的第一个:

while(*(++s)!='\0') 

具体来说,如果你看一下你在那里做的事情,那么看起来像这样:

char *s = "this";
int i = 0;

while (1) {
    s = s + 1;
    if (*s == '\0') break;
    i++;
}
printf("%d", i);
...

你看到了这个问题吗? ++s首先递增指针。所以你跳过字符串的第一个字母。

无论如何,你可能想要的是这样的:

int len(const char *s) {

    int clen = 0;
    while (*s++ != '\0') clen++;
    return clen;

}

当然,当标准C库中有strlen()strnlen()时,人们可能会问你为什么要重新发明轮子。也许这只是一个练习?

答案 1 :(得分:0)

++s在评估之前递增该值。这就是为什么你的答案比实际长度少一个。使用s++

答案 2 :(得分:0)

++s是前缀增量,因此循环实际上将从第二个字符开始。最短的修复方法是将其更改为后缀增量:

while(*(s++) != '\0')

可替换地:

while(*s++)

答案 3 :(得分:0)

在阅读了几次问题后,我明白“len”的功能会为长度为2的字符串返回1(如'hi')

这是因为以下行:while (*(++s)!='\0')

解析条件导致以下陈述(只是为了明确你的代码会发生什么,当然这不是应该怎么做)

startover: 
    s = s + 1;
    if (*s != '\0') goto end;
        i = i + 1;
    goto startover;

正如您所看到的,在开始计算之前,您总是跳过第一个角色。您可以使用s++来避免这种情况。这将在检查'\ 0'之后移动s的修改:

startover: 
    if (*s != '\0') goto end;
        s = s + 1;
        i = i + 1;
    goto startover;