字符串逆序是經典的面試題與基礎算法練習。本文介紹「雙指針交換法」,在原數組上直接操作,空間複雜度 O(1),時間複雜度 O(n),是最高效的原地反轉方案。
start 指向字符串首地址,end 指向最後一個有效字符(即 start + len - 1)。start < end 時,交換兩指針指向的字符,start++,end--。#include <stdio.h>
#include <string.h>
#include <assert.h>
char *my_reverse(char *str) {
assert(str != NULL);
char *start = str;
char *end = str + strlen(str) - 1; // 指向最後一個字符
char tmp;
while (start < end) {
tmp = *start;
*start = *end;
*end = tmp;
start++;
end--;
}
return str; // 返回原指針,支持鏈式調用
}
int main(void) {
char arr[] = "abcdef"; // 必須用數組,不能用字符串常量指針
printf("原字符串: %s\n", arr);
my_reverse(arr);
printf("逆序後: %s\n", arr); // 輸出 fedcba
return 0;
}
char * 且指向可修改的內存(如棧上數組),不能傳入字符串字面量(如 char *p = "abc";),因為字面量通常存放在只讀段,寫入會導致段錯誤。strlen 計算長度,也可手寫循環計算,避免重複造輪子。char tmp 暫存,不可用 int 等大類型,否則可能越界寫入相鄰內存。start < end 而非 start != end,前者在偶數長度時正確停止,後者可能導致指針交錯多交換一次。雖不適合生產環境(棧開銷大),但能體現遞歸思想:
void reverse_recursive(char *start, char *end) {
if (start >= end) return;
char tmp = *start;
*start = *end;
*end = tmp;
reverse_recursive(start + 1, end - 1);
}
雙指針原地反轉是字符串操作的基石,掌握它有助於理解數組、指針、內存佈局。實際開發中,若需頻繁反轉,可考慮預分配緩衝區或使用標準庫算法(C++ std::reverse)。