回文字串(Palindrome)是指正反讀都相同的字串,例如 "level"、"madam" 或 "abcba"。判斷回文是經典的程式設計練習,特別適合鍛鍊指標操作。本文將展示 C 與 C++ 兩種版本的實作,並深入解析指標在其中的關鍵作用。
判斷回文最直觀的方法是「雙指標法」:一個指標指向字串開頭,另一個指向結尾,向中間移動並逐一比對字元。若所有對應字元都相等,則為回文。
在 C 語言中,我們先將輸入字元存入字元陣列,再使用整數索引或指標進行比對。
#include <stdio.h>
#include <string.h>
int main() {
char str[100];
char ch;
int len = 0;
// 讀取一行輸入(不含換行符)
while ((ch = getchar()) != '\n' && len < 99) {
str[len++] = ch;
}
str[len] = '\0'; // 結束字串
// 雙指標比對
char *left = str;
char *right = str + len - 1;
int is_palindrome = 1;
while (left < right) {
if (*left != *right) {
is_palindrome = 0;
break;
}
left++;
right--;
}
printf("%s\n", is_palindrome ? "是回文" : "不是回文");
return 0;
}
關鍵點: `getchar()` 逐字元讀取,`left` 和 `right` 指標分別指向首尾,移動時只需遞增/遞減指標地址,無需索引運算,體現指標操作的高效與直觀。
C++ 允許直接用指標指向字串字面值,並配合 `strlen` 取得長度,程式碼更簡潔。
#include <iostream>
#include <cstring>
using namespace std;
int main() {
const char *p = "abcba"; // 指向字串常量
int n = strlen(p);
bool flag = true;
for (int i = 0; i < n / 2; ++i) {
if (p[i] != p[n - 1 - i]) {
flag = false;
break;
}
}
cout << (flag ? "是回文" : "不是回文") << endl;
return 0;
}
此處 `p[i]` 等價於 `*(p + i)`,展示了指標算術與陣列下標的等價性。
為了複用,可將判斷邏輯封裝為獨立函數,接受 `char*` 參數,返回狀態碼。
#include <stdio.h>
#include <string.h>
int is_palindrome(const char *p) {
if (p == NULL) return -1; // 防禦性程式設計
int n = strlen(p);
for (int i = 0; i < n / 2; ++i) {
if (p[i] != p[n - 1 - i]) return 0;
}
return 1;
}
int main() {
char buf[100];
fgets(buf, sizeof(buf), stdin);
buf[strcspn(buf, "\n")] = '\0'; // 移除換行符
int ret = is_palindrome(buf);
if (ret == 1) puts("是回文");
else if (ret == 0) puts("不是回文");
else puts("輸入錯誤");
return 0;
}
函數參數用 `const char*` 表明不修改字串內容,返回 `int` 以便區分「非回文」與「參數錯誤」。
掌握雙指標法不僅能解決回文問題,更是處理陣列、鏈表等線性結構「對撞/雙指針」技巧的基礎。