我用另一个可能非常简单的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.那只是巧合吗?答案 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