C语言进阶(数据在内存中的存储)

一、数据类型

1.数据类型的意义

          (1)让程序员更好地描述生活中的各种问题
          (2)使用这个类型开辟内存空间的大小
                   char—1字节      short—2字节      int—4字节      long—4字节
                   long long—8字节      float—4字节      double—8字节
          (3)提供了看待内存空间的视角

2.数据类型的分类

❤️2.1 整型
char 在内存中以ASCII的形式进行存储
    unsigned(无符号的) char
    signed(有符号的) char
int
    unsigned int        无符号的整型
    signed int        有符号的整型

short
    unsigned short [int]        int可以省略(unsigned short a == unsigned short int a)
    signed short [int]        int可以省略

long
    unsigned long [int]
    signed long [int]

long long
    unsigned long long [int]
    signed long long [int]

除了char类型,一般数据类型是默认有符号的,即 int == signed int,但是char类型要取决于编译器

❤️2.2 浮点型
float        单精度浮点数

double        双精度浮点数

❤️2.3 构造类型(自定义类型)
数组类型        int [10]    char [11]

结构体类型         struct

枚举类型         enum

联合类型         union

❤️2.4 指针类型
int* pa        char* pa         float* pa         void* pa(没有具体类型的指针)

❤️2.5 空类型
void — 空类型(无类型),可以应用于函数的返回类型,函数的参数,指针类型,如void arr(void )和void* pa

二、整型的存储

2.1 以补码的形式保存

整型数值可以由各种位进行表示,如10在二进制中是1010,八进制中是12,16进制中是A,虽然表现的形式不一样,但是都是同一个数值。

二进制主要有三种形式,即原码、反码、补码(点击看原码、补码、反码的详细介绍),电脑的数值是以原码的大小打印的,但是内存上的存储和表示是以补码进行的

但是为什么不以原码或者反码来进行表示呢,这取决于补码有三点优势:
       (1)可以把符号位和数值域统一处理
       (2)可以加法、减法统一处理(CPU中只有加法处理器),如1 - 1在CPU中的运算是1 + (-1)
       (3)补码和原码之间的转换方式都是"取反 + 1",不需要额外的步骤

2.2 大小端问题

首先,我们需要了解为什么会有大小端这个问题?

假设有一个整型a,已知整型是4个字节,但是一个内存单元是1个字节,这4个字节是已怎样的顺序存储进去的,是没有明确规定的,我们可以顺着放、反着放、随机放,只要这个数据方便你取和存,实际上并没有什么优劣之分。

其次,什么是大小端?

基于上面的了解,我们可以先得出,存储是以一个字节为单位的,也就是说大小端更准确的说是“大小端字节序存储”。然后大端是把高位的字节放在低地址处,低位的字节放在高地址中,小端则相反。

那么什么是低位,数学中1234这个四位数,分别有个位、十位、百位、千位,那么个位即是最低位。对应到编程中,整型10的补码是00000000 00000000 00000000 00001010,转为16进制即为00 00 00 0a,那么0a就是最低位的字节

如下图,VS2019版本所使用的是小端存储
在这里插入图片描述

2.3 例子解析

#include <stdio.h>
int main()
{
    char a= -1;          
    signed char b=-1;
    unsigned char c=-1;
    printf("a=%d,b=%d,c=%d",a,b,c);
    return 0;
}

答案:-1 -1 255

解析:
    数值就像是一块蛋糕,本身的大小是不会改变的,而类型就像是不同尺寸的刀具,-1是整型放到char类型中,需要发生【截断】,又因为内存中储存的是补码,所以原本32bit的
11111111 11111111 11111111 11111111 截断为8bit的11111111,即a内存中存储的是8个1。

    b和c与a同理,里面存的都是8个1,只不过c是无符号的char类型,最高位不是符号位。

    %d的意思是“打印有符号的整数”,所以需要【整型提升】,有符号的补符号位,无符号的补0,所以a、b内部储存为11111111 11111111 11111111 11111111,所以打印的数值需要转换为原码,为-1。c内部储存为00000000 00000000 00000000 11111111,由于是无符号的,不需要转换,所以是255

四、浮点型的存储

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

根据国际标准IEEE754,任意一个二进制浮点数V可以表示成(-1)^S * M * 2^E这种形式

  • (-1)^S表示符号位,当S=0,V为正数;当S=1,V为负数。
  • M表示有效数字,大于等于1,小于2。
    • 因为都是1.XXXXX,所以储存时省略了1,只保留XXXXX,等到读取的时候再加上1,可以提高精度
  • 2^E表示指数位,E是无符号整数
    • E为8位:0 <= E <= 255                E为11位:0 <= E <= 2047
    • 存入内存时E的真实值需要加上一个真实值(因为指数是有为负数的情况的,但是E的范围不允许),如果E为8位,需要加127,E是11位则加1023
    • E在内存中的三种情况
      • E不全为0或不全为1:指数E的计算值减去127或1023,得到真实值,再将有效数字M前加上第一位的1
      • E为全0:指数E等于1-127或1-1023,有效数字不加上1,而是还原成0.XXXX,表示±0或一个无穷小的数
      • E全为1:表示±无穷大

4.2 float 和 double 的存储模型

1.float
在这里插入图片描述

2.double
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值