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

C 語言指標實作字串反轉:三種經典演算法與記憶體視覺化

     編輯:關於C語言

一、問題描述

輸入一字串,輸出原字串與反轉後字串。要求使用字元指標操作,不使用陣列下標 []。

二、演算法 1:雙指標原地交換 (最常用、O(1) 空間)

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 (交會停止)

三、演算法 2:雙緩衝區複製 (教學用、保留原字串)

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';
}

四、演算法 3:遞迴反轉 (展示指標運算、堆疊空間 O(n))

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

七、常見錯誤避坑

  1. 未處理空字串:strlen("")-1 變 SIZE_MAX (無號下溢),導致指標亂跳。必須檢查 if (!*str) return;。
  2. 修改字串常值:char *s = "hello"; reverse_inplace(s); → 崩潰。必須用陣列 char s[] = "hello"; 或 malloc。
  3. 忘記結束符:複製法必須手動加 *dst = '\0'。
  4. 遞迴深度過大:超長字串導致堆疊溢位,生產環境禁用遞迴版。
  5. 緩衝區溢位:fgets 限制長度,strcpy 確保目的足夠大。

八、效能對比

  • 原地交換:最快、最省記憶體、破壞原資料。
  • 複製法:需額外 O(n) 空間、保留原字串、適合不可變字串。
  • 遞迴:教學展示指標運算、堆疊開銷大、非尾遞迴無法優化。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved