C语言-数据在内存中的存储(万字详解)

本文详细探讨了C语言中数据类型的分类,包括整型、浮点型、构造类型和指针类型等。重点讲解了整型在内存中的存储,包括原码、反码、补码的概念,以及大小端字节序的原理。同时,文章还介绍了浮点型的存储方式,按照IEEE 754标准解析浮点数在内存中的表示。通过实例和练习,帮助读者深入理解数据在内存中的存储机制。
摘要由CSDN通过智能技术生成

目录

1. 数据类型

1.1 类型的归类:

整型家族:

浮点数家族:

构造类型:(自定义类型 - 我们可以自己创建出新的类型)

指针类型:

空类型(void):

2. 整形在内存中的存储

2.1 原码、反码、补码

2.2 大小端字节序

2.3 练习

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

3.1 浮点数存储的例子:

3.2 浮点数在内存中的存储方式


1. 数据类型

char        //字符数据类型 1byte
short       //短整型 2byte
int         //整形 4byte
long        //长整型 4or8byte   C语言只规定了:sizeof(long)>= sizeof(int)
                                    32位下:4byte   64位下:8byte
long long   //更长的整形 8byte C99中引入的long long
float       //单精度浮点数 4byte
double      //双精度浮点数 8byte
//C语言有没有字符串类型?
答:C语言没有字符串类型,字符串一般都是通过char类型的数组来存储的

类型的意义:

1. 类型决定了类型开辟内存空间的大小。

2. 内存空间的视角代表了变量的类型。

1.1 类型的归类:

整型家族:

字符的本质在内存中是ASCII码值,是整型,所以划分到整型家族)
VS下: char与signed char等价
char
unsigned char
signed char
char是signed char还是unsigned char,C语言标准是未定义的,这取决于编译器的实现

short <--> signed short(等价)
unsigned short [int]
signed short [int]

int <--> signed int(等价)
unsigned int
signed int

long <--> signed long(等价)
unsigned long [int]
signed long [int]

long long <--> signed long long(等价)
unsigned long long [int]
signed long long [int]

那为什么会分为unsigned和signed类型呢?

答:在现实生活中有些数据是没有负数的,比如:身高、体重、长度

int a=0;a是一个整型,有符号整型,一个整型是四个字节==32bit
0 0000000 00000000 00000000 00000000
第一位是符号位,后面的31位才是有效位
符号位是0,表示正数
符号位是1,表示负数
有正有负的数据,比如:温度这个时候就需要signed类型的


而身高、体重、长度这些没有负数的数据
使用unsigned类型
unsigned int b=0;
00000000 00000000 00000000 00000000
32位全部是有效位

浮点数家族:

(只要是表示小数,就可以使用浮点型)

float //float的精度低,存储的数值范围较小
double//double精度高,存储的数值范围较大

构造类型:(自定义类型 - 我们可以自己创建出新的类型)

数组类型   int arr[5];   类型是int[5]
结构体类型 struct
枚举类型 enum
联合类型 union

指针类型:

int *pi; //类型是int*
char *pc;
float* pf;
void* pv;//类型void* 

空类型(void):

void 表示空类型(无类型)
通常应用于函数的返回类型(表示没有返回值)、函数的参数(表示没有不需要传参)、
指针类型(void*)

//第一个void,表示函数没有返回值
//第二个void,表示函数不需要传任何参数
void test(void)
{
        printf("hehe\n");
}
int main()
{
        test(1);//如果传参也不会报错,会出现警告,只不过test函数不会使用该参数,
                //如果函数参数是void,那么最好不要传参数,防止写出bug
        return 0;
}

2. 整形在内存中的存储

变量创建需要开辟内存空间,而内存空间的大小是根据类型决定的。

2.1 原码、反码、补码

如果我们想要知道整型是怎样在内存中存储,那我们首先需要了解到计算机中整数的三种表示形式,即:原码、反码、补码。

三种表示方法均有符号位和数值位两部分,

符号位:用0表示“正”,用1表示“负”,

数值位

正整数的原、反、补码都相同。

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

原码
直接将数值转换成二进制

反码
原码的符号位不变,其他位按位取反

补码
反码+1

例:

int main()
{
        int a = 20;//内存中展示:0x0113FA38  14 00 00 00
        //00000000 00000000 00000000 00010100 -
        //   00       00       00       14
        // 0x00 00 00 14 -- 16进制
        //00000000 00000000 00000000 00010100
        //00000000 00000000 00000000 00010100

        int b = -10;//内存中展示:0x0113FA2C  f6 ff ff ff
        //10000000 00000000 00000000 00001010--原码
        // 0x80 00 00 0a
        //11111111 11111111 11111111 11110101--反码
        // 0xff ff ff f5
        //11111111 11111111 11111111 11110110--补码
        // 0xff ff ff f6

        //所以说内存中存的是补码
        return 0;
}

对于整型来说:数据存放内存中其实存放的是补码。

为什么会存放补码呢?

因为1.使用补码,可以将符号位和数值域统一处理;2.加法和减法也可以统一处理(CPU只有加法器)3.补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。

对2进行说明:

怎样实现1-1呢?
1+(-1)

00000000 00000000 00000000 00000001
10000000 00000000 00000000 00000001
如果是原码相加后:
10000000 00000000 00000000 00000010 -- -2
由此可见原码相加得到的结果不是我们想要的

00000000 00000000 00000000 00000001
11111111 11111111 11111111 11111111
而补码相加后:
1 00000000 00000000 00000000 00000000 -- 32位就是0
所以说补码相加后才能得到我们想要的结果

对3进行说明:(也就是补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。

这句话是什么意思呢?

首先我们可以从上面知道

//原码:直接通过正负的形式写出的二进制序列就是原码
//反码:原码的符号位不变,其它位按位取反得到反码
//补码:反码+1就是补码

同理我们倒推回去:

原码就等于补码-1变反码,反码符号位不变再取反得到原码。

而补码与原码相互转换,其运算过程是相同的,这句话意思就是:

补码取反+1也可以得到原码

例:

int b = -10;//内存中展示:0x0113FA2C  f6 ff ff ff
//10000000 00000000 00000000 00001010--原码
//11111111 11111111 11111111 11110101--反码
//11111111 11111111 11111111 11110110--补码

//10000000 00000000 00000000 00001001 - 补码取反
//10000000 00000000 00000000 00001010 - 补码取反后+1-> 原码 -10

//或者
//11111111 11111111 11111111 11110101 - 补码-1,变反码
//10000000 00000000 00000000 00001010 - 取反变原码

2.2 大小端字节序

int main()
{
    int a=20;
    //
    int b=-10;
    return 0;
}

//我们可以在内存窗口中看到
//a的存储方式
//14 00 00 00
//b的存储方式
//f6 ff ff ff

但其实我们在上面会知道
a的十六进制表示形式是:0x00 00 00 14
b的十六进制表示形式是:0xff ff ff f6

我们会发现顺序有点不对劲,这就引出了大小端的问题

什么是大端小端呢?(取决于硬件)

大端(存储)模式,是指数据的低位保存在内存
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值