首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

C語言字串反轉:原地逆置演算法與 sizeof vs strlen 關鍵差異

     編輯:關於C

題目需求

將字串 `"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--;
    }
}

完整程式碼

#include 

void 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 vs strlen 深度解析

特性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` 回傳?

因為陣列以指標形式傳遞,函式直接修改原始陣列內容(原地操作),無需回傳新指標。呼叫端陣列已被修改。

進階:標準庫 strrev / 手寫通用版

// 通用版:自動計算長度
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;
    }
}

常見錯誤

  1. 用 `sizeof(arr)` 直接當長度 → 多複製 `\0` 導致字串提早結束。
  2. 迴圈條件 `left <= right` → 中間字元自我交換(無害但多餘)。
  3. 未處理 `NULL` 或空字串輸入。
  4. 字串常值 `char *s = "abc"; reverse(s);` → 崩潰(唯讀記憶體)。

總結

字串原地反轉是指標操作基本功。**雙指標向中間收斂**是標準解法。關鍵細節在於正確計算有效長度(扣除 `\0`),且理解 `sizeof` 與 `strlen` 的本質差異,避免在函式參數退化為指標時誤用 `sizeof`。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved