快速的问题

我来打扰你们所有人可能都是非常简单的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? 此外,当我在主函数中而不是在get_len函数中执行strlen时,两者都是4.那只是巧合吗?

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; } 

这个

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

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

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

 char y[] = "test"; 

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

顺便说一句,这是一个简单的strlen()实现:

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

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

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

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

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

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

字符串是由第一个空字符终止并包括第一个空字符的连续字符序列。

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

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

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

你需要null-terminate 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之前的字节数。 碰巧你的内存中有两个字节的NULL。

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

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

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

会是一样的

 char *x = "test"; 

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