1. 前言
C 語言是一種被眾多程式設計師使用的強大程式語言,並提供了豐富且高效處理數值的方法。其中,「16 進位」在位元操作與記憶體管理等情境中經常被使用。本文將詳細解說 C 語言中 16 進位的基礎到應用,並以循序方式說明,讓第一次接觸 16 進位的讀者也能輕鬆理解。
2. 數值的表示方法
10 進位、8 進位與 16 進位的差異
在 C 語言中,數值可以以下列方式表示:
- 10 進位
人類日常使用的數字表示方式。例如:123
會被視為 10 進位。 - 8 進位
在數值前加上0
會被視為 8 進位。例如:0123
在 8 進位中代表「83」。 - 16 進位
在數值前加上0x
或0X
會被視為 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 進位:
- 用 16 除(47 ÷ 16 = 2 餘 15)。
- 商為高位,餘數為低位。
- 結果:
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 語言中,即使省略位數也能正常運作。例如 0xA
與 0x000A
意義相同。但為了程式可讀性,建議必要時補零。
Q5:處理 16 進位時常見錯誤原因?
- 忘記加
0x
- 解法:記得在 16 進位數值前加上
0x
或0X
。
- 格式化字元錯誤
- 例:用
%d
輸出 16 進位。 - 解法:輸出 16 進位應使用
%x
或%X
。
- 資料型態不符
- 例:未使用
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