浮点型和整型在内存中的存储方式

(代码运行环境:Xcode7.3.1)

先来看这段代码

#include <stdio.h>
int main() {
    int a = 0x12345678;
    int i = 0;
    printf("0x%x, 0x%x\n", &a, a);
    for(; i < sizeof(a); i++) {
        printf("0x%x, 0x%x\n",(char *)&a +i, *((char *)&a + i));
    }
    return 0;
}
输出:
0x5fbff7c8, 0x12345678
0x5fbff7c8, 0x78
0x5fbff7c9, 0x56
0x5fbff7ca, 0x34
0x5fbff7cb, 0x12

得出结论:在内存中,数是倒着存储的;

87 65 43 21


整形的存储方式
运行此代码
我们把Int类型拆开来看,分成4个字节看(32位)

#include <iostream>
#include <vector>
void c_to_b(unsigned char c, std::vector<int> &ve) { // 十进制char类型转换为二进制
    int st[8];
    for(int index = 7; index >= 0; index--) {
        st[index] = c % 2;
        c >>= 1;
    }
    for (int index = 0; index < 8; index++) {
        ve.push_back(st[index]);
    }
}
void int_to_char(int interge) { // int类型转化为char类型,而且以二进制输出
    std::vector<int> ve;
    union {
        int a;
        struct {
            unsigned char a1, a2, a3, a4;
        } st;
    } un;
    un.a = interge;
    c_to_b(un.st.a1, ve); // 明显体现出。倒着存储的
    c_to_b(un.st.a2, ve);
    c_to_b(un.st.a3, ve);
    c_to_b(un.st.a4, ve);

    for (int index = 0; index < 8; index++) {
        std::cout << ve[index];
    }
    std::cout << " ";
    for (int index = 8; index < 16; index++) {
        std::cout << ve[index];
    }
    std::cout << " ";
    for (int index = 16; index < 24; index++) {
        std::cout << ve[index];
    }
    std::cout << " ";
    for (int index = 24; index < 32; index++) {
        std::cout << ve[index];
    }
}

int main(int argc, const char * argv[]) {
    int_to_char(-2);
    return 0;
}
-2 :11111110 11111111 11111111 11111111
    低位                          高位
2:  00000010 00000000 00000000 00000000
-5: 11111011 11111111 11111111 11111111

结论:
1 数据倒着存储
2 负数在计算机中是以该负数的二进制的补码形式
存储的。
比如2的反码是 11111101 11111111 11111111 11111111
补码是(反码 + 1 ,在低位加1) 11111110 11111111 11111111 11111111
在有符号数中,正数第一位是0,负数第一位是1
(高位字节的第一位就是符号位)


浮点型的存储方式
float 单精度浮点型 1位符号位 8为阶码位 23位尾位
double 双精度浮点型 1位符号位 11位阶码位 52位尾位

以double为例

void d_to_b(double d) { //double转化为内存中的二进制表示
    std::vector<int> ve;
    union  {
        double a;
        struct  {
            unsigned char a1, a2, a3, a4, a5, a6, a7, a8;
        } b;
    } t;
    t.a = d;
    c_to_b(t.b.a8, ve); // 已经确实是倒着存储了,这里手动把他反过来
    c_to_b(t.b.a7, ve);
    c_to_b(t.b.a6, ve);
    c_to_b(t.b.a5, ve);
    c_to_b(t.b.a4, ve);
    c_to_b(t.b.a3, ve);
    c_to_b(t.b.a2, ve);
    c_to_b(t.b.a1, ve);
    std::cout << "符号位:" << ve.at(0) << " ";
    std::cout << "阶码:";
    for (int index = 1; index < 12; index++) {
        std::cout << ve.at(index);
    }
    std::cout << std::endl << "尾码:";
    for (int index = 12; index < 64; index++) {
        std::cout << ve.at(index);
    }
    std::cout << std::endl;
}
7.3:
符号位:0 阶码:10000000001
尾码:1101001100110011001100110011001100110011001100110011

7.5:
符号位:0 阶码:10000000001
尾码:1110000000000000000000000000000000000000000000000000

来看一道题目

printf("%d",7.5f); // 输出是多少?

(在VS2005上运行的时候是0 ,在Xcode里是一堆数)

解释一下为什么是0,7.5f在内存中的存储已经知道了,而%d是读取32位,很明显尾数的7.5f都是0

也不是所有浮点数这样输出都是0,试试7.4

在Mac中尝试了一下,。。。竟然是随机数。。。神奇的事情,有待研究。

指针的应用

指针是从低位开始的

int main(int argc, const char * argv[]) {
    int num = 1;
    int *p1 = &num;
    char *p2 = p1;
    char *p3 = p2 + 1;
    *p3 = 3;
    printf("%d", *p1);

    return 0;
}
// 低位                        高位
// 00000001 00000000 00000000 00000000
// p1
// p2
//          p3
// 00000001 00000011 00000000 00000000
// 倒回来读00000000 00000000 00000011 00000001 = 512+256+1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值