基础概念
进制又称数制,是指用一组固定的符号和统一的规则来表示数值的方法,在C语言中,可以使用不同的前缀来表示不同的进制:
- 二进制:以0b或0B为前缀(部分编译器可能不支持)
- 八进制:以0为前缀
- 十进制:无特殊前缀
- 十六进制:以0x或0X为前缀
进制转换方法大约分为3种:
- 二进制、八进制、十六进制转十进制:
按照各进制的权值展开,然后相加即可得到十进制数。 - 十进制转二进制、八进制、十六进制:
采用除基取余法,即用十进制数除以目标进制的基数,然后取整数部分继续除,直到商为0为止,最后将所有余数从后往前排列,即可得到转换后的数。 - 二进制、八进制、十六进制之间的转换:
可以先转换为十进制,然后再转换为目标进制,也可以利用它们之间的关系直接转换,如二进制与八进制之间可以每三位二进制数对应一位八进制数进行转换。
在C语言代码编写中,可以使用标准库函数如printf和scanf来进行进制的输入和输出,比如使用%d格式符输出十进制数,%x或%X输出十六进制数(小写或大写),%o输出八进制数。对于二进制的输入和输出,C语言标准库并未提供直接的支持,但可以通过位运算等技巧实现。
进制位 | 二进制 | 八进制 | 十进制 | 十六进制 |
---|---|---|---|---|
规则 | 逢二进一 | 逢八进一 | 逢十进一 | 逢十六进一 |
基数 | r=2 | r=8 | r=10 | r=16 |
数符 | 0,1 | 0,1,2,3,…7 | 0,1,2,3,…9 | 0,1,2,3,…15 |
权 | 2 i 2^{i} 2i | 8 i 8^{i} 8i | 1 0 i 10^{i} 10i | 1 6 i 16^{i} 16i |
形式表示符 | B | O | D | H |
常用的进制转换表:
二进制 | 八进制 | 十进制 | 十六进制 |
---|---|---|---|
0000 | 0 | 0 | 0x0 |
0001 | 1 | 1 | 0x1 |
0010 | 2 | 2 | 0x2 |
0011 | 3 | 3 | 0x3 |
0100 | 4 | 4 | 0x4 |
0101 | 5 | 5 | 0x5 |
0110 | 6 | 6 | 0x6 |
0111 | 7 | 7 | 0x7 |
1000 | 10 | 8 | 0x8 |
1001 | 11 | 9 | 0x9 |
1010 | 12 | 10 | 0xA |
1011 | 13 | 11 | 0xB |
1100 | 14 | 12 | 0xC |
1101 | 15 | 13 | 0xD |
1110 | 16 | 14 | 0xE |
1111 | 17 | 15 | 0xF |
二进制转换
二进制转换为八进制
#include <stdio.h>
#include <string.h>
#include <math.h> void binaryToOctal(char *binary) { int len = strlen(binary); int extraZeros = len % 3; // 计算需要补充的0的个数,让他能被3整除 char octal[len / 3 + extraZeros + 1]; // 分配足够的空间来存储八进制数 int octalIndex = 0; int binaryIndex = 0; // 如果二进制数长度不是3的倍数,则前面补0 for (int i = 0; i < extraZeros; i++) { printf("0"); } while (binaryIndex < len) { int value = 0; for (int i = 0; i < 3 && binaryIndex < len; i++, binaryIndex++) { value = value * 2 + (binary[binaryIndex] - '0'); } octal[octalIndex++] = (value < 8) ? (value + '0') : '?'; // ?表示转换错误 } octal[octalIndex] = '\0'; // 添加字符串结束符 printf("%s\n", octal);
} int main() { char binary[] = "1101001"; // 示例binaryToOctal(binary); // 调用函数进行转换 return 0;
}
二进制转换为十进制
使用到了pow()函数
,需要添加 -lm
选项来链接libm数学库
gcc test.c -o test -lm
./test
// test.c
#include <stdio.h>
#include <string.h>
#include <math.h> void binaryToOctal(char *binary) { int len = strlen(binary); int extraZeros = len % 3; char octal[len / 3 + extraZeros + 1]; int octalIndex = 0; int binaryIndex = 0; for (int i = 0; i < extraZeros; i++) { printf("0"); } while (binaryIndex < len) { int value = 0; for (int i = 0; i < 3 && binaryIndex < len; i++, binaryIndex++) { value = value * 2 + (binary[binaryIndex] - '0'); } octal[octalIndex++] = (value < 8) ? (value + '0') : '?'; } octal[octalIndex] = '\0'; printf("%s\n", octal);
} int main() { char binary[] = "1101001"; binaryToOctal(binary); return 0;
}
二进制转换为十六进制
#include <stdio.h>
#include <string.h>
#include <math.h> void binaryToHexadecimal(char *binary) { int length = strlen(binary); int decimal = 0; for (int i = length - 1; i >= 0; i--) { if (binary[i] == '1') { decimal += pow(2, length - 1 - i); } } if (decimal < 16) { if (decimal >= 10) { printf("%c", decimal - 10 + 'A'); } else { printf("%d", decimal); } } else { binaryToHexadecimal(binary); int remainder = decimal % 16; if (remainder >= 10) { printf("%c", remainder - 10 + 'A'); } else { printf("%d", remainder); } }
} int main() { char binary[65]; printf("Enter a binary number: "); scanf("%32s", binary); printf("Hexadecimal representation: "); binaryToHexadecimal(binary); printf("\n"); return 0;
}
十进制转换
十进制转换为二进制
#include <stdio.h> void decimalToBinary(int n) { if (n == 0) { return; } decimalToBinary(n / 2); printf("%d", n % 2);
} int main() { int decimal; printf("Enter a decimal number: "); scanf("%d", &decimal); printf("Binary representation: "); decimalToBinary(decimal); printf("\n"); return 0;
}
十进制转换为八进制
#include <stdio.h> void decimalToOctal(int n) { if (n < 8) { printf("%d", n); return; } decimalToOctal(n / 8); printf("%d", n % 8);
} int main() { int decimal; printf("Enter a decimal number: "); scanf("%d", &decimal); printf("Octal representation: "); decimalToOctal(decimal); printf("\n"); return 0;
}
十进制转换为十六进制
#include <stdio.h> void decimalToHexadecimal(int n) { if (n < 16) { if (n >= 10) { printf("%c", n - 10 + 'A'); } else { printf("%d", n); } return; } decimalToHexadecimal(n / 16); decimalToHexadecimal(n % 16);
} int main() { int decimal; printf("Enter a decimal number: "); scanf("%d", &decimal); printf("Hexadecimal representation: "); decimalToHexadecimal(decimal); printf("\n"); return 0;
}
八进制转换
八进制转换为二进制
#include <stdio.h>
#include <string.h> void octalToBinary(char *octal) { int length = strlen(octal); for (int i = 0; i < length; i++) { int digit = octal[i] - '0'; switch (digit) { case 7: printf("111"); break; case 6: printf("110"); break; case 5: printf("101"); break; case 4: printf("100"); break; case 3: printf("011"); break; case 2: printf("010"); break; case 1: printf("001"); break; case 0: printf("000"); break; } }
} int main() { char octal[33];printf("Enter an octal number: "); scanf("%32s", octal); printf("Binary representation: "); octalToBinary(octal); printf("\n"); return 0;
}
八进制转换为十进制
#include <stdio.h>
#include <string.h>
#include <math.h> long long octalToDecimal(char *octal) { int length = strlen(octal); long long decimal = 0; for (int i = 0; i < length; i++) { int digit = octal[i] - '0'; decimal += digit * pow(8, length - 1 - i); } return decimal;
} int main() { char octal[33]; printf("Enter an octal number: "); scanf("%32s", octal); long long decimal = octalToDecimal(octal); printf("Decimal representation: %lld\n", decimal); return 0;
}
八进制转换为十六进制
#include <stdio.h>
#include <string.h>
#include <math.h> long long octalToDecimal(char *octal) { int length = strlen(octal); long long decimal = 0; for (int i = 0; i < length; i++) { int digit = octal[i] - '0'; decimal += digit * pow(8, length - 1 - i); } return decimal;
} void decimalToHexadecimal(long long decimal) { if (decimal < 16) { if (decimal >= 10) { printf("%c", (int)(decimal - 10 + 'A')); } else { printf("%lld", decimal); } } else { decimalToHexadecimal(decimal / 16); decimalToHexadecimal(decimal % 16); }
}
int main() { char octal[33]; printf("Enter an octal number: "); scanf("%32s", octal); long long decimal = octalToDecimal(octal); printf("Hexadecimal representation: "); decimalToHexadecimal(decimal); printf("\n"); return 0;
}
十六进制转换
十六进制转换为二进制
#include <stdio.h>
#include <string.h>
#include <ctype.h> void hexadecimalToBinary(char hex) { switch (toupper(hex)) { case '0': printf("0000"); break; case '1': printf("0001"); break; case '2': printf("0010"); break; case '3': printf("0011"); break; case '4': printf("0100"); break; case '5': printf("0101"); break; case '6': printf("0110"); break; case '7': printf("0111"); break; case '8': printf("1000"); break; case '9': printf("1001"); break; case 'A': case 'a': printf("1010"); break; case 'B': case 'b': printf("1011"); break; case 'C': case 'c': printf("1100"); break; case 'D': case 'd': printf("1101"); break; case 'E': case 'e': printf("1110"); break; case 'F': case 'f': printf("1111"); break; default: printf("Invalid hexadecimal digit\n"); break; }
} int main() { char hexadecimal[100]; printf("Enter a hexadecimal number: "); scanf("%s", hexadecimal); printf("Binary representation: "); for (int i = 0; hexadecimal[i] != '\0'; i++) { hexadecimalToBinary(hexadecimal[i]); } printf("\n"); return 0;
}
十六进制转换为八进制
#include <stdio.h>
#include <string.h>
#include <ctype.h> int hexadecimalToOctalDigit(char hex) { switch (toupper(hex)) { case '0': return 0; case '1': return 1; case '2': return 2; case '3': return 3; case '4': return 4; case '5': return 5; case '6': return 6; case '7': return 7; case '8': return 10; case '9': return 11;case 'A': case 'a': return 12;case 'B': case 'b': return 13;case 'C': case 'c': return 14; case 'D': case 'd': return 15; case 'E': case 'e': return 16; case 'F': case 'f': return 17; default: return -1; }
} void hexadecimalToOctal(const char *hexadecimal) { int length = strlen(hexadecimal); int value = 0; int base = 1; for (int i = length - 1; i >= 0; --i) { int digit = hexadecimalToOctalDigit(hexadecimal[i]); if (digit == -1) { printf("Invalid hexadecimal input\n"); return; } value += digit * base; base = base == 1 ? 8 : base * 16; if (base == 128) { printf("%o", value); value = 0; base = 1; } } if (value > 0) { printf("%o", value); }
} int main() { char hexadecimal[100]; printf("Enter a hexadecimal number: "); scanf("%s", hexadecimal); printf("Octal representation: "); hexadecimalToOctal(hexadecimal); printf("\n"); return 0;
}
十六进制转换为十进制
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <ctype.h> long long hexadecimalToDecimal(const char *hexadecimal) { long long decimal = 0; int length = strlen(hexadecimal); for (int i = length - 1, power = 0; i >= 0; --i, ++power) { int digit = 0; char c = toupper(hexadecimal[i]); if (c >= '0' && c <= '9') { digit = c - '0'; } else if (c >= 'A' && c <= 'F') { digit = 10 + (c - 'A'); } else { printf("Invalid hexadecimal input\n"); return -1; } decimal += digit * pow(16, power); } return decimal;
} int main() { char hexadecimal[100]; printf("Enter a hexadecimal number: "); scanf("%s", hexadecimal); long long decimal = hexadecimalToDecimal(hexadecimal); if (decimal != -1) { printf("Decimal representation: %lld\n", decimal); } return 0;
}
字符转换
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <ctype.h> // 十进制
int charToDecimal(char c) { return (int)c;
}
// 二进制
void charToBinary(char c, char *binary) { int decimal = (int)c; int index = 0; while (decimal > 0) { binary[index++] = (decimal % 2) + '0'; decimal /= 2; } binary[index] = '\0'; for (int i = 0; i < index / 2; i++) { char temp = binary[i]; binary[i] = binary[index - i - 1]; binary[index - i - 1] = temp; }
}
// 八进制
void charToOctal(char c, char *octal) { int decimal = (int)c; int index = 0; while (decimal > 0) { octal[index++] = (decimal % 8) + '0'; decimal /= 8; } octal[index] = '\0'; for (int i = 0; i < index / 2; i++) { char temp = octal[i]; octal[i] = octal[index - i - 1]; octal[index - i - 1] = temp; }
}
// 十六进制
void charToHexadecimal(char c, char *hexadecimal) { int decimal = (int)c; int index = 0; while (decimal > 0) { int digit = decimal % 16; if (digit < 10) { hexadecimal[index++] = digit + '0'; } else { hexadecimal[index++] = (digit - 10) + 'A'; } decimal /= 16; } hexadecimal[index] = '\0'; for (int i = 0; i < index / 2; i++) { char temp = hexadecimal[i]; hexadecimal[i] = hexadecimal[index - i - 1]; hexadecimal[index - i - 1] = temp; }
}int main() { char inputChar; printf("Enter a character: "); scanf(" %c", &inputChar); // c前有一个空格,可以跳过任何空白字符 int decimal = charToDecimal(inputChar); printf("Decimal(十进制): %d\n", decimal); char binary[33]; // 32位表示一个字符的ASCII码的二进制形式 charToBinary(inputChar, binary); printf("Binary(二进制): %s\n", binary); char octal[12]; // 最多需要11位来表示一个字符的ASCII码的八进制形式 charToOctal(inputChar, octal); printf("Octal(八进制): %s\n", octal); char hexadecimal[9]; // 最多需要8位来表示一个字符的ASCII码的十六进制形式 charToHexadecimal(inputChar, hexadecimal); printf("Hexadecimal(十六进制): %s\n", hexadecimal); return 0;
}
十六进制在内存操作上的应用
这里给分配一段动态内存,并使用十六进制值初始化这块内存区域,然后打印出内存中的内容
#include <stdio.h>
#include <stdlib.h>
#include <string.h> int main() { // 动态分配一个包含16个字节的内存块 unsigned char *memoryBlock = (unsigned char *)malloc(16 * sizeof(unsigned char)); if (memoryBlock == NULL) { printf("Memory allocation failed.\n"); return 1; } // 使用十六进制值初始化内存块 unsigned char initValues[] = {0xA1, 0xB2, 0xC3, 0xD4, 0xE5, 0xF6, 0x07, 0x18, 0x29, 0x3A, 0x4B, 0x5C, 0x6D, 0x7E, 0x8F, 0x90}; // 将初始化值复制到分配的内存块中 memcpy(memoryBlock, initValues, 16 * sizeof(unsigned char)); // 打印内存块中的内容,以十六进制形式展示 printf("Memory contents (in hexadecimal):\n"); for (int i = 0; i < 16; ++i) { printf("%02X ", memoryBlock[i]); if ((i + 1) % 8 == 0) { printf("\n"); } } printf("\n"); free(memoryBlock); return 0;
}