首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

C 語言遞迴列印字串逆序:參數遞增順序導致輸出缺字元

     編輯:程式設計疑難解答

問題代碼

void prints(char *p) {
    if (*p != '\0') prints(++p);  // 先遞增指標
    if (*p != '\0') printf("%c", *p); // 再列印 -> 跳過第一個字元
}

int main() {
    char p[] = "hello";
    prints(p); // 輸出 "olle" 少了 'h'
}

錯誤分析

  1. 呼叫 prints("hello")
  2. ++p 使指標指向 'e'
  3. 遞迴處理 "ello" → "llo" → "lo" → "o" → ""
  4. 回溯時列印:'o'、'l'、'l'、'e'
  5. 原始 'h' 從未被列印,因為第一次遞迴前就已 ++p

修正版:先列印再遞迴

void prints(char *p) {
    if (*p != '\0') {
        printf("%c", *p);  // 先列印當前字元
        prints(p + 1);     // 再遞迴處理下一個 (用 p+1 而非 ++p 避免副作用)
    }
}

// 或更簡潔
void prints(char *p) {
    if (*p) {
        putchar(*p);
        prints(p + 1);
    }
}

執行流程對比

步驟錯誤版 (++p 先行)正確版 (列印先行)
1p→'h',++p→'e',遞迴p→'h',列印'h',遞迴 p+1
2p→'e',++p→'l',遞迴p→'e',列印'e',遞迴 p+1
.........
回溯列印o, l, l, eh, e, l, l, o

進階:尾端遞迴優化 (編譯器支援時)

// 尾端遞迴:遞迴呼叫為最後動作
void prints_tail(char *p, char *end) {
    if (p < end) {
        putchar(*p);
        prints_tail(p + 1, end); // GCC -O2 可優化為迴圈
    }
}

// 呼叫
prints_tail(str, str + strlen(str));

遞迴 vs 迴圈效能對比

  • 遞迴:程式碼簡潔,但佔用堆疊空間,長字串可能堆疊溢位
  • 迴圈:while (*p) putchar(*p++); 效能最佳,無堆疊風險
  • 教學用途:遞迴展示分治思維;生產環境優先迴圈
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved