最安全做法是先检查字符串长度是否大于1,再用std::swap交换首尾字符;空串或单字符无需操作,手动赋值需防范无符号整数回绕导致的越界访问。

用 std::swap 直接交换首尾字符最安全
只要字符串非空,std::swap 就能原地交换 s[0] 和 s[s.size()-1],不涉及内存重分配或越界风险。注意必须检查长度,否则空串或单字符串会触发未定义行为。
- 空字符串(
s.empty())直接返回,不操作 - 单字符字符串(
s.size() == 1)也无需交换,但std::swap(s[0], s[0])是合法的,不影响结果 - 推荐写法:
if (s.size() > 1) std::swap(s[0], s[s.size()-1]);
手动赋值时别忘了边界判断
有人习惯用临时变量赋值:char t = s[0]; s[0] = s[n-1]; s[n-1] = t;,逻辑没错,但若忘记 n > 1 判断,s[n-1] 在 n == 0 时就是 s[-1] —— 这是未定义行为,可能崩溃或静默出错。
- 错误示例:
size_t n = s.length(); char t = s[0]; s[0] = s[n-1];——s为空时n是 0,n-1变成极大正数(无符号回绕),访问非法地址 - 正确做法:先转为有符号整型判断,或直接用
s.size() > 1 - 更稳妥的写法:
if (!s.empty()) { size_t i = 0, j = s.size() - 1; if (i
使用 std::string::at() 会抛异常但适合调试
s.at(0) 和 s.at(s.size()-1) 在越界时抛 std::out_of_range,比静默越界更容易暴露问题,适合开发阶段验证逻辑。但线上性能敏感场景应避免,因为异常开销大,且本操作本就不该越界。
- 仅建议在单元测试或断言中使用:
assert(!s.empty()); s.at(0) = s.at(s.size()-1); // 至少保证不崩
- 生产代码中仍推荐
operator[]+ 显式长度检查,零开销且意图清晰
别对字面量字符串或 const 字符串调用此操作
const char* s = "hello"; 或 const std::string& s 无法修改,强行取地址交换会编译失败或运行时报错(如段错误)。必须确保目标是可修改的 std::string 对象。
- 错误:
std::swap("abc"[0], "abc"[2]);—— 字面量不可修改,编译不过 - 错误:
const std::string cs = "test"; std::swap(cs[0], cs[3]);——cs[0]返回char值而非引用,无法作为std::swap左值参数 - 正确前提:变量声明为
std::string s = ...;,非const
实际写的时候最容易漏掉空串检查,尤其当字符串来自用户输入或文件读取时,s.size() 可能为 0 —— 这个边界条件不处理,轻则结果错乱,重则程序崩溃。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











