程序员面试宝典第5章:程序设计基本概念(例题5.4)

5.4.1

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <conio.h>
using namespace std;
int main()
{
    float a = 1.0f;
    cout << (int)a << endl;
    cout << &a << endl;//输出a的地址
    cout << (int&)a << endl;
    cout << boolalpha << ( (int)a == (int&)a )
        << endl;  //输出什么?
    //boolalpha,函数名称,功能是把bool值显示为true或false
    float b = 0.0f;
    cout << (int)b << endl;
    cout << &b << endl;
    cout << (int&)b << endl;
    cout << boolalpha << ( (int)b == (int&)b )
        << endl;  //输出什么?
    return 0;
}

(int&)a:

在机器上运行一下,可以得到结果,“cout<<(int&)a<<endl;”输出的是1065353216,而不是1。这是因为浮点数在内存里和整数的存储方式不同,(int&)a相当于将该浮点数地址开始的sizeof(int)个字节当成int型的数据输出(所以是十六进制的形式啊),因此这取决于float型数据在内存中的存储方式,而不是经过(int&)a显示转换的结果(1)。

1.0f在内存中:
0 0111 1 111 1 000 0000 0000 0000 0000……0000(阶码127+0)

03f8000000

3f800000H=0 01111111 00000000000000000000000B 
符点型数据在X86机上占四个字节,其存储按IEEE754标准实现,即:
1位的符号位s 0(代表正数,1代表负数)
8位的指数位e(移码表示)01111111是0的移码
23位的小数位f 0000000000000000000000 表示小数部分为0
计算机在表示符点数时,要将10进制数转成二进制的规范数形式进行存储的。即:1.f*2^e在存储时,小数前面的1是隐式存储的,不体现在数据中。
现在翻译一下:
3f800000H=1.0*2^0=1.0

1.0f和0.0f在内存中是怎么存的?参考:
https://blog.csdn.net/cnd2449294059/article/details/73912050

运行结果:
在这里插入图片描述

5.4.2

#include <stdio.h>

int  main()
{
    unsigned int a = 0xFFFFFFF7;//32位
    unsigned char i = (unsigned char)a;//8位
    //ff ff ff f7高三位被截断。所以结果为00 00 00 f7。
    char* b = (char*)&a;//取出a的地址(这个是a的指针。unsigned int类型的指针。)
    //把一个unsigned int类型的指针强制转换为一个char型的指针。
    printf("%08x, %08x", i,*b);
    //%p是打印地址的,%x是以十六进制形式打印,完全不同!另外在64位下结果会不一样,所以打印指针老老实实用%p。参考https://blog.csdn.net/qq_25077833/article/details/70041142
}

运行结果:
在这里插入图片描述

为什么输出ff ff ff f7?

上面的程序为什么输出fffffff7:char* b=(char*)&a;这句话到底干了什么事呢?其实说来也简单,&a可以认为是个指向unsigned int类型数据的指针,char*)&a则把&a强制转换成char类型的指针,并且这个时候发生了截断!截断后,指针b只指向oxf7这个数据(为什么b指向最低位的oxf7而不是最高位的oxff?想想上面刚刚讲过的“小端存储”,低地址单元存放低位数据),又由于指针b是char型的,属于有符号数,所以有符号数0xf7在printf()的作用下输出fffffff7。

猜你喜欢

转载自blog.csdn.net/qq_34941153/article/details/90047943