【C语言进阶】1. 数据的存储

1.数据类型的介绍

在这里插入图片描述
long 长整型 4/8个字节
在C语言的定义中只规定了sizeof(long)>=sizeof(int)
在32位平台long为4个字节,在64位平台int为8个字节
类型的意义
1.使用这个类型所开辟的内存空间
2.如何看待内存空间的视角
int/float类型都是4个字节但是内存布局不一样

1.1数据类型的划分

在这里插入图片描述
char 到底是signed char 还是unsigned char 标准是未定义的,取决于编译器。
short、int、long、long long这些都是signed 类型(有符号类型)
有无符号的区别:
有符号,符号位0表示是正数,符号位1表示是负数。
无符号,第一位也是数值位为1表示2^31。
在这里插入图片描述
在这里插入图片描述
int [ 5 ] /int [ 8 ] …都是不同类型
在这里插入图片描述在这里插入图片描述

2.整型在内存中的存储

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

2.1 原码、反码、补码

在这里插入图片描述
0b表示二进制 0表示八进制 0x表示16进制
在这里插入图片描述
在这里插入图片描述
数据在内存中存储是以二进制的形式,这些0x只是为了方便在内存窗口观察
整数在内存中的存储是补码的形式
在这里插入图片描述
在这里插入图片描述
如果计算机以原码的形式存储 -1+1计算结果为-2,明显不正确 而以补码的形式存储计算结果就是0
补码与原码的相互转换,其运算过程是相同的
原码得到补码取反加1;补码得到原码取反加1;

2.2 大小端的介绍

在这里插入图片描述
数据在内存中的存储形式可以是五花八门的,只要能从内存中取出数据即可,但是奇奇怪怪的方式并不适合计算机取出数据,于是就保留下来两种方式大端存储,小端存储
在这里插入图片描述
这里的11 22 33 44只是为了方便表示,实际上数据在内存中还是以二进制进行存储
在这里插入图片描述
通过代码来判断计算机是大端字节序还是小端字节序
在这里插入图片描述
小端:0x 01 00 00 00 大端:0x 00 00 00 01
取出a的地址 int 类型 一次访问四个字节,进行强制类型转换 char* 取出的是第一个字节的地址再解引用判断大端小端
不管是浮点型还是整型只要是有多个字节的,就存在大小端字节序
在这里插入图片描述
signed char -127~128(10000000不用计算原反补,直接当做-128)
unsigned char 0~255

2.3 练习

1.

在这里插入图片描述
打印出来的是-1,-1,255
-1在内存中存储形式为补码:11111111111111111111111111111111
将-1放入char中会发生截断(截断都发生在存储过程)
a,b中存放的就是:11111111(补码形式)
又要将a,b以%d的形式打印出来发生整型提升
a,b都是有符号类型(符号位为1)全补1
11111111111111111111111111111111(补码)
转换成原码就是-1
c中同样存放的是11111111 发生整形提升,c是unsigned 所以全补0
认为其是正数 原反补相同,所以打印出来为255
这里的截断与大小端无关,(隐式类型转换)只是将int类型的最后几位截取后存放到char类型变量当中
大小端是指在内存中存储的字节序形式

2.

在这里插入图片描述
整型提升全补1以%u的形式打印出来数值很大
在这里插入图片描述

3.

在这里插入图片描述
给char类型赋值128时, 截取得到的还是10000000
所以在进行整型提升时,char是有符号类型的,符号位为1,全补1
在这里插入图片描述
结果与上面2题相同

4.

在这里插入图片描述
unsigned int类型与int类型相加 会自动发生类型转换 转化成unsigned int类型 但是这里的printf打印形式是以有符号整型的形式打印
将1111111111111111111110110看做补码,就是负数的形式(要进行原反补的转化),结果就是 - 10

5.

判断打印出来的是什么?
在这里插入图片描述
在这里插入图片描述
i 是无符号整型,所以所有的二进制位都是有效位 9~0,0-1 就是-1
-1是以补码的形式存放在内存中全为1,-1以无符号整型表示是很大的数字
i永远不会小于0,所以就是一直死循环的状态。
在这里插入图片描述

6.

在这里插入图片描述
如果不加思索,-1,-2,-3,-4…-1000
循环1000次
但是数组当中的元素是char类型
char的范围是-128~127
表达式 a[ i ](char) = -1 - i (int);会发生截断
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
所以strlen算出的长度应该为255

7.

在这里插入图片描述
当unsigned char 为255时 再加一又变为0 ,所以也是死循环

8.

在这里插入图片描述
在C语言定义当中strlen返回值是size_t类型
size_t 就是unsigned int
因为计算字符串长度是不可能返回负数的,所以设计成无符号整型
两个strlen进行相减,返回的也是无符号整型,所以恒大于0 只可能打印出>
而采用my_strlen 模拟函数,返回值是int类型,则不会出现上述的情况(各有利弊)

3.浮点数在内存中的存储(重点)

常见的浮点数:
3.14159
1E10
浮点数家族包括: float、double、long double 类型。
浮点数表示的范围:float.h中定义(整型的定义在limits.h当中)
1E10 就是1.0*1010 科学计数法

3.1 一个例子

在这里插入图片描述
将int类型的地址类型转换成float的形式 分别以整型和浮点数的形式取出
将n中的值修改为9.0浮点数类型 分别以整型和浮点数的形式取出
如果浮点数和整型在内存中的存储形式是一致的,那么打印出来的将是9 , 9.0 , 9 , 9.0
但是结果如下
在这里插入图片描述
这个案例说明了浮点数与整型在内存中的存储形式不一样

3.2 浮点数存储规则

浮点数的二进制表示:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
小数点后面的位置从2-1 ,2-2 … 所以,小数点第一位是0.5 ,第二位是0.125. …
在这里插入图片描述
如果存储类似于9.6的浮点数,那么可能永远无法精确的表示出 .6这小数点位,而且float(double)类型只有32(64)个比特位
无法存放下后面的数字,导致精度丢失
浮点数在内存中无法精确保存
float类型的数据
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
f在内存中的存储形式

取出情况
在这里插入图片描述
在这里插入图片描述
当E为全0时,真实值为-126或者-1022 , xxxxx*2-126这是非常小的,232 已经是42亿
在这里插入图片描述
同理,全1就是+126 ,就是存储非常大的数值

3.3 解释上面例子

在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值