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

C 語言型別轉換函式實作:atoi、itoa、atof 手寫核心邏輯全解析

     編輯:關於C

前言

標準庫 <stdlib.h> 提供 atoi、itoa (非標準但常見)、atof 等轉換函式。理解其底層實作邏輯,不僅能應付面試手寫題,更能深入掌握字串解析、數值累積、邊界處理等核心程式設計技巧。本文提供三個函式的完整實作碼與逐行解析。

一、字串轉整數 atoi

int atoi(char s[]) {
    int i, n, sign;
    
    // 1. 跳過前導空白
    for (i = 0; isspace(s[i]); i++);
    
    // 2. 處理正負號
    sign = (s[i] == '-') ? -1 : 1;
    if (s[i] == '+' || s[i] == '-') i++;
    
    // 3. 累積數值 (ASCII '0' = 48)
    for (n = 0; isdigit(s[i]); i++)
        n = n * 10 + (s[i] - '0');
    
    return sign * n;
}

關鍵點解析

  • isspace 處理空白、Tab、換行等。
  • s[i] - '0' 將字元數字轉為整數值 (如 '5' - '0' = 5)。
  • n = n * 10 + digit 是經典的「左移累積」演算法。
  • 缺陷:無溢位檢查、無錯誤回報機制 (標準庫版本行為未定義)。

二、整數轉字串 itoa


void reverse(char s[]) {
    int c, i, j;
    for (i = 0, j = strlen(s) - 1; i < j; i++, j--) {
        c = s[i]; s[i] = s[j]; s[j] = c;
    }
}

void itoa(int n, char s[]) {
    int i, sign;
    
    // 1. 記錄正負號,轉為正數處理
    if ((sign = n) < 0) n = -n;
    
    // 2. 從個位數開始產生字元 (逆序)
    i = 0;
    do {
        s[i++] = n % 10 + '0';
    } while ((n /= 10) > 0);
    
    // 3. 補上負號
    if (sign < 0) s[i++] = '-';
    
    s[i] = '\0';
    
    // 4. 反轉字串得到正確順序
    reverse(s);
}

設計巧思

  1. 使用 do-while 確保 n=0 也能產生 "0"。
  2. 先生成逆序字串,最後 reverse() 一次完成,避免複雜的索引計算。
  3. reverse 採雙指標對調,空間 O(1),時間 O(n)。

三、字串轉浮點數 atof


double atof(char s[]) {
    double val, power;
    int i, sign;
    
    // 1. 跳過空白
    for (i = 0; isspace(s[i]); i++);
    
    // 2. 正負號
    sign = (s[i] == '-') ? -1 : 1;
    if (s[i] == '+' || s[i] == '-') i++;
    
    // 3. 整數部分累積
    for (val = 0.0; isdigit(s[i]); i++)
        val = val * 10.0 + (s[i] - '0');
    
    // 4. 小數點處理
    if (s[i] == '.') i++;
    
    // 5. 小數部分累積,同時計算 10 的冪次
    for (power = 1.0; isdigit(s[i]); i++) {
        val = val * 10.0 + (s[i] - '0');
        power *= 10.0;
    }
    
    return sign * val / power;
}

邏輯流程圖解

輸入: "  -123.45  "
步驟1: i 跳過空白 → 指向 '-'
步驟2: sign = -1, i 指向 '1'
步驟3: val 累積 1→12→123
步驟4: 遇到 '.', i++
步驟5: val 累積 1234→12345, power 累積 10→100
結果: -1 * 12345 / 100 = -123.45

四、實作比較與擴充建議

函式標準庫手寫版優缺點生產環境建議
atoistdlib.h簡單但無錯誤處理用 strtol (可檢測錯誤、支援進制)
itoa非標準邏輯清晰、教學價值高用 snprintf (安全、標準)
atofstdlib.h不支援科學記號、無錯誤處理用 strtod (完整、健壯)

五、進階挑戰

  • 實作支援 1.23e-4 科學記號的 atof。
  • 實作 strtol 完整功能:進制自動偵測 (0x/0)、endptr 回傳解析位置、errno 溢位標記。
  • 處理 INT_MIN 絕對值溢位問題 ( -INT_MIN 會溢位 )。

核心收穫:型別轉換的本質是 字元編碼與數值系統的映射。掌握「累積乘 10 + 當前位」與「取模 10 取當前位」這對對偶操作,即掌握了進制轉換的通用鑰匙。

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