整数在内存中到底是怎样存储的?最好的方法就是将其打印出来看一看。在C的标准库中 <stdio.h>中有一个相当强大的输出函数:printf。但是它却不能够打印出整数的二进制形式。怎么办呢?自己写一个吧!
10进制到二进制的转换是通过短除法进行的,像下面这样:
本想按照这样的算法写一个打印程序,但是转念一想要是负数怎么办?是否可以和正数一样使用同样的算法?是否还有更简洁易懂的方法(我觉得除法有点不好懂)。还是得另外想个办法。最后发现可以用位运算来做。
通过观察,我们可以从二进制数的最高位开始访问,如果是1就打印1,是0就打印0。直到二进制数的最后一位。下面是我写的一个测验程序,打印8位二进制数:
1 2 3 4 5 6 7 8 9 |
int print_int_8bit(char value) { unsigned char index = 0x80; while (index > 0) { putchar(value & index ? '1' : '0'); index >>= 1; } } |
变量index就像一个“游标”一样,它让我们可以从value的最高位一直访问到最低位。(想想为什么要将index声明为 unsigned 类型)。
1 2 3 4 5 |
print_int_8bit(10); print_int_8bit(-10); /* 运行结果 */ 00001010 11110110 |
如果你要打印16位,32位二进制的整数呢?只要修改index的类型即可。下面这个函数接受两个参数,第一个参数是要打印的整数,第二个参数是你要打印多少位(可以是8,16,32)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
void print_int_bit(int value,int type) { unsigned int index = 0x80000000; switch(type) { case 8: index = 0x80; break; case 16: index = 0x8000; break; case 32: index = 0x80000000; break; } while(index > 0) { putchar(value & index ? '1' : '0'); index >>= 1; } } |
如果你要打印整数10,你可以这样:
1 2 3 4 5 6 7 8 |
print_int_bit(10,8); print_int_bit(10,16); print_int_bit(10,32); /* 运行结果 */ 00001010 0000000000001010 00000000000000000000000000001010 |
如果我像下面这样调用会不会出bug?
1 2 3 4 5 6 7 8 9 10 |
char x = 13; print_int_bit(x,32) /* ** 调用print_int_bit,打印一个8位char ** 但是要打印出32位,会不会有bug? ** 答案是 不会 ** 因为C语言函数参数是值传递 ** 所以value不足的部分会用0填充 */ |
但是index变量为什么要声明成unsigned呢?
这是因为如果将其声明为一个有符号数,比如char 。在使用0×80(二进制10000000)初始化时,它是一个负数-128。而我们是通过判断index是否大于0来确定是否已经访问完value的所以二进制位的。所以不能将其声明为char,否则你将什么都看不到(循环不执行)。
如果你有兴趣可以将其声明为有符号整数,然后看看怎么修改函数才能让它正常工作。PS:char 和 unsigned char 使用 0×80 初始化是其二进制表示都是 10000000。
(全文完)
发表评论
要发表评论,您必须先登录。