C编程 - strlen的功能

Rya*_*ker 4 c string strlen

我正在尝试理解一些字符串函数,以便我可以在以后的编码项目中更有效地使用它们,所以我在下面设置了简单的程序:

#include <stdio.h>
#include <string.h>

int main (void)
{
// Declare variables:
char test_string[5];
char test_string2[] = { 'G', 'O', '_', 'T', 'E', 'S', 'T'};
int init; 
int length = 0;
int match;

// Initialize array:
for (init = 0; init < strlen(test_string); init++)
{    test_string[init] = '\0';
}

// Fill array:
test_string[0] = 'T';
test_string[1] = 'E';
test_string[2] = 'S';
test_string[3] = 'T';

// Get Length:
length = strlen(test_string);

// Get number of characters from string 1 in string 2:
match = strspn(test_string, test_string2);

printf("\nstrlen return = %d", length);
printf("\nstrspn return = %d\n\n", match);

return 0;
}
Run Code Online (Sandbox Code Playgroud)

我希望看到回归:

strlen return = 4 strspn return = 4

但是,我看到strlen return = 6和strspn return = 4.据我所知,char test_string [5]应该分配5个字节的内存并将十六进制00放入第五个字节.for循环(甚至不应该是nessecary)然后应该将test_string的所有内存字节设置为十六进制00.然后,紧接着的行应该填充test_string字节1到4(或test_string [0]到test_string [3])用我指定的.此时调用strlen应该返回一个4,因为它应该从字符串0的地址开始并计算一个增量,直到它到达第一个空字符,即字符串[4].然后strlen返回6.任何人都可以解释这个吗?谢谢!

Kei*_*son 7

char test_string[5];
Run Code Online (Sandbox Code Playgroud)

test_string是一个包含5个未初始化 char对象的数组.

for (init = 0; init < strlen(test_string); init++)
Run Code Online (Sandbox Code Playgroud)

KABOOM.strlen扫描第一个'\0'空字符.由于内容test_string是垃圾,因此行为未定义.如果碰巧有空字符,它可能返回一个小值,如果没有任何零字节,它可能返回一个大值或程序崩溃test_string.

即使不是这种情况,strlen()for循环的标题中进行评估也是低效的.每次strlen()调用都必须重新扫描整个字符串(假设你给它一个有效的字符串),所以如果你的循环工作,它将是O(N 2).

如果您只想test_string包含零字节,可以这样初始化它:

char test_string[5] = "";
Run Code Online (Sandbox Code Playgroud)

或者,因为您稍后初始化前4个字节:

char test_string[5] = "TEST";
Run Code Online (Sandbox Code Playgroud)

要不就:

char test_string[] = "TEST";
Run Code Online (Sandbox Code Playgroud)

(后者让编译器发现它需要5个字节.)

回到你的声明:

char test_string2[] = { 'G', 'O', '_', 'T', 'E', 'S', 'T'};
Run Code Online (Sandbox Code Playgroud)

这导致test_string27个字节长,没有尾随'\0'字符.这意味着传递test_string2给任何需要指向字符串的指针的函数都会导致未定义的行为.你可能想要这样的东西:

char test_string2[] = "GO_TEST";
Run Code Online (Sandbox Code Playgroud)

  • @RyanBarker:C中的"字符串"是数据布局,而不是数据类型; 它被定义为"由第一个空字符终止并包括第一个空字符的连续字符序列".一个`char`数组可能包含也可能不包含字符串,编译器不会认为它将包含一个字符串.字符串文字(几乎总是)以null结尾; 字符数组不是. (2认同)