快速的问题

时间:2010-04-23 20:45:27

标签: c string strlen

我用另一个可能非常简单的C问题来打扰你们。

使用以下代码:

int get_len(char *string){

    printf("len: %lu\n", strlen(string));

    return 0;
}

int main(){

    char *x = "test";
    char y[4] = {'t','e','s','t'};

    get_len(x); // len: 4
    get_len(y); // len: 6

    return 0;
}

2个问题。为什么他们不同,为什么是6?谢谢你们。

编辑:对不起,我知道会解决什么问题,我只是想了解发生了什么。那么strlen只是继续转发这个点,直到碰巧找到一个\ 0?另外当我在main函数中而不是在get_len函数中执行strlen时,两者都是4.那只是巧合吗?

9 个答案:

答案 0 :(得分:13)

y不会以空值终止。 strlen()计算字符,直到它遇到空字符。你的碰巧在6点之后找到了一个,但它可能是任何数字。试试这个:

char y[] = {'t','e','s','t', '\0'};

以下是strlen()的实现可能看起来像什么(我的头顶 - 没有我的K& R书,但我相信那里有一个实现):

size_t strlen(const char* s)
{
    size_t result = 0;
    while (*s++) ++result;
    return result;
}

答案 1 :(得分:4)

这个

char y[4] = {'t','e','s','t'};

不是一个正确的以零结尾的字符串。这是一个由四个字符组成的数组, 没有 终止'\0'strlen()只需对字符进行计数,直至达到零。对于y,它只是计算数组的末尾,直到它意外地找到零字节 这样做是为了调用未定义的行为。代码也可以格式化您的硬盘驱动器。

您可以使用字符数组初始化的特殊语法来避免这种情况:

char y[] = "test";

这会使用 五个 字符初始化y,因为它会自动附加'\0'
请注意,我还没有指定数组的大小。编译器自己计算出来,如果我改变字符串的长度,它会自动重新计算。

BTW,这是一个简单的strlen()实现:

size_t strlen(const char* p)
{
    size_t result = 0;
    while(*p++) ++result;
    return result;
}

现代实现可能无法获取单个字节甚至使用CPU内在函数,但这是基本算法。

答案 2 :(得分:3)

以下不是以空字符结尾的字符数组:

 char y[4] = {'t','e','s','t'};

strlen()合同的一部分是它提供了一个指向空终止字符串的指针。由于strlen(y)不会发生这种情况,因此您会得到未定义的行为。在您的特定情况下,您会返回6,但任何事情都可能发生,包括程序崩溃。

从C99的7.1.1“术语的定义”:

  

string 是由第一个null终止并包含第一个null的连续字符序列   字符。

答案 3 :(得分:3)

strlen适用于字符串。字符串定义为以\0字符结尾的字符序列(数组)。

您的x指向一个字符串。因此,strlen可以正常使用x作为参数。

您的y不是字符串。因此,将y传递给strlen会导致未定义的行为。结果毫无意义且无法预测。

答案 4 :(得分:2)

您需要空终止y。

int get_len(char *string){

    printf("len: %lu\n", strlen(string));

    return 0;
}

int main(){

    char *x = "test";
    char y[5] = {'t','e','s','t','\0'};

    get_len(x); // len: 4
    get_len(y); // len: 4

    return 0;
}

strlen()基本上接受你给它的指针,并计算内存中下一个NULL之前的字节数。碰巧你的内存中有两个字节的空白。

答案 5 :(得分:1)

实际的C类型字符串比字符数大一,因为它需要一个终止空字符。

因此,char y[4] = {'t','e','s','t'};不会形成字符串,因为它是四个字符。 char y[] = "test";char y[5] = "test";将形成一个字符串,因为它们有一个以空字节终止符结尾的五个字符的字符数组。

答案 6 :(得分:0)

char y[5] = {'t','e','s','t','\0'};

相同
char *x = "test"; 

答案 7 :(得分:0)

正如其他人所说,你只需要确保以0或'\ 0'字符结束字符串。作为旁注,您可以查看:http://bstring.sourceforge.net/。它具有O(1)字符串长度函数,不像C / C ++ strlen,它容易出错并且在O(N)处很慢,其中N是非空字符的数量。我不记得最后一次使用strlen和它的朋友了。寻求安全和保障快速的功能/类!

答案 8 :(得分:0)

当你使用单引号时总是使用'​​/0'但在双引号中避免在strlen()中使用'/0'

注意 strlen() 函数在计算长度时不计算空字符\0