將字串 `"tneduts a ma i"` 原地反轉為 `"i am a student"`,限制:只能使用有限額外空間(O(1) 空間複雜度)。
void my_reverse(int len, char arr[]) {
int left = 0;
int right = len - 1;
while (left < right) {
char tmp = arr[left];
arr[left] = arr[right];
arr[right] = tmp;
left++;
right--;
}
}
#includevoid my_reverse(int len, char arr[]) { int left = 0, right = len - 1; while (left < right) { char tmp = arr[left]; arr[left] = arr[right]; arr[right] = tmp; left++; right--; } } int main() { char arr[] = "tneduts a ma i"; // 關鍵:sizeof 包含結束符 \0,strlen 不包含 int len = sizeof(arr) / sizeof(arr[0]) - 1; // 扣除 \0 my_reverse(len, arr); printf("%s\n", arr); // 輸出: i am a student return 0; }
| 特性 | sizeof(arr) | strlen(arr) |
|---|---|---|
| 計算時機 | 編譯期(陣列) | 執行期 |
| 包含 \0 | 是 | 否 |
| 參數類型 | 陣列/型別/變數 | 字串指標 (char*) |
| 退化為指標 | 否(陣列參數除外) | 是 |
| 回傳型別 | size_t (位元組數) | size_t (字元數) |
char str[] = "hello";
printf("%zu\n", sizeof(str)); // 6 (含 \0)
printf("%zu\n", strlen(str)); // 5
char *p = str;
printf("%zu\n", sizeof(p)); // 8 (指標大小,64位元系統)
printf("%zu\n", strlen(p)); // 5
因為陣列以指標形式傳遞,函式直接修改原始陣列內容(原地操作),無需回傳新指標。呼叫端陣列已被修改。
// 通用版:自動計算長度
void reverse_string(char *str) {
if (!str) return;
char *end = str;
while (*end) end++; // 移至 \0
end--; // 移至最後一字元
while (str < end) {
char tmp = *str;
*str++ = *end;
*end-- = tmp;
}
}
字串原地反轉是指標操作基本功。**雙指標向中間收斂**是標準解法。關鍵細節在於正確計算有效長度(扣除 `\0`),且理解 `sizeof` 與 `strlen` 的本質差異,避免在函式參數退化為指標時誤用 `sizeof`。