8.深度剖析数据在内存中的存储(C进阶)

目录

一.数据类型介绍

1.类型的基本归类

二.整型在类型中的存储

2.1 原码、反码、补码

2.2 大小端介绍

三.练习

四.浮点型在内存中的存储

1.一个例子

2.浮点数存储规则


一.数据类型介绍

基本的内置类型:

char----1字节 //  字符类型数据

int------4字节//整型

short---2字节//短整型

long----4字节(32位) 8字节(64位)//长整型

longlong-8字节//更长整型

float---4字节//单精度浮点数

double--8字节//双精度浮点数

类型的意义:

a. 使用这个类型开辟内存空间的大小(大小决定了使用范围)
b. 如何看待内存空间的视角

1.类型的基本归类

浮点数家族:

float

double

二.整型在类型中的存储

一个变量的创建是要在内存中开辟空间的 空间的大小是根据不同类型而决定的

那么好了好了接下来就是弄清楚数据在内存中是怎样存储的

2.1 原码、反码、补码

首先就是搞清楚 原码 反码 补码的概念

三种表示方法均有符号位和数值位两部分 符号位都是用0表示“正” 用1表示“负” 而数值位正数的原、反、补码都相同

负整数的三种表示方法各不相同:

原码:直接将数值按照正负数的形式翻译成二进制就可以得到原码

反码:将原码的符号位不变 其他位依次按位取反就可以得到反码

补码:反码+1就得到补码

2.2 大小端介绍

这时就涉及到大端和小端

关于大端(存储)模式:是指数据的低位保存在内存的高地址中 而数据的高位 保存在内存的低地址

关于小端(存储)模式:是指数据的低位保存在内存的低地址中 而数据的高位 保存在内存的高地址

为什么有大端和小端?

三.练习

//设计常规函数来解决
#include <stdio.h>
int skycheck(int i)
{
    return(*(char*)&i);
}
int main(void)
{
    int i = 1;
    int ret = skycheck(i);
    if(ret == 1)
    {
        printf("小端\n");
    }
    else
        printf("大端\n");
    
    return 0;
}
//用联合体来解决
int skycheck(void)
{
    union
    {
        int i;
        char c;
    }u;
    u.i = 1;
    return u.c;
}

#include <stdio.h>
int main()
{
    char a = -1;
    //    //10000000000000000000000000000001
    //    //11111111111111111111111111111110
    //    //11111111111111111111111111111111
    //    //11111111 - 截断
    //    //整型提升
    //    //11111111111111111111111111111111
    //    //11111111111111111111111111111110
    //    //10000000000000000000000000000001 -1
    //
    signed char b = -1;
    //    //-1
    //
    unsigned char c = -1;
    //    //10000000000000000000000000000001
    //    //11111111111111111111111111111110
    //    //11111111111111111111111111111111
    //    //00000000000000000000000011111111
    //    //
    printf("a=%d,b=%d,c=%d", a, b, c);
    //
    return 0;
}

#include <stdio.h>
int main()
{
    char a = -128;
    //   1000 0000 0000 0000 0000 0000 1000 0000
    //   1111 1111 1111 1111 1111 1111 0111 1111
    //   1111 1111 1111 1111 1111 1111 1000 0000
    //   1000 0000
    //   因为是char 类型即 1代表为负数
    //   1111 1111 1111 1111 1111 1111 1000 0000
    //   以无符号 u 打印 视作正数 原 反 补 相同即4294967168
    printf("%u\n", a);

    return 0;
}

#include <stdio.h>
int main()
{
    char a = 128;
    //   0000 0000 0000 0000 0000 0000 1000 0000
    //   1000 0000
    //   因为是char 类型即 1代表为负数
    //   1111 1111 1111 1111 1111 1111 1000 0000
    //   以无符号 u 打印 视作正数 原 反 补 相同即4294967168
    printf("%u\n", a);

    return 0;
}

#include <stdio.h>
int main()
{
    int i= -20;
    //   1000 0000 0000 0000 0000 0000 0001 0100    -20
    //   1111 1111 1111 1111 1111 1111 1110 1011
    //   1111 1111 1111 1111 1111 1111 1110 1100
    unsigned int j = 10;
    //   0000 0000 0000 0000 0000 0000 0000 1010    10
    printf("%d\n", i+j);
    //   1111 1111 1111 1111 1111 1111 1111 0110
    //   1111 1111 1111 1111 1111 1111 1111 0101
    //   1000 0000 0000 0000 0000 0000 0000 1010    -10
    return 0;
}

#include <stdio.h>
int main()
{
    unsigned int i;
    for(i = 9; i >= 0; i--)
    {
        //当打印到0后 开始从-1以无符号数开始打印
        printf("%u\n",i);
    }
    return 0;
}

#include <stdio.h>
#include <string.h>
int main()
{
        char a[1000];
        int i;
        for(i=0; i<1000; i++)
        {
          a[i] = -1-i;
        }
        printf("%d",strlen(a));  //255
    return 0;
}

四.浮点型在内存中的存储

常见的浮点数:
1E10
3.14159
浮点数家族包括: float、double、long double 类型

浮点数的表示范围:float.h中定义

1.一个例子

讲解在最后哦

2.浮点数存储规则

要理解上面的结果 就要弄清楚浮点数在计算机内部的表示方法

根据国际标准IEEE(电气和电子工程协会) 754 任意一个二进制浮点数V可以表示成下面的形式: 

(-1)^S * M * 2^E

(-1)^S表示符号位 当S=0 V为正数;当S=1 V为负数

M表示有效数字 大于等于1 小于2

2^E表示指数位

举例来说:

十进制的5.0 写成二进制是 101.0  相当于 1.01×2^2 。
那么 按照上面V的格式 可以得出S=0,M=1.01,E=2。

十进制的-5.0 写成二进制是 -101.0 相当于 -1.01×2^2                                                                         那么 S=1,M=1.01,E=2

#include<stdio.h>
int main(void)
{
    int n = 9;
//    //00000000000000000000000000001001 - 9的补码
//    //
//    //0 00000000 00000000000000000001001
//    //E = 1-127 = -126
//    //M = 0.00000000000000000001001
//    //(-1)^0 * 0.00000000000000000001001 * 2^-126
//    //
    float* pFloat = (float*)&n;

   printf("n的值为:%d\n", n);
   printf("*pFloat的值为:%f\n", *pFloat);//0.0
//    *pFloat = 9.0;//以浮点数的视角,存放浮点型的数字
//    //1001.0
//    //1.001 * 2^3
//    //(-1)^0 * 1.001 * 2^3
//    //S=0
//    //E=3
//    //M=1.001
//    //0 10000010 00100000000000000000000
//    //
   printf("num的值为:%d\n", n);//1,091,567,616
   printf("*pFloat的值为:%f\n", *pFloat);//9.0
   return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值