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

十六進制轉十進制:原理、C 實現與邊界處理完整指南

     編輯:關於C

轉換原理

十六進制為基數 16 位置制,數字 0-9、字母 A-F(或 a-f)分別代表 0~15。第 N 位(從右起 0)權值為 16^N。例:0x2AF5 = 2×16³ + 10×16² + 15×16¹ + 5×16⁰ = 10997。

C 語言標準庫方案

#include 
#include 
#include 
#include 

long hex_to_long(const char *str) {
    char *endptr;
    errno = 0;
    long val = strtol(str, &endptr, 16); // 基數 16
    if (errno == ERANGE) { perror("溢位"); return LONG_MAX; }
    if (endptr == str) { fprintf(stderr, "無效格式\n"); return 0; }
    if (*endptr != '\0') { fprintf(stderr, "尾部垃圾字符: %s\n", endptr); }
    return val;
}

int main() {
    printf("%ld\n", hex_to_long("2AF5"));   // 10997
    printf("%ld\n", hex_to_long("-1A"));    // -26
    printf("%ld\n", hex_to_long("0xFF"));   // 255 (支援 0x 前綴)
    return 0;
}
  • strtol/strtoul/strtoll 自動處理空白、正負號、0x 前綴、大小寫。
  • 返回 endptr 可精確檢測解析位置與錯誤。
  • 首選方案,除非教學或極度受限環境。

手寫解析器(教學用)

#include 
#include 

uint32_t hex_to_u32_manual(const char *s) {
    uint32_t result = 0;
    while (*s) {
        char c = *s++;
        uint32_t digit;
        if (c >= '0' && c <= '9') digit = c - '0';
        else if (c >= 'A' && c <= 'F') digit = c - 'A' + 10;
        else if (c >= 'a' && c <= 'f') digit = c - 'a' + 10;
        else break; // 遇到非十六進制字符停止
        result = (result << 4) | digit; // 乘 16 相當於左移 4 位
    }
    return result;
}

關鍵技巧:result = (result << 4) | digit 替代乘法,效率更高。

進階:支援前綴、負號、溢位檢測

int parse_hex_int32(const char *str, int32_t *out) {
    if (!str) return -1;
    // 跳過空白
    while (isspace(*str)) str++;
    // 處理符號
    int neg = 0;
    if (*str == '-') { neg = 1; str++; }
    else if (*str == '+') str++;
    // 跳過 0x/0X
    if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) str += 2;

    uint32_t val = 0;
    for (; *str; str++) {
        char c = *str;
        uint32_t d;
        if (c >= '0' && c <= '9') d = c - '0';
        else if (c >= 'A' && c <= 'F') d = c - 'A' + 10;
        else if (c >= 'a' && c <= 'f') d = c - 'a' + 10;
        else break;
        // 溢位檢測:val > (UINT32_MAX - d) / 16
        if (val > (UINT32_MAX - d) >> 4) return -2; // 溢位
        val = (val << 4) | d;
    }
    if (neg) {
        if (val > (uint32_t)INT32_MAX + 1) return -2;
        *out = -(int32_t)val;
    } else {
        if (val > INT32_MAX) return -2;
        *out = (int32_t)val;
    }
    return 0;
}

應用場景

  • 網路協議解析(IPv6 位址、MAC 位址、十六進制帧)。
  • 嵌入式 Shell 指令解析(reg write 0x4000 0xFF)。
  • 檔案格式解析(ELF、PNG、ZIP 魔數、偏移量)。
  • 顏色值轉換(#RRGGBB → RGB 分量)。

總結

  1. 生產代碼:直接用 strtoul/strtoll,健壯、標準、無需造輪子。
  2. 教學/面試:掌握「左移 4 位 + 或運算」核心邏輯、字符分類、溢位檢測。
  3. 嵌入式無標準庫:手寫解析器 < 30 行,極度輕量。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved