题目要求如下:
分析binaryOut这个函数:
unsigned char tmp = 0x80,转换为二进制就是1000,0000。而字符c在内存中所占大小为一字节,与1000,0000做按位与运算其实就取决于字符c的ascii码转换为二进制的首位是1还是0。
如'a',其ascii码为97,转换为二进制就是0110,0001,与1000,0000按位与就得到0。而0作为判断条件即为假,输出了0;接着tmp>>=1,即tmp右移一位,得到0100,0000,与a(0110,0001)按位与得到1,为真,输出1…… 以此类推,即输出了'a'的二进制序列。
注:这里如果用tmp的类型能不能是char而不是unsigned char?
需要注意char是带符号的,因此其范围是-128~127,若赋值1000,0000(128)则会溢出,且会变为-128(1000,0000的第一位是1,代表了是负数)。
分析displayInBinary这个函数:
这里面有两个参数,其中void *data是无类型指针,它指向的数据类型暂时不确定;后期使用时一般要通过强制类型转换(再转换成具体类型前不能通过*解引用,因为void指针只知道指向变量的首地址,而不知道指向变量所占的字节大小)。而int len参数就是变量所占字节的大小。
#include
using namespace std;
void displayInBinary(void *data , int len);
void binaryOut(char c);
int main(){
char c = 'a';
short n = 257;
float f = 1.0f;
displayInBinary(&c,sizeof(c));
displayInBinary(&n,sizeof(n));
displayInBinary(&f,sizeof(f));
return 0;
}
void displayInBinary(void *data , int len){
int move = 8*(len-1);
unsigned int tmp = 0x80<>=1;
}
cout <<"\n";
}
这里我的想法是根据变量所占的字节数,来取得不同的tmp与其做位运算。比如short是2位,我就用1000,0000,0000,0000和它做按位与运算。
输出结果如下:
01100001
0000000100000001
00111111100000000000000000000000
关于打印浮点数的疑惑:
为什么这里可以用int型指针指向存放float型的地址?是否会发生类型转换呢?
个人认为这里将data的地址强制转为int型的地址是没有什么区别的,因为地址就是地址:
//float f = 1.0f;
cout << data << endl;
cout << (int *)data << endl;
cout << *(int *)data << endl;
输出结果如下:
0x71ff2c
0x71ff2c
1065353216
其中1065353216转换为二进制就是00111111,10000000,00000000,00000000。
为什么是这样的呢?
这里就要说说浮点数的存储方式了:
根据国际标准IEEE规定,任何一个浮点数NUM的二进制数可以写为:
NUM = (-1)^S*M*2^E;
①当S(sign)为0时,表示一个正数;当S为1时,表示一个负数 。
②E(exponent)表示指数:即科学计数法中的指数,2的多少次方。
③M(mantissa)表示尾数部分。
因此00111111,10000000,00000000,00000000可以解读为0,01111111,00000000000000000000000。
其中M(尾数)部分看上去只有23位的精度,事实上是有24位:因为科学计数法中,如1.01001*2^5,事实上小数点前的1是可以省略的。
然而E(指数)部分看上去有8位,实际上只有7位的精度,因为指数是有正负的。因此指数其实是从00000000(-127)开始到11111111(+128)结束的。故这里的01111111应该解读为指数为0。从而浮点数f的值就是1.0了。
(是老师给出的思路)
#include
using namespace std;
void binaryOut(char);
void displayInBinary(void *, int);
int main(){
char c = 'a';
short n = 100;
float f = 1.0f;
displayInBinary(&c,sizeof(c));
displayInBinary(&n,sizeof(n));
displayInBinary(&f,sizeof(f));
return 0;
}
void binaryOut(char c){
unsigned char tmp=0x80;
for(int i=0; i<8; i++){
if(c&tmp)
cout << 1;
else
cout << 0;
tmp >>=1;
}
}
void displayInBinary(void * data, int len){
char *ptr = (char *)data;
ptr += (len-1);
//栈中高地址往低处增长,先让指针指向高地址
//才能按顺序打印出来
for(int i =0; i
其中对于 ptr += (len-1); 我们需要分析一下栈中的存储情况:
(以short n=100为例)
因此在for循环中ptr--就是将指针向低地址方向移动;从而借助binarOut函数将其二进制序列打印出来。