我正在尝试理解一些字符串函数,以便我可以在以后的编码项目中更有效地使用它们,所以我在下面设置了简单的程序:
#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.任何人都可以解释这个吗?谢谢!
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)