一、基本概念
1. 常见进制系统
-
十进制(Decimal): 基数为10,使用数字0-9
-
二进制(Binary): 基数为2,使用数字0-1
-
八进制(Octal): 基数为8,使用数字0-7
-
十六进制(Hexadecimal): 基数为16,使用数字0-9和字母A-F
2. 进制表示方法
在C语言中,不同进制的表示方法:
-
十进制: 直接写数字,如
123
-
八进制: 数字前加
0
,如0123
表示八进制的123 -
十六进制: 数字前加
0x
或0X
,如0x1A3
二、进制转换方法
1. 其他进制转十进制
按权展开法:
十进制数 = dₙ×baseⁿ + dₙ₋₁×baseⁿ⁻¹ + ... + d₁×base¹ + d₀×base⁰
2. 十进制转其他进制
短除法:不断用目标基数除十进制数,记录余数,直到商为0,然后倒序排列余数。
3. 二进制与八进制/十六进制互转
-
二进制转八进制:每3位二进制对应1位八进制
-
二进制转十六进制:每4位二进制对应1位十六进制
-
反向转换同样适用
三、C语言中的进制转换函数
1. 输入输出函数
// 输入
scanf("%d", &num); // 十进制输入
scanf("%o", &num); // 八进制输入
scanf("%x", &num); // 十六进制输入
// 输出
printf("%d", num); // 十进制输出
printf("%o", num); // 八进制输出(无前缀)
printf("%#o", num); // 八进制输出(带0前缀)
printf("%x", num); // 十六进制输出(小写,无前缀)
printf("%#x", num); // 十六进制输出(小写,带0x前缀)
printf("%X", num); // 十六进制输出(大写,无前缀)
printf("%#X", num); // 十六进制输出(大写,带0X前缀)
2. 转换函数
#include <stdlib.h>
// 字符串转整数
long int strtol(const char *str, char **endptr, int base);
// 示例:将十六进制字符串"1A"转为十进制数
char str[] = "1A";
char *end;
long num = strtol(str, &end, 16); // num = 26
// 整数转字符串
char* itoa(int value, char *str, int base); // 非标准函数,部分编译器支持
四、手动实现进制转换
1. 十进制转其他进制
void decimalToBase(int num, int base) {
char digits[] = "0123456789ABCDEF";
char result[32];
int index = 0;
if(num == 0) {
printf("0");
return;
}
while(num > 0) {
result[index++] = digits[num % base];
num /= base;
}
// 倒序输出
for(int i = index-1; i >= 0; i--) {
printf("%c", result[i]);
}
}
2. 其他进制转十进制
int baseToDecimal(char *str, int base) {
int len = strlen(str);
int num = 0;
for(int i = 0; i < len; i++) {
char c = str[i];
int digit;
if(c >= '0' && c <= '9') {
digit = c - '0';
} else if(c >= 'A' && c <= 'F') {
digit = 10 + (c - 'A');
} else if(c >= 'a' && c <= 'f') {
digit = 10 + (c - 'a');
} else {
return -1; // 非法字符
}
if(digit >= base) {
return -1; // 数字超过基数范围
}
num = num * base + digit;
}
return num;
}
五、位操作与进制转换
二进制与其他进制的转换可以使用位操作提高效率:
// 十进制转二进制(输出形式)
void printBinary(unsigned int num) {
for(int i = 31; i >= 0; i--) {
printf("%d", (num >> i) & 1);
if(i % 4 == 0) printf(" "); // 每4位加空格
}
}
六、总结
-
理解进制本质:所有进制都是位置计数法,只是基数不同
-
掌握转换方法:
-
其他进制→十进制:按权展开
-
十进制→其他进制:短除法
-
二进制↔八/十六进制:分组对应
-
-
熟练使用C语言工具:
-
printf/scanf的格式控制
-
strtol等转换函数
-
-
注意边界情况:负数、0、非法输入的处理
-
性能考虑:大量转换时考虑使用位操作或查表法优化