strcmp() 是什么?
strcmp() 是 C 语言标准库 <string.h> 中提供的一个函数,它的全称是 "string compare"(字符串比较),它的主要作用是逐个字符地比较两个字符串,并根据比较结果返回一个整数值。

函数原型
#include <string.h> int strcmp(const char *str1, const char *str2);
参数说明:
str1: 指向第一个要比较的字符串的指针。str2: 指向第二个要比较的字符串的指针。
返回值说明:
这是 strcmp() 最核心的部分,它的返回值是一个整数,其含义如下:
- 返回值
< 0: 表示str1小于str2。- 这意味着在字典序(lexicographical order)中,
str1出现在str2的前面。 strcmp("apple", "banana")会返回一个负数。
- 这意味着在字典序(lexicographical order)中,
- 返回值
== 0: 表示str1等于str2。- 这意味着两个字符串的长度和所有对应位置的字符都完全相同。
strcmp("hello", "hello")会返回0。
- 返回值
> 0: 表示str1大于str2。- 这意味着在字典序中,
str1出现在str2的后面。 strcmp("banana", "apple")会返回一个正数。
- 这意味着在字典序中,
重要提示: strcmp() 返回的具体负数或正数值是未定义的,你不应该依赖这个具体数值是 1 还是 -1,而应该只关心它是小于零、等于零还是大于零,不同的编译器或标准库实现可能会返回不同的具体数值。

比较规则详解
strcmp() 的比较是基于字符的ASCII码值(或字符在系统中的编码值)进行的,它会从字符串的开头开始,逐个字符进行比较。
- 逐个字符比较:比较
str1和str2在当前位置的字符。 - 发现差异:一旦发现两个字符串在某个位置上的字符不同,比较立即结束。
str1的字符 ASCII 码值更小,则返回一个负数。str1的字符 ASCII 码值更大,则返回一个正数。
- 一个字符串是另一个的前缀:如果所有比较过的字符都相同,但其中一个字符串先结束(即遇到了
\0空字符)。- 较短的字符串被认为更小。
strcmp("hello", "hello world")会返回一个负数,因为"hello"是"hello world"的前缀。
- 完全相同:如果两个字符串同时到达
\0,说明它们完全一样,返回0。
代码示例
下面通过几个例子来直观地理解 strcmp() 的行为。
#include <stdio.h>
#include <string.h>
int main() {
char str1[] = "apple";
char str2[] = "banana";
char str3[] = "apple";
char str4[] = "Apple"; // 'A' 的 ASCII 码是 65, 'a' 的 ASCII 码是 97
char str5[] = "apples";
// 示例 1: "apple" < "banana"
printf("strcmp(\"apple\", \"banana\") = %d\n", strcmp(str1, str2)); // 输出一个负数
// 示例 2: "apple" == "apple"
printf("strcmp(\"apple\", \"apple\") = %d\n", strcmp(str1, str3)); // 输出 0
// 示例 3: "apple" > "Apple" (因为 'a' > 'A')
printf("strcmp(\"apple\", \"Apple\") = %d\n", strcmp(str1, str4)); // 输出一个正数
// 示例 4: "apple" < "apples" (因为 "apple" 是 "apples" 的前缀)
printf("strcmp(\"apple\", \"apples\") = %d\n", strcmp(str1, str5)); // 输出一个负数
return 0;
}
可能的输出结果:
strcmp("apple", "banana") = -1
strcmp("apple", "apple") = 0
strcmp("apple", "Apple") = 32 // 'a' - 'A' = 97 - 65 = 32
strcmp("apple", "apples") = -1
(注意:输出结果的具体数值可能因编译器和库的实现而异,但正负号关系是确定的。)

常见错误与注意事项
-
比较未初始化的指针:传递一个未初始化的指针给
strcmp()会导致未定义行为,通常是程序崩溃(段错误)。char *s1; // 危险!s1 指向未知内存 char *s2 = "hello"; strcmp(s1, s2); // 崩溃!
-
忘记
#include <string.h>:如果你不包含头文件,编译器可能不知道strcmp的存在,导致编译错误。 -
与 混淆:这是初学者最常犯的错误。 用于比较两个指针是否指向同一个内存地址,而不是比较指针指向的字符串内容是否相同。
char s1[] = "hello"; char s2[] = "hello"; if (s1 == s2) { // 错误!比较的是数组地址,几乎总是 false printf("s1 and s2 are the same address.\n"); } if (strcmp(s1, s2) == 0) { // 正确!比较的是字符串内容 printf("s1 and s2 have the same content.\n"); } -
不检查返回值:直接使用
strcmp()而不检查其返回值,if (strcmp(s1, s2)),这在逻辑上是错误的,因为如果字符串相等,它会返回0,if(0)为假,条件不成立,正确的写法是if (strcmp(s1, s2) == 0)。
相关函数
strcmp() 还有一些变体,用于处理大小写不敏感的比较:
-
strcasecmp()(非标准,但在 Linux/Unix 上常见) 或strcmpi()(在 Windows 上常见):这两个函数的比较是不区分大小写的。strcmp("Hello", "hello")会返回非零值,而strcasecmp("Hello", "hello")会返回0。 -
strncmp():这个函数增加了一个size_t n参数,表示最多只比较前n个字符,这在只需要比较字符串开头部分时非常有用,可以提高效率并避免因字符串过长而进行不必要的比较。// 只比较前 3 个字符 strncmp("apple", "application", 3); // 返回 0,因为 "app" == "app"
| 函数 | 功能 | 头文件 | 返回值 |
|---|---|---|---|
strcmp() |
区分大小写的字符串比较 | <string.h> |
<0, 0, >0 |
strcasecmp() / strcmpi() |
不区分大小写的字符串比较 | <strings.h> (Linux) / <string.h> (Windows) |
<0, 0, >0 |
strncmp() |
最多比较前 n 个字符 |
<string.h> |
<0, 0, >0 |
strcmp() 的核心:按字典序逐个字符比较,返回一个表示大小关系的整数,在 C 语言中进行字符串比较时,它是最基本、最重要的工具之一。
