直接使用 printf 函数(最简单、最常用)
这是最直接的方法,利用 printf 函数的格式化输出功能,将一个以十六进制表示的整数直接以十进制形式打印出来。

(图片来源网络,侵删)
核心思想:
C语言中的整数(如 int)在内存中存储的是其二进制补码形式,我们写的 0x1A 只是一个字面量,是告诉编译器“这个数字的值是十六进制的1A”,但编译器一旦解析后,它和十进制数 26 在内存中存储的二进制是完全一样的。printf 只是根据你指定的格式说明符(%d 或 %x)来“翻译”并显示这个内存中的值。
示例代码:
#include <stdio.h>
int main() {
// 定义一个十六进制整数
int hex_value = 0x1A;
// 使用 %d 格式说明符,以十进制形式输出
printf("十六进制数 0x1A 对应的十进制数是: %d\n", hex_value);
// 再举一个例子
int hex_value2 = 0xFF;
printf("十六进制数 0xFF 对应的十进制数是: %d\n", hex_value2);
// 负数示例
int hex_value3 = -0x1A; // 等于 -26
printf("十六进制数 -0x1A 对应的十进制数是: %d\n", hex_value3);
return 0;
}
输出结果:
十六进制数 0x1A 对应的十进制数是: 26
十六进制数 0xFF 对应的十进制数是: 255
十六进制数 -0x1A 对应的十进制数是: -26
优点:

(图片来源网络,侵删)
- 简洁、高效、可读性高。
- 是处理所有整数类型(
int,long,unsigned int等)转换的首选方法。
手动计算(理解转换原理)
如果你需要手动实现转换逻辑(作为编程练习或在没有 printf 的环境中),你需要理解十六进制到十进制的转换算法。
转换原理:
一个十六进制数可以按权展开求和,每一位的权是 16 的相应次方。
公式为:D_n * 16^n + ... + D_1 * 16^1 + D_0 * 16^0
D_i 是第 i 位的十六进制数字(0-9, A-F),n 是位数(从0开始)。
示例:将 0x1A 转换为十进制
0x1A = 1 * 16^1 + A * 16^0
0x1A = 1 * 16 + 10 * 1
0x1A = 16 + 10
0x1A = 26

(图片来源网络,侵删)
C语言实现:
下面是一个函数,它接收一个表示十六进制数的字符串(如 "1A" 或 "FF"),然后手动计算出其十进制值。
#include <stdio.h>
#include <string.h> // 用于 strlen 函数
#include <ctype.h> // 用于 isxdigit 函数
// 函数:将十六进制字符串转换为十进制整数
int hexStringToDecimal(const char *hexStr) {
int decimal = 0;
int base = 1; // 16的幂次,从16^0开始
// 从字符串的末尾向前遍历
for (int i = strlen(hexStr) - 1; i >= 0; i--) {
char c = toupper(hexStr[i]); // 统一转为大写,方便处理 'a'-'f'
int digitValue;
if (isdigit(c)) {
digitValue = c - '0'; // '0'->0, '1'->1, ..., '9'->9
} else if (c >= 'A' && c <= 'F') {
digitValue = 10 + (c - 'A'); // 'A'->10, 'B'->11, ..., 'F'->15
} else {
printf("错误: 字符 '%c' 不是有效的十六进制数字,\n", c);
return 0; // 或者返回一个错误码
}
decimal += digitValue * base;
base *= 16; // 更新16的幂次
}
return decimal;
}
int main() {
const char *hex1 = "1A";
const char *hex2 = "FF";
const char *hex3 = "2B4";
printf("十六进制字符串 \"%s\" 对应的十进制数是: %d\n", hex1, hexStringToDecimal(hex1));
printf("十六进制字符串 \"%s\" 对应的十进制数是: %d\n", hex2, hexStringToDecimal(hex2));
printf("十六进制字符串 \"%s\" 对应的十进制数是: %d\n", hex3, hexStringToDecimal(hex3));
return 0;
}
输出结果:
十六进制字符串 "1A" 对应的十进制数是: 26
十六进制字符串 "FF" 对应的十进制数是: 255
十六进制字符串 "2B4" 对应的十进制数是: 700
使用标准库函数 strtol
C标准库提供了一个非常强大的函数 strtol (string to long),可以将字符串形式的数字转换为长整型,它可以自动识别多种进制(包括十六进制)。
函数原型:
long strtol(const char *nptr, char **endptr, int base);
nptr: 要转换的字符串。endptr: 指向一个字符指针,用于存储转换停止的位置,如果不需要,可以传NULL。base: 进制,如果为0,函数会根据字符串的前缀自动判断(0x或0X表示十六进制,0表示八进制,其他表示十进制),如果为16,则强制按十六进制转换。
示例代码:
#include <stdio.h>
#include <stdlib.h> // 用于 strtol 函数
#include <errno.h> // 用于检测 strtol 的错误
int main() {
const char *hexStr1 = "0x1A";
const char *hexStr2 = "FF"; // 没有前缀0x,需要指定base为16
const char *hexStr3 = "100"; // 这个可以是十进制,也可以是十六进制
char *endptr; // 用于存储转换结束的位置
// 使用 strtol 进行转换
long num1 = strtol(hexStr1, &endptr, 0); // base=0, 自动识别0x前缀
long num2 = strtol(hexStr2, &endptr, 16); // base=16, 强制十六进制
long num3 = strtol(hexStr3, &endptr, 16); // 指定为十六进制,则100是256
// 检查转换是否成功
if (errno == ERANGE) {
printf("错误:数值超出 long 类型的表示范围,\n");
} else if (hexStr1 == endptr) {
printf("错误:没有有效的数字被转换,\n");
} else {
printf("字符串 \"%s\" (自动识别) 转换为十进制是: %ld\n", hexStr1, num1);
printf("字符串 \"%s\" (base=16) 转换为十进制是: %ld\n", hexStr2, num2);
printf("字符串 \"%s\" (base=16) 转换为十进制是: %ld\n", hexStr3, num3);
}
return 0;
}
输出结果:
字符串 "0x1A" (自动识别) 转换为十进制是: 26
字符串 "FF" (base=16) 转换为十进制是: 255
字符串 "100" (base=16) 转换为十进制是: 256
总结与对比
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
printf |
最简单、最直接、性能最高 | 只能用于输出,无法在程序中获取转换后的数值变量。 | 只是想查看或打印一个十六进制字面量的十进制值。 |
| 手动计算 | 能深刻理解转换原理,不依赖任何库函数。 | 代码复杂,需要自己处理字符串、错误和边界情况。 | 学习目的,或在没有标准库的受限环境中。 |
strtol |
功能强大、灵活,能处理字符串输入,自动识别前缀,有完善的错误处理机制。 | 比 printf 稍微复杂一点,需要理解其参数。 |
需要将用户输入的字符串(如 "FF")转换为数字,或者需要处理各种进制输入时。 |
- 日常编程中,如果你有一个十六进制字面量(如
0x1A),想得到它的十进制值,直接用printf("%d", 0x1A);是最佳选择。 - 如果你需要处理来自字符串的十六进制数据(例如用户输入),使用
strtol是最标准、最安全、最灵活的方法。 - 如果你想学习底层的转换算法,手动实现一个转换函数是非常好的练习。
