C 語言 16 進位完整指南:從基礎概念到實用應用與範例

1. 前言

C 語言是一種被眾多程式設計師使用的強大程式語言,並提供了豐富且高效處理數值的方法。其中,「16 進位」在位元操作與記憶體管理等情境中經常被使用。本文將詳細解說 C 語言中 16 進位的基礎到應用,並以循序方式說明,讓第一次接觸 16 進位的讀者也能輕鬆理解。

2. 數值的表示方法

10 進位、8 進位與 16 進位的差異

在 C 語言中,數值可以以下列方式表示:

  1. 10 進位
    人類日常使用的數字表示方式。例如:123 會被視為 10 進位。
  2. 8 進位
    在數值前加上 0 會被視為 8 進位。例如:0123 在 8 進位中代表「83」。
  3. 16 進位
    在數值前加上 0x0X 會被視為 16 進位。例如:0x123 在 16 進位中代表「291」。

16 進位的優點

16 進位是 2 進位的簡化表示,一位 16 進位數可對應四位 2 進位數,因此在位元操作時非常方便。此外,在偵錯過程中檢視記憶體內容時也經常使用。

年収訴求

3. 16 進位的基礎

16 進位的結構

16 進位由以下 16 個符號組成:

  • 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F
    其中 A 代表 10,B 代表 11,…,F 代表 15。

16 進位轉換為 10 進位

例如將 16 進位的 0x2F 轉換為 10 進位:

  • 0x2F = (2 × 16) + (15 × 1) = 47

10 進位轉換為 16 進位

將 10 進位 47 轉換為 16 進位:

  1. 用 16 除(47 ÷ 16 = 2 餘 15)。
  2. 商為高位,餘數為低位。
  • 結果:0x2F

4. C 語言中的 16 進位常數表示

常數的寫法

在 C 語言中,16 進位可以以下形式撰寫:

int hexValue = 0x1A; // 16 進位的「26」

使用 printf 輸出 16 進位

在 C 語言中,若要輸出 16 進位可使用 printf 函數:

#include <stdio.h>

int main() {
    int hexValue = 0x1A;
    printf("16進位: %X
", hexValue); // 大寫輸出
    printf("16進位: %x
", hexValue); // 小寫輸出
    return 0;
}

輸出結果:

16進位: 1A
16進位: 1a

指定給整數型別的範例

16 進位可指定給整數型變數:

int num = 0xFF; // 視為 255

5. 16 進位與位元運算

使用位元遮罩(Bitmask)

16 進位在位元遮罩操作中非常常見。以下是範例:

#include <stdio.h>

int main() {
    unsigned char value = 0xAF; // 16 進位「AF」
    unsigned char mask = 0x0F;  // 只擷取低 4 位元的遮罩

    unsigned char result = value & mask;
    printf("結果: 0x%X
", result); // 結果為「0x0F」
    return 0;
}

設定位元旗標(Bit Flag)

將特定位元設定為 1:

unsigned char flags = 0x00;
flags |= 0x10; // 將第 4 個位元設定為 1

6. 16 進位與浮點數

以 16 進位表示浮點數的方法比較特殊,但可使用 printf 函數:

#include <stdio.h>

int main() {
    double value = 123.456;
    printf("16進位格式: %a
", value);
    return 0;
}

輸出範例:

16進位格式: 0x1.ed70a3d70a3d7p+6

7. 16 進位的應用範例

記憶體傾印(Memory Dump)分析

偵錯時利用 16 進位檢視記憶體內容的範例:

#include <stdio.h>

void dumpMemory(void* ptr, size_t size) {
    unsigned char* byte = (unsigned char*)ptr;
    for (size_t i = 0; i < size; i++) {
        printf("%02X ", byte[i]);
        if ((i + 1) % 16 == 0) printf("
");
    }
}

int main() {
    int data = 0x12345678;
    dumpMemory(&data, sizeof(data));
    return 0;
}

8. 總結

本文從基礎到應用介紹了 C 語言中的 16 進位知識。16 進位不僅用於數值表示,還廣泛應用於位元操作與偵錯工作。熟練掌握 16 進位,能讓你在 C 語言開發中更加高效。

FAQ:C 語言 16 進位常見問題

Q1:在 C 語言中宣告 16 進位時,如果忘了加 0x 會怎樣?

若 16 進位常數前沒有加上 0x(或 0X),則會被當作 10 進位處理。
例如:

int value = 123; // 當作 10 進位的 123

要以 16 進位處理,必須加上 0x

Q2:如何在 C 語言中輸入(scanf)16 進位?

使用 scanf 讀取 16 進位時,需使用格式化字元 %x
範例:

#include <stdio.h>

int main() {
    int value;
    printf("請輸入 16 進位(例如: 0x1A):");
    scanf("%x", &value);
    printf("輸入的值(10 進位): %d
", value);
    return 0;
}

若輸入 0x1A,則會被轉為 10 進位的「26」。

Q3:如何將 16 進位當成字串處理?

可用字串操作函數或格式化輸出將數值轉為 16 進位字串。
範例:

#include <stdio.h>

int main() {
    int value = 255;
    char hexStr[10];
    sprintf(hexStr, "%X", value); // 轉為 16 進位字串
    printf("16進位字串: %s
", hexStr);
    return 0;
}

輸出:

16進位字串: FF

Q4:16 進位位數不足時會怎樣?

在 C 語言中,即使省略位數也能正常運作。例如 0xA0x000A 意義相同。但為了程式可讀性,建議必要時補零。

Q5:處理 16 進位時常見錯誤原因?

  1. 忘記加 0x
  • 解法:記得在 16 進位數值前加上 0x0X
  1. 格式化字元錯誤
  • 例:用 %d 輸出 16 進位。
  • 解法:輸出 16 進位應使用 %x%X
  1. 資料型態不符
  • 例:未使用 unsigned,導致符號出現異常。
  • 解法:必要時加上 unsigned

Q6:如何將 10 進位快速轉成 16 進位?

可直接用 printf 輸出 16 進位。
範例:

#include <stdio.h>

int main() {
    int decimalValue = 42;
    printf("10進位: %d -> 16進位: %X
", decimalValue, decimalValue);
    return 0;
}

輸出:

10進位: 42 -> 16進位: 2A

Q7:16 進位可以表示負數嗎?

可以,負數會用二補數(Two’s Complement)形式儲存。
範例:

#include <stdio.h>

int main() {
    int negativeValue = -16;
    printf("10進位: %d -> 16進位: %X
", negativeValue, negativeValue);
    return 0;
}

輸出:

10進位: -16 -> 16進位: FFFFFFF0

這裡的 FFFFFFF0 即為負數的二補數表示。

Q8:如何在 C 語言中使用 16 進位陣列?

可直接以 16 進位常數初始化陣列。
範例:

#include <stdio.h>

int main() {
    unsigned char hexArray[] = {0x1A, 0x2B, 0x3C, 0x4D};

    for (int i = 0; i < sizeof(hexArray); i++) {
        printf("陣列[%d]: 0x%X
", i, hexArray[i]);
    }
    return 0;
}

輸出:

陣列[0]: 0x1A
陣列[1]: 0x2B
陣列[2]: 0x3C
陣列[3]: 0x4D
侍エンジニア塾