strcmp比较字符串内容,返回0表示相等;==比较指针地址,即使内容相同也可能为假。

strcmp 与 == 比较字符串指针,结果完全不同
直接用 == 比较两个 char* 变量,比的是地址值,不是内容。哪怕两个指针指向内容完全相同的字符串字面量(如 "hello"),只要它们地址不同,== 就返回 false。
而 strcmp 是逐字符比对内容,直到遇到 '\0';只有内容完全一致才返回 0。
-
char* a = "test"; char* b = "test";:在多数编译器中,a == b可能为true(字符串字面量合并优化),但这不可靠、不 portable -
char a[] = "test"; char b[] = "test"; char* p1 = a; char* p2 = b;:此时p1 == p2一定为false,但strcmp(p1, p2)返回0 - 若指针为空(
nullptr),strcmp(p1, p2)会崩溃;==则安全(但逻辑无意义)
std::string::operator== 和 strcmp 的语义差异
std::string 的 == 是重载运算符,它内部做的是内容比较,等价于调用 compare(),不是地址比较。这和 C 风格的 char* 完全不同。
-
std::string s1 = "abc"; std::string s2 = "abc";→s1 == s2为true,且安全(自动处理空串、长度) -
std::string s = "abc"; const char* c = "abc";→s == c合法(隐式转换const char*为std::string),但c == s同样合法;而strcmp(c, s.c_str())才是纯 C 风格写法 -
std::string的比较支持短路(如长度不等直接返回),strcmp总是遍历到第一个差异或结尾
指针比较常被误用于判断字符串相等
新手容易把 char* 当成“字符串对象”,以为 == 能判断文本是否相同。实际它只是两个内存地址的整数比较。
- 函数返回临时字符串字面量(如
const char* get_name() { return "Alice"; }),多次调用可能返回相同地址,也可能不同(取决于编译器和优化) - 堆上分配的字符串(
new char[10])每次地址都不同,==必然失败 - 用
std::string替代裸指针可彻底规避这类误用;若必须用char*,一律用strcmp或std::string_view(C++17)
strcmp 的陷阱:空指针和编码假设
strcmp 不检查参数是否为空,传入 nullptr 直接导致未定义行为(多半 crash)。它也默认操作的是以 '\0' 结尾的、单字节编码(如 ASCII / UTF-8)字符串。
- 若字符串未正确以
'\0'结尾(比如忘了strcpy后补'\0'),strcmp会越界读取,行为不可控 - 宽字符(
wchar_t*)不能用strcmp,得用wcscmp - UTF-8 字符串中含多字节字符时,
strcmp仍能按字节比对(因为 UTF-8 兼容 ASCII 排序),但语义上不等于“Unicode 字典序”——需要std::locale或 ICU 库
真正容易被忽略的点是:C 风格字符串没有“值语义”。一个 char* 只是地址标签,它不携带长度、不管理内存、不保证有效性。所有基于它的操作(包括比较)都建立在程序员手动维护这些前提之上。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











