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

C 語言進制轉換代碼修復:遞歸輸出邏輯與次方計算優化

     編輯:程式設計綜合問答

原代碼問題

  1. printoutevery 中 if(k=0) 是賦值而非判斷,應為 if(k < 0) 或 if(k == 0) (配合遞歸終止條件)。
  2. 查找數字 a 的循環邏輯錯誤:if(num < pow(i, k)) 應為 pow(i, a),且循環變量混淆。
  3. 重複調用 pow() 性能低且精度問題 (浮點轉整型)。
  4. 未處理負數輸入。

修正後的遞歸實現


#include 
#include 

// 遞歸輸出每一位
void printDigit(int num, int base, int pos) {
    if (pos < 0) return; // 終止條件:位數耗盡
    
    // 計算當前位權值 base^pos (用整數避免浮點誤差)
    int power = 1;
    for (int i = 0; i < pos; i++) power *= base;
    
    int digit = num / power;     // 當前位數值
    num -= digit * power;        // 剩餘數值
    
    // 輸出字符
    if (digit < 10) putchar('0' + digit);
    else putchar('A' + digit - 10); // 10->A, 15->F 等
    
    // 遞歸下一位
    printDigit(num, base, pos - 1);
}

// 計算最高位位置 (最高次方數)
int highestPosition(int num, int base) {
    if (num == 0) return 0;
    int pos = 0;
    int value = 1;
    while (value <= num / base) { // 防止溢出
        value *= base;
        pos++;
    }
    return pos;
}

int main() {
    int num, base;
    printf("輸入十進制整數: ");
    scanf("%d", &num);
    printf("輸入目標進制 (2-36): ");
    scanf("%d", &base);
    
    if (base < 2 || base > 36) {
        printf("進制範圍 2-36\n");
        return 1;
    }
    
    if (num < 0) {
        putchar('-');
        num = -num; // 注意 INT_MIN 絕對值溢出,簡化處理
    }
    
    if (num == 0) {
        putchar('0');
    } else {
        int pos = highestPosition(num, base);
        printDigit(num, base, pos);
    }
    putchar('\n');
    return 0;
}

關鍵修復點

原代碼修正說明
if(k=0)if(pos < 0)遞歸終止條件,防止無限遞歸
循環查找 a 用 pow(i, k)預計算 power = base^pos,用整數除法
浮點 pow() 轉整型整數乘法累積 power
無負數處理輸出 '-' 後取絕對值
進制限制檢查 2-36 範圍

非遞歸迭代版 (更推薦,無棧溢出風險)


void printBaseIterative(int num, int base) {
    if (num == 0) { putchar('0'); return; }
    if (num < 0) { putchar('-'); num = -num; }
    
    char buf[64]; // 足夠 64 位整數任意進制
    int idx = 0;
    while (num > 0) {
        int digit = num % base;
        buf[idx++] = (digit < 10) ? '0' + digit : 'A' + digit - 10;
        num /= base;
    }
    // 逆序輸出
    while (idx > 0) putchar(buf[--idx]);
}

標準庫函數 (生產代碼直接用)


// itoa 非標準但廣泛可用
char buf[33];
itoa(num, buf, base); // base 2-36
printf("%s\n", buf);

// sprintf 格式化 (僅 8, 10, 16 進制)
printf("%x\n", num); // 16進制
printf("%o\n", num); // 8進制

總結

進制轉換核心:**反覆取模 (得當前位) + 除以基數 (得剩餘數)**,逆序輸出。遞歸易理解但迭代更健壯。生產代碼優先用標準庫 itoa / sprintf / C++ std::bitset / std::format (C++20)。

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