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

C語言輸出整數每一位數字:三種經典演算法對比

     編輯:關於C語言

C語言輸出整數每一位數字:三種經典演算法對比

將整數分解為個別位數字(如 12345 → 1 2 3 4 5)是基礎位運算練習。本文對比三種經典方法:取模存陣列再反轉、遞迴分解、字串轉換,分析各自優缺點、適用場景與邊界處理。

方法一:取模存陣列 + 反轉(最通用)

#include <stdio.h>

void printDigitsArray(int num) {
    if (num == 0) { printf("0 "); return; }

    int digits[20];  // 足夠容納 64 位整數
    int count = 0;

    // 處理負數
    bool negative = false;
    if (num < 0) {
        negative = true;
        num = -num;  // 注意 INT_MIN 絕對值溢位問題
    }

    // 從低位到高位取出
    while (num > 0) {
        digits[count++] = num % 10;
        num /= 10;
    }

    // 輸出負號
    if (negative) printf("- ");

    // 反序輸出(高位到低位)
    for (int i = count - 1; i >= 0; i--) {
        printf("%d ", digits[i]);
    }
    printf("\n");
}

方法二:遞迴分解(最優雅)

#include <stdio.h>

void printDigitsRecursive(int num) {
    if (num < 0) {
        putchar('-');
        putchar(' ');
        num = -num;  // 同上溢位風險
    }
    if (num >= 10) {
        printDigitsRecursive(num / 10);
    }
    printf("%d ", num % 10);
}

// 使用範例
int main() {
    int n = 12345;
    printDigitsRecursive(n);  // 輸出: 1 2 3 4 5
    printf("\n");
    return 0;
}

方法三:轉字串處理(最簡潔)

#include <stdio.h>

void printDigitsString(int num) {
    char buf[32];
    int len = snprintf(buf, sizeof(buf), "%d", num);
    for (int i = 0; i < len; i++) {
        if (buf[i] == '-') printf("- ");
        else printf("%c ", buf[i]);
    }
    printf("\n");
}

三方法詳細比較

維度陣列+反轉遞迴字串轉換
時間複雜度O(log₁₀ n)O(log₁₀ n)O(log₁₀ n)
空間複雜度O(log₁₀ n) 陣列O(log₁₀ n) 呼叫棧O(log₁₀ n) 緩衝區
可讀性中高最高
負數處理需額外邏輯需額外邏輯自動處理
INT_MIN 問題需特殊處理需特殊處理無問題
適用場景需進一步處理位數(如統計、修改)教學展示、簡單輸出快速除錯、日誌輸出
執行效率最快函數呼叫開銷格式化解析較慢

INT_MIN 邊界陷阱與解決

// INT_MIN = -2147483648,絕對值 2147483648 超過 INT_MAX (2147483647)
// 直接 -num 會導致未定義行為(有號整數溢位)

// 解決方案 1:使用長整型
long long val = num;
if (val < 0) val = -val;

// 解決方案 2:無號轉換
unsigned int uval = (num < 0) ? (unsigned int)(-num) : (unsigned int)num;
// 注意:-INT_MIN 在無號下定義為 2147483648U

// 解決方案 3:字串法天然免疫
snprintf(buf, sizeof(buf), "%d", INT_MIN);  // 正確產生 "-2147483648"

進階應用:位數統計與操作

// 統計各數字出現次數
void countDigits(int num, int count[10]) {
    if (num == 0) { count[0]++; return; }
    if (num < 0) num = -num;  // 處理負數
    while (num) {
        count[num % 10]++;
        num /= 10;
    }
}

// 反轉整數(LeetCode 7)
int reverseInt(int x) {
    long long rev = 0;
    while (x) {
        rev = rev * 10 + x % 10;
        x /= 10;
    }
    return (rev > INT_MAX || rev < INT_MIN) ? 0 : (int)rev;
}

// 回文數判斷
bool isPalindrome(int x) {
    if (x < 0) return false;
    int original = x, reversed = 0;
    while (x) {
        reversed = reversed * 10 + x % 10;
        x /= 10;
    }
    return original == reversed;
}

教學建議

  1. 初學者:先掌握「取模+除法」核心邏輯,理解位權展開。
  2. 進階者:實作遞迴版體會呼叫棧機制,嘗試處理 INT_MIN 邊界。
  3. 實務開發:優先使用 snprintf 字串法,正確、簡潔、免邊界煩惱。
  4. 面試準備:熟練手寫三種版本,並能說明各自優缺點與適用場景。

分解整數位數看似微不足道,實則蘊含進制轉換、邊界條件、遞迴與迭代轉換、字串格式化等核心概念。徹底掌握這三種方法,能舉一反三解決反轉整數、回文判斷、位數統計、大數加法等進階問題。

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