使用字符数组判断回文需手动处理边界,核心是双指针从两端向中间比对;必须确保数组以'\0'结尾,否则strlen会越界导致未定义行为。

用 std::string 比字符数组更安全,但真要用字符数组就得手动处理边界
直接判断字符数组是否为回文,核心是双指针从两端向中间比对。但 C++ 中字符数组(如 char arr[100])没有内置长度信息,必须确保它以 '\0' 结尾,否则 strlen 会越界读取,导致未定义行为。
常见错误:传入未初始化或未正确结尾的数组,比如:
char s[5] = {'a', 'b', 'b', 'a'}; // 缺少 '\0',strlen 可能崩溃或返回错误长度
- 务必用
std::cin >> s或std::fgets(s, size, stdin)输入,它们会自动补'\0' - 若手动赋值,末尾必须显式写
s[n] = '\0'; - 用
strlen(s)获取有效长度,别依赖数组声明大小
strcmp 不能直接判断回文,得自己写比对逻辑
strcmp 是比较两个字符串是否相等,不是检查单个字符串是否对称。想用标准库“偷懒”,只能把原数组翻转后比较——但这反而更慢、更易出错(需额外空间和复制开销)。
推荐手写双指针,简洁且无额外分配:
bool isPalindrome(char s[]) {
int len = strlen(s);
for (int i = 0; i
- 循环只到
len / 2,避免重复比对和中间字符自比 - 索引
len - 1 - i确保右端从最后一个有效字符开始(len-1是'\0'前一位) - 不区分大小写?那就用
tolower(s[i]) != tolower(s[len-1-i])
遇到中文或 UTF-8 多字节字符,char 数组方案直接失效
C++ 原生 char 数组按字节操作,而 UTF-8 中一个汉字占 3 字节。此时 s[i] 可能截断某个汉字的中间字节,导致比对完全错乱,甚至触发非法字节序列错误。
- 纯 ASCII 文本(英文、数字、基本符号)可安全使用上述方法
- 含中文、emoji 或其他 Unicode 字符,必须改用
std::u8string(C++20)或第三方库(如 ICU)做 Unicode 码点级处理 - 临时 workaround:用
std::string存原始 UTF-8 字节流,但回文判断仍需先转码为 Unicode 序列,不能直接下标访问
用 std::string 替代字符数组几乎总是更好的选择
除非在嵌入式环境或有严格内存约束,否则没必要硬扛 char[]。std::string 自带长度、自动管理内存、支持迭代器,回文判断更直观:
bool isPalindrome(const std::string& s) {
int l = 0, r = s.length() - 1;
while (l
- 无需担心
'\0'、无需调用strlen、不会因未初始化数组而崩溃 - 如果要忽略空格和标点,用
std::isalnum和std::tolower跳过非字母数字字符 - 真正要注意的是:
std::string的operator[]不做越界检查,但.at()会抛异常,调试阶段可临时替换验证逻辑
回文判断本身很简单,难的是搞清输入来源是否可靠、字符编码是否干净、以及你到底要不要为“看起来省一点内存”付出维护成本。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











