快速提问
我用另一个可能非常简单的 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个问题。为什么它们不同,为什么 y 是 6?谢谢你们。
编辑:抱歉,我知道如何解决它,我只是想了解发生了什么。那么 strlen 是否会继续转发该点直到碰巧找到 \0 为止?另外,当我在 main 函数中而不是在 get_len 函数中执行 strlen 时,两者都是 4。这只是巧合吗?
I've come to bother you all with another probably really simple C question.
Using the following code:
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 questions. Why are they different and why is y 6? Thanks guys.
EDIT: Sorry, I know what would fix it, I kind of just wanted to understand what was going on. So does strlen just keep forwarding the point till it happens to find a \0? Also when I did strlen in the main function instead of in the get_len function both were 4. Was that just a coincidence?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
y
不是以 null 结尾的。strlen()
计算字符数,直到遇到空字符。你的碰巧在 6 之后找到了 1,但它可以是任何数字。试试这个:char y[] = {'t','e','s','t', '\0'};
下面是
strlen()< 的实现/code> 可能看起来像(我突然想到——手边没有我的 K&R 书,但我相信那里给出了一个实现):
y
is not null-terminated.strlen()
counts characters until it hits a null character. Yours happened to find one after 6, but it could be any number. Try this:char y[] = {'t','e','s','t', '\0'};
Here's what an implementation of
strlen()
might look like (off the top of my head -- don't have my K&R book handy, but I believe there's an implementation given there):这个
不是一个正确的以零结尾的字符串。它是一个由四个字符组成的数组,没有终止符
'\0'
。strlen()
只是计算字符数,直到达到零。使用y
它只是对数组末尾进行计数,直到意外找到零字节为止。这样做会调用未定义的行为。该代码也可能会格式化您的硬盘。
您可以通过使用字符数组初始化的特殊语法来避免这种情况:
这会使用 五个 个字符初始化
y
,因为它会自动附加一个'\0'
。请注意,我还未指定数组的大小。编译器会自行计算出这一点,如果我更改字符串的长度,它会自动重新计算。
顺便说一句,这是一个简单的
strlen()
实现:现代实现可能不会获取单个字节,甚至不会使用 CPU 内在函数,但这是基本算法。
This
is not a proper zero-terminated string. It's an array of four characters, without the terminating
'\0'
.strlen()
simply counts the characters until it hits a zero. Withy
it simply counts over the end of the array until it accidentally finds a zero byte.Doing this you are invoking undefined behavior. The code might just as well format your hard drive.
You can avoid this by using the special syntax for character array initialization:
This initializes
y
with five characters, since it automatically appends a'\0'
.Note that I also left the array's size unspecified. The compiler figures this out itself, and it automatically re-figures if I change the string's length.
BTW, here's a simple
strlen()
implementation:Modern implementations will likely not fetch individual bytes or even use CPU intrinsics, but this is the basic algorithm.
以下不是以 null 结尾的字符数组:
strlen()
契约的一部分是为其提供一个指向以 null 结尾的字符串的指针。由于strlen(y)
不会发生这种情况,因此您会得到未定义的行为。在您的特定情况下,您会返回6
,但任何事情都可能发生,包括程序崩溃。来自C99的7.1.1“术语定义”:
The following is not a null terminated array of characters:
Part of
strlen()
's contract is that it be provided with a pointer to a null terminated string. Since that doesn't happen withstrlen(y)
, you get undefined behavior. In your particular case, you get6
returned, but anything could happen, including a program crash.From C99's 7.1.1 "Definition of terms":
strlen
适用于字符串。字符串定义为以\0
字符结尾的字符序列(数组)。您的
x
指向一个字符串。因此,strlen
使用x
作为参数可以正常工作。您的 y 不是字符串。因此,将
y
传递给strlen
会导致未定义的行为。结果是毫无意义且不可预测的。strlen
works with strings. String is defined as a sequence (array) of characters terminated with\0
character.Your
x
points to a string. So,strlen
works fine withx
as an argument.Your
y
is not a string. For this reason, passingy
tostrlen
results in undefined behavior. The result is meaningless and unpredictable.您需要以空终止 y。
strlen() 基本上采用您给它的指针并计算字节数,直到内存中的下一个 NULL。恰巧你的内存里后来出现了两个字节的NULL。
You need to null-terminate y.
strlen() basically takes the pointer you give it and counts the number of bytes until the next NULL in memory. It just so happened that there was a NULL two bytes later in your memory.
实际的 C 类型字符串比其字符数大 1,因为它需要一个终止空字符。
因此,
char y[4] = {'t','e','s','t'};
不形成字符串,因为它有四个字符。char y[] = "test";
或char y[5] = "test";
将形成一个字符串,因为它们有一个包含五个字符的字符数组以空字节终止符结束。An actual C-type string is one bigger than the number of its characters, since it needs a terminating null character.
Therefore,
char y[4] = {'t','e','s','t'};
doesn't form a string, since it's four characters.char y[] = "test";
orchar y[5] = "test";
would form a string, since they'd have a character array of five characters ending with the null-byte terminator.会是一样的
would be the same as
正如其他人所说,您只需要确保以 0 或 '\0' 字符结束字符串即可。作为旁注,您可以查看: http://bstring.sourceforge.net/ 。它具有 O(1) 字符串长度函数,与 C/C++ strlen 不同,后者容易出错且速度慢,为 O(N),其中 N 是非空字符的数量。我不记得上次使用strlen是什么时候了,它是朋友。追求安全&快速的函数/类!
As others have said, you just need to make sure to end a string with the 0 or '\0' character. As a side note, you may check this out: http://bstring.sourceforge.net/ . It has O(1) string length function, unlike the C/C++ strlen which is error prone and slow at O(N), where N is the number of non-null characters. I don't remember the last time when I used strlen and it's friends. Go for safe & fast functions/classes!
使用单引号时始终使用 '/0',但在双引号中避免在 strlen() 中使用 '/0'
请注意,strlen() 函数在计算长度时不会计算空字符 \0
when you use the single quotes always use '/0' but in double quotes avoid to use the '/0' in strlen()
Note that the strlen() function doesn't count the null character \0 while calculating the length