C语言 - 十进制转十六进制
我们首先理解十进制转十六进制的原理,然后给出几种C语言实现方法。
原理:不断除以16,记录余数,余数范围0-15,其中10-15用字母A-F表示。然后将余数倒序排列。
步骤:
-
用十进制数除以16,记录余数。
-
将商作为新的被除数,重复步骤1,直到商为0。
-
将余数倒序排列,如果余数在10-15之间,转换为对应的字母。
例如:将255转换为十六进制
255 ÷ 16 = 15 ... 15 (余数15对应F)
15 ÷ 16 = 0 ... 15 (余数15对应F)
所以倒序排列是FF。
我们提供几种方法:
方法1:使用循环和数组存储余数,然后倒序输出。
方法2:使用递归,在递归返回的过程中输出(这样自然就是倒序)。
方法3:使用位运算(实际上十六进制与二进制的对应关系,每4位二进制对应一位十六进制),但这里我们按照除16取余的方法。
注意:我们也要处理0的情况。
我们写一个程序,包含多种方法,并给出详细的解释。
十进制转十六进制 - C语言教程
什么是十进制和十六进制?
-
十进制:我们日常使用的数字系统,使用0-9这10个数字
-
十六进制:计算机中常用的数字系统,使用0-9和A-F这16个字符
-
A=10, B=11, C=12, D=13, E=14, F=15
-
转换原理:除16取余法
将十进制数不断除以16,记录每次的余数,直到商为0,然后将余数倒序排列,并将10-15转换为A-F。
示例:将255转换为十六进制
255 ÷ 16 = 15 ... 余15(F) ↑
15 ÷ 16 = 0 ... 余15(F) ↑
从下往上读取余数:FF,所以255的十六进制是0xFF
示例:将256转换为十六进制
256 ÷ 16 = 16 ... 余0 ↑
16 ÷ 16 = 1 ... 余0 ↑
1 ÷ 16 = 0 ... 余1 ↑
从下往上读取余数:100,所以256的十六进制是0x100
C语言实现代码
#include <stdio.h>
#include <string.h>
// 方法1:使用数组存储余数
void decimalToHex1(int decimal) {
char hex[32]; // 存储十六进制位的数组
int i = 0;
int remainder;
// 处理0的特殊情况
if (decimal == 0) {
printf("十六进制: 0\n");
return;
}
// 不断除以16,记录余数
while (decimal > 0) {
remainder = decimal % 16; // 求余数
// 将余数转换为十六进制字符
if (remainder < 10) {
hex[i] = remainder + '0'; // 0-9直接转换为字符
} else {
hex[i] = remainder - 10 + 'A'; // 10-15转换为A-F
}
decimal = decimal / 16; // 求商
i++;
}
// 倒序输出
printf("十六进制: ");
for (int j = i - 1; j >= 0; j--) {
printf("%c", hex[j]);
}
printf("\n");
}
// 方法2:使用递归实现
void decimalToHex2(int decimal) {
if (decimal == 0) {
return;
}
// 先递归处理高位的数
decimalToHex2(decimal / 16);
// 输出当前位的十六进制字符
int remainder = decimal % 16;
if (remainder < 10) {
printf("%c", remainder + '0');
} else {
printf("%c", remainder - 10 + 'A');
}
}
// 方法3:使用sprintf函数(最简单的方法)
void decimalToHex3(int decimal) {
char hex[32];
sprintf(hex, "%X", decimal); // %X表示输出为大写十六进制
printf("十六进制: %s\n", hex);
}
// 方法4:处理负数的补码形式
void decimalToHex4(int decimal) {
unsigned int num; // 使用无符号整数来处理负数
if (decimal < 0) {
// 对于负数,我们使用其补码表示
num = (unsigned int)decimal;
printf("十进制 %d 的补码十六进制: ", decimal);
} else {
num = decimal;
printf("十六进制: ");
}
char hex[32];
int i = 0;
if (num == 0) {
printf("0\n");
return;
}
while (num > 0) {
int remainder = num % 16;
if (remainder < 10) {
hex[i] = remainder + '0';
} else {
hex[i] = remainder - 10 + 'A';
}
num = num / 16;
i++;
}
// 倒序输出
for (int j = i - 1; j >= 0; j--) {
printf("%c", hex[j]);
}
printf("\n");
}
// 方法5:使用位运算(每4位对应一个十六进制位)
void decimalToHex5(int decimal) {
printf("十六进制: ");
if (decimal == 0) {
printf("0\n");
return;
}
// 处理负数
unsigned int num = (decimal < 0) ? (unsigned int)decimal : decimal;
// 找到最高非零位
int shift = 28; // 32位系统中,十六进制有8位,从第28位开始检查
int foundNonZero = 0;
while (shift >= 0) {
int nibble = (num >> shift) & 0xF; // 提取4位
if (nibble != 0 || foundNonZero) {
foundNonZero = 1;
if (nibble < 10) {
printf("%c", nibble + '0');
} else {
printf("%c", nibble - 10 + 'A');
}
}
shift -= 4; // 移动到下一个4位组
}
printf("\n");
}
// 辅助函数:显示十六进制字符对应关系
void showHexTable() {
printf("十六进制对照表:\n");
printf("十进制 十六进制\n");
for (int i = 0; i <= 15; i++) {
if (i < 10) {
printf(" %2d %c\n", i, i + '0');
} else {
printf(" %2d %c\n", i, i - 10 + 'A');
}
}
printf("\n");
}
int main() {
int number;
printf("十进制转十六进制转换器\n\n");
showHexTable();
printf("请输入一个十进制整数: ");
scanf("%d", &number);
printf("\n转换结果:\n");
printf("方法1(数组存储): ");
decimalToHex1(number);
printf("方法2(递归): ");
if (number == 0) {
printf("0");
} else {
decimalToHex2(number);
}
printf("\n");
printf("方法3(sprintf): ");
decimalToHex3(number);
printf("方法4(处理负数): ");
decimalToHex4(number);
printf("方法5(位运算): ");
decimalToHex5(number);
return 0;
}
代码详解
方法1:数组存储法
-
使用数组
hex[32]存储每一位的十六进制字符 -
decimal % 16获取当前最低4位的值 -
将10-15转换为A-F字符
-
最后倒序输出数组内容
方法2:递归法
-
利用函数调用栈来"记住"余数
-
递归到最深层后依次输出余数
-
代码简洁但可能栈溢出
方法3:sprintf函数法
-
使用C标准库函数
sprintf -
%X格式说明符直接转换为大写十六进制 -
最简单实用的方法
方法4:处理负数补码
-
使用
unsigned int来处理负数 -
显示负数的补码表示形式
-
更符合计算机中实际的存储方式
方法5:位运算法
-
使用移位操作提取每4位
-
(num >> shift) & 0xF提取特定的4位 -
跳过前导零,从第一个非零位开始输出
运行示例
十进制转十六进制转换器
十六进制对照表:
十进制 十六进制
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 A
11 B
12 C
13 D
14 E
15 F
请输入一个十进制整数: 255
转换结果:
方法1(数组存储): 十六进制: FF
方法2(递归): FF
方法3(sprintf): 十六进制: FF
方法4(处理负数): 十六进制: FF
方法5(位运算): 十六进制: FF
负数的处理示例
请输入一个十进制整数: -1
转换结果:
方法1(数组存储): 十六进制:
方法2(递归):
方法3(sprintf): 十六进制: FFFFFFFF
方法4(处理负数): 十进制 -1 的补码十六进制: FFFFFFFF
方法5(位运算): 十六进制: FFFFFFFF
常见问题
-
为什么十六进制用A-F表示10-15?
-
因为需要单字符表示10-15,字母是最自然的选择
-
十六进制在计算机中广泛使用,便于表示二进制数据
-
-
负数怎么处理?
-
计算机中使用补码表示负数
-
方法3、4、5都能正确处理负数
-
负数的十六进制表示是其补码的十六进制形式
-
-
哪种方法最实用?
-
方法3(sprintf)最简单实用
-
方法1(数组存储)最适合理解原理
-
方法5(位运算)性能最好
-
-
十六进制在编程中的用途?
-
内存地址表示
-
颜色代码(如HTML中的#FFFFFF)
-
二进制数据的紧凑表示
-
调试和底层编程
-
这个教程应该能帮助你理解十进制转十六进制的原理和多种C语言实现方法!

浙公网安备 33010602011771号