S1
,S2
和S3
之间有什么区别?
char S1[6];
S1[0] = 'A';
S1[1] = 'r';
S1[2] = 'r';
S1[3] = 'a';
S1[4] = 'y';
char S2[6] = {'A','r','r','a','y'};
string S3 = "Array";
当我使用if (strcmp(a,b) == 0)
运行程序时a, b = S1, S2, S3
。
它表明S2
和S3
相同,S1
和S2
不同。
这是为什么?
为什么不是这三个都是等价的?
当我向'\0'
,S1b
添加S1c
时。所有3都是一样的。这是可以理解的。
但为什么在我的第一次试验中,S2
和S3
是一样的?我也没有包含'\0'
。我怀疑S1
和S2
应该相同,但不是S2
和S3
。
谁能告诉我为什么我的想法错了???
感谢您的回答。我已尝试将设置更改为以下内容:
char S1[5];
S1[0] = 'A';
S1[1] = 'r';
S1[2] = 'r';
S1[3] = 'a';
S1[4] = 'y';
char S2[5] = {'A','r','r','a','y'};
string S3 = "Array";
现在显然S2
和S3
不一样,因为它们相差'\0'
。
但是,如果我使用strcmp来比较两者,我仍然有点困惑,为什么S1
和S2
这次不一样?
答案 0 :(得分:4)
比较数组的实际内存中值:
{,}
语法时,任何额外元素都归零。因此char foo[5] = { 1, 2 }
与char foo[5] = { 1, 2, 0, 0, 0}
相同。char
(或wchar_t
)数组,其中一个额外的元素设置为\0
(空终止符)。 / LI>
醇>
目视:
S1 = 0x41, 0x72, 0x72, 0x61, 0x79, 0x??
S2 = 0x41, 0x72, 0x72, 0x61, 0x79, 0x00
S3 = 0x41, 0x72, 0x72, 0x61, 0x79, 0x00
请注意,您遇到strcmp
的安全问题:它没有长度参数,它一直在搜索,直到遇到\0
,这可能永远不会(即直到它导致段错误或访问冲突)。而是使用更安全的函数,如strncmp
或(如果使用C ++)std::string
类型。
答案 1 :(得分:2)
It shows that S2 and S3 are the same, and S1 and S2 is different.
S3包含S1没有的nul终结符。这string S3 = "Array";
表示
| A | r | r | a | y | \0 |
S2是
| A | r | r | a | y | \0 |
虽然S1是
| A | r | r | a | y | Garbage |
S1和S2比较可以导致UB(我推测),因为S1不是nul终止的,并且没有我们在strcmp
传递的长度。
#include <stdio.h>
#include <string.h>
int main(void)
{
char S1[6];
S1[0] = 'A';
S1[1] = 'r';
S1[2] = 'r';
S1[3] = 'a';
S1[4] = 'y';
S1[5] = 0;
char S2[6] = {'A','r','r','a','y', 0};
printf("%d" ,strcmp(S1,S2));
return 0;
}
输出:
0
答案 2 :(得分:1)
strcmp()函数开始比较每个字符串的第一个字符。如果它们彼此相等,则继续使用以下对,直到字符不同或者到达终止空字符为止。
我不认为使用它来比较S1和S2是安全的。输入到strcmp是第一个字符的地址。 S1不是以空值终止的。虽然在两种情况下都分配了6个字节,但S1 [5]未初始化。有可能他们有一些垃圾价值。这里的风险是strcmp最终还会在搜索字符diff或null字符时比较未分配的内存。这甚至可能导致seg故障或访问冲突。
可视化S1,S2,S3的内存对齐可能是这样的
S1 = A | r | r | a | y | ?
S2 = A | r | r | a | y | 0
S3 = A | r | r | a | y | 0
S2和S3之间的任何比较都是安全的。 S1 vs S2或S3可能不是。
答案 3 :(得分:0)
只需添加现有答案
char S2[6] = {'A','r','r','a','y'};
string S3 = "Array";
两者都以NULL结尾,因此strcmp()
运行良好,并说它们都是相同的。而对于S1
,显式完成赋值,此数组没有NULL终止。所以这不是C中的有效字符串。因此使用strcmp()
可能会导致未定义的行为。
S3
的要点是S3是一个只读的字符串文字。大多数情况下,这些值存储在只读位置。因此,当您尝试在初始化后向S3
写一些内容时,您可能会看到崩溃。所以我们应该在使用S3