std::reverse 是最直接可靠的选择,需传入合法迭代器范围,正确写法为 arr + n(开区间右端),手写循环需确保边界安全且仅运行 n/2 次。

用 std::reverse 最直接可靠
绝大多数情况下,直接调用 std::reverse 是最安全、最简洁的选择。它专为这种需求设计,底层优化充分,且不依赖数组是否在栈上或堆上(只要传入合法迭代器范围)。
常见错误是传错迭代器边界:比如对长度为 n 的数组写成 std::reverse(arr, arr + n - 1),这会漏掉最后一个元素——正确写法必须是 arr + n(开区间右端)。
- 对栈数组:
int arr[5] = {1,2,3,4,5}; std::reverse(arr, arr + 5); - 对
std::vector:std::reverse(vec.begin(), vec.end()); - 对动态分配数组(需确保有长度信息):
int* ptr = new int[3]{1,2,3}; std::reverse(ptr, ptr + 3);
手写循环交换要注意索引边界
手动实现能加深理解,但容易在边界条件上出错,尤其当数组长度为 0 或 1 时未做保护,可能触发未定义行为。
核心逻辑是交换 i 和 n-1-i,循环只需运行 n/2 次(整除向下取整),无需额外判断奇偶。
立即学习“C++免费学习笔记(深入)”;
- 错误写法:
for (int i = 0; i → 会重复翻转,结果变回原样 - 正确写法:
for (int i = 0; i - 如果不用
std::swap,务必用临时变量,避免自赋值陷阱(如a ^= b; b ^= a;在a和b指向同一地址时崩溃)
字符串字面量不能逆序
初学者常试图对字符串字面量(如 "hello")调用 std::reverse,这会导致段错误。因为字面量存储在只读内存段,任何修改都是非法的。
- 错误:
char* s = "abc"; std::reverse(s, s + 3);→ 运行时报Segmentation fault - 正确:先复制到可写内存,例如
char s[] = "abc";(栈数组)或std::string s = "abc"; - 若必须用指针,应分配堆内存:
char* s = new char[4]{"abc"}; std::reverse(s, s + 3); delete[] s;
std::array 和 std::vector 的差异点
虽然都能用 std::reverse,但两者的使用习惯和性能影响不同:前者大小编译期固定,begin()/end() 是 constexpr;后者涉及运行时长度查询,但实际开销可忽略。
-
std::array推荐用arr.begin()和arr.end(),语义清晰且类型安全 -
std::vector同理,但注意不要误用vec.data()配合vec.size()—— 虽然可行,但不如迭代器惯用法自然 - 若容器含非平凡类型(如含构造/析构函数的对象),
std::reverse会调用其移动或拷贝操作,性能取决于该类型的开销
真正容易被忽略的是:逆序操作本身不改变数组/容器的大小或内存布局,但它会影响后续所有依赖顺序的逻辑(比如二分查找前忘了排序,或把逆序后的数组当成升序用了)。动手前确认“逆序”确实是业务需要,而不是误解了算法前提。


















