輸入一字串,輸出原字串與反轉後字串。要求使用字元指標操作,不使用陣列下標 []。
void reverse_inplace(char *str) {
if (!str) return;
char *left = str;
char *right = str + strlen(str) - 1; // 指向最後一個有效字元
while (left < right) {
char tmp = *left;
*left++ = *right;
*right-- = tmp;
}
}
記憶體視覺化:
初始: H e l l o \0
↑ ↑
left right
交換後: o e l l H \0
↑ ↑
left right
完成: o l l e H \0
↑ ↑
left right (交會停止)
void reverse_copy(const char *src, char *dst) {
if (!src || !dst) return;
const char *p = src + strlen(src) - 1; // 來源尾端
while (p >= src) {
*dst++ = *p--; // 從尾複製到頭
}
*dst = '\0';
}
void reverse_recursive(char *left, char *right) {
if (left >= right) return;
char tmp = *left;
*left = *right;
*right = tmp;
reverse_recursive(left + 1, right - 1);
}
// 呼叫入口
void reverse_rec(char *str) {
if (!str) return;
reverse_recursive(str, str + strlen(str) - 1);
}
#include#include #define MAX_LEN 1024 void reverse_inplace(char *str); void reverse_copy(const char *src, char *dst); void reverse_recursive(char *left, char *right); int main() { char input[MAX_LEN] = {0}; char copy[MAX_LEN] = {0}; printf("請輸入字串: "); if (!fgets(input, MAX_LEN, stdin)) return 1; // 移除 fgets 讀入的換行符 input[strcspn(input, "\n")] = '\0'; printf("原字串: %s\n", input); // 方法 1: 原地反轉 strcpy(copy, input); reverse_inplace(copy); printf("原地反轉: %s\n", copy); // 方法 2: 複製反轉 reverse_copy(input, copy); printf("複製反轉: %s\n", copy); // 方法 3: 遞迴反轉 strcpy(copy, input); reverse_recursive(copy, copy + strlen(copy) - 1); printf("遞迴反轉: %s\n", copy); return 0; }
| 運算 | 含義 | 範例 |
|---|---|---|
p++ | 後置遞增,回傳舊值,指標移向下一個 char | *dst++ = *src++ |
++p | 前置遞增,指標先移動,回傳新值 | *++p = 'x' |
p + n | 指標加整數,位移 n 個元素大小 | str + len - 1 |
p - q | 同陣列指標相減,得元素數差 (ptrdiff_t) | right - left |
*p | 解參考,存取指向的字元 | tmp = *left |
strlen("")-1 變 SIZE_MAX (無號下溢),導致指標亂跳。必須檢查 if (!*str) return;。char *s = "hello"; reverse_inplace(s); → 崩潰。必須用陣列 char s[] = "hello"; 或 malloc。*dst = '\0'。fgets 限制長度,strcpy 確保目的足夠大。