当前位置:网站首页>数据的存储(进阶)
数据的存储(进阶)
2022-06-22 05:29:00 【头发没有代码多】
目录
数据类型介绍
char //字符数据类型short //短整型int //整形long //长整型long long //更长的整形float //单精度浮点数double //双精度浮点数类型的意义:
1. 使用这个类型开辟内存空间的大小(大小决定了使用范围)。2. 如何看待内存空间的视角
类型的基本归类:
整形家族:
char //char'类型的本质是ASCII码值,所以在整形里面unsigned charsigned charshortunsigned short [int]signed short [int]intunsigned intsigned intlongunsigned long [int]signed long [int]
一般情况下int a,此时a是signed int类型,而char不一样char a,a此时是signed char还是unsigned char这个C语言标准是未定义的,由编译器决定char是signed还是unsigned
浮点型家族
floatdouble浮点型家族:只要是表示小数就可以使用浮点型,flaot 的精度低,存储的数值范围较小,double的精度高,存储的数据的范围更大。
构造类型:
> 数组类型> 结构体类型 struct> 枚举类型 enum> 联合类型 union
指针类型
int *pi;char *pc;float* pf;void* pv;
空类型:
void 表示空类型(无类型)通常应用于函数的返回类型、函数的参数、指针类型。

红色框表示函数不需要返回值,蓝色框表示函数不需要参数,但如果我们硬给函数传参,函数会正常运行,只不过是没有接收参数罢了 ,俩个void其实都课省略,但最好不要进行省略
整形在内存中的存储
int a = 20;int b = -10;我们知道为 a 分配四个字节的空间。 那如何存储? 下来了解下面的概念:
原码、反码、补码
计算机中的整数有三种2进制表示方法,即原码、反码和补码。三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”,而数值位正数的原、反、补码都相同。负整数的三种表示方法各不相同。
原码
直接将数值按照正负数的形式翻译成二进制就可以得到原码。
反码
将原码的符号位不变,其他位依次按位取反就可以得到反码。
补码
反码+1就得到补码。 在计算机中整形数据以补码的形式进行存储
前面的博客有涉及到原码反码补码的一些知识和二进制下的计算
在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理(CPU只有加法器)此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。
原反补转换法则
方法一
一、正整数的原码、反码、补码完全一样,即符号位固定为0,数值位相同
二、负整数的符号位固定为1,由原码变为补码时,规则如下:
1、原码符号位1不变,整数的每一位二进制数位求反,得到反码
2、反码符号位1不变,反码数值位最低位加1,得到补码
补码得原码:补码-1得反码,反码符号位不变其余位取反得原码
方法二
一、正整数的原码、反码、补码完全一样,即符号位固定为0,数值位相同
补码得原码:补码符号位不变其余位按位取反,取反之后得结果+1得到原码
-1和1以补码的形式进行相加, 加完之后为33位,多出一位。然后去掉最高位就得到最终结果的补码

大小端介绍
什么大端小端:
大端(存储)模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中;小端(存储)模式,是指数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地址中。

我们在编译器中运行可发现数据是反着存的,为什么要倒着放呢?
这里如11 22 33 44,其实这些数据在内存中是可以随便放的,但是使用的时候必须得原样拿出,如数据本来是11 22 33 44,存放形式 33 22 11 44,但是使用的时候必须按11 22 33 44使用,即拿出来的时候必须得恢复原样,但是乱序存储过于麻烦,一般选择正序存储或倒序存储
我们把这俩中方式分别称为大端字节序存储和小端字节序存储
大端字节序存储:
把一个数据的高位字节序的内容存放在低地址处,把低位字节序的内容放在高地址处,就是大端字节序存储。
小端字节序存储:
把一个数据的低位字节序的内容存放在低地址处,把高位字节序的内容放在高地址处,就是小端字节序存储。
一个字节看不出大小端的顺序
为什么有大端和小端:
为什么会有大小端模式之分呢?这是因为在计算机系统中,我们是以字节为单位的,每个地址单元 都对应着一个字节,一个字节为8 bit。但是在C语言中除了8 bit的char之外,还有16 bit的short 型,32 bit的long型(要看具体的编译器),另外,对于位数大于8位的处理器,例如16位或者32 位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何将多个字节安排的问题。因 此就导致了大端存储模式和小端存储模式。例如:一个 16bit 的 short 型 x ,在内存中的地址为 0x0010 , x 的值为 0x1122 ,那么 0x11 为 高字节, 0x22 为低字节。对于大端模式,就将 0x11 放在低地址中,即 0x0010 中, 0x22 放在高 地址中,即 0x0011 中。小端模式,刚好相反。我们常用的 X86 结构是小端模式,而 KEIL C51 则 为大端模式。很多的ARM,DSP都为小端模式。有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。简单来说:一个数据有若干个字节,至于如何在内存中存放,就产生了大小端问题
习题:如何判断当前机器是大端还是小端存储
#include<stdio.h>
int check(int a)
{
return *(char*)&a;
}
int main()
{
int a = 1;
check(a);
if (check)
printf("小端存储\n");
else
printf("大端存储\n");
return 0;
}

练习题
#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;
}有符号的char取值范围-128-127,
其它数字均可按照原码,反码,补码转换规则,算出来,但是10000000不能这样算,直接人为是-128
unsigned char的取值范围是0-255,应为无符号数没有负数


short类型占俩个字节,也就是16个二进制数字,取值范围在下面


这里的C为什么是255?看下面图解


习题2
#include <stdio.h>
int main()
{
char a = -128;
printf("%u\n",a);
return 0;
}

习题3
#include <stdio.h> int main() { char a = 128; printf("%u\n", a); printf("%d\n", a); return 0; }
这个跟前面的题一样都是先发生截断,然后整形提升,然后再打印
习题4
#include <stdio.h>
int main()
{
int i = -20;
unsigned int j = 10;
printf("%d\n", i + j);
return 0;
}
习题5 unsigned三码习题
#include<stdio.h> int main() { unsigned int i; for (i = 9; i >= 0; i--) { printf("%u\n", i); } return 0; }

我们看到这里9-0都是正常打印但是到-1就出现了问题,具体原因请看下图


二进制下的32个1,换成十进制为一个特别大的数字,所以会打印4294967295,之后每次i--这个数都会减一
习题6 signed char取值范围问题
#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)); return 0; }
这里把数字放入到数组a中,而a是char类型,范围为-128~127
这里是-1-i,其实就是上面这个图逆序的走法,从-1~-128~127~0
\0的ASCII码值是0,strlen遇到\0会停下来,所以在遇到0之前,数组里面已经存了128+127个数字了,所以打印255
习题7 无符号char取值范围习题
#include<stdio.h> unsigned char i = 0; int main() { for (i = 0; i <= 255; i++) { printf("hello world\n"); } return 0; }
程序运行后会进入死循环,这是因为i是unsigned char类型范围是0~255,前面有说过,i为255之后,i+1,此时i又变为0,陷入死循环
习题8 关于strlen返回值类型的习题
#include<stdio.h> #include<string.h> int main() { if (strlen("abc") - strlen("abcdef") >= 0) printf(">"); else printf("<"); return 0; }
这里会打印>是因为strlen返回值为unsigned int类型,无论怎样运算结果都>=0.
浮点型在内存中的存储
浮点数家族包括: float、double、long double 类型。浮点数表示的范围:float.h中定义用everything查找float.h然后用VS打开,就可看到浮点数的范围,整形输入litmits.h可查看范围
浮点数存储规则
根据国际标准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。9.5f9.5f其实用二进制表示为:1001.1,这跟权重有关系,因为2^-1为0.5
1001.1=1.0011*2^3
S=0,M=1.0011,e=3
例:9.6f
二进制:1001.XXXXXX,因为这个0.6不好表示,需要一堆0和1,但是如果数字过多就有可能存不下,因此浮点数就产生了精度问题
float 4byte double 8byte
浮点数如何保存
IEEE 754规定:对于32位的浮点数,最高的1位是符号位s,接着的8位是指数E,剩下的23位为有效数字M。
对于64位的浮点数,最高的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M。
特别规定:
前面说过, 1≤M<2 ,也就是说,M可以写成 1.xxxxxx 的形式,其中xxxxxx表示小数部分。IEEE 754规定,在计算机内部保存M时,默认这个数的第一位总是1,因此可以被舍去,只保存后面的 xxxxxx部分。比如保存1.01的时 候,只保存01,等到读取的时候,再把第一位的1加上去。这样做的目的,是节省1位有效数字。以32位 浮点数为例,留给M只有23位, 将第一位的1舍去以后,等于可以保存24位有效数字。
指数E的存放规则
首先,E为一个无符号整数(unsigned int),这意味着,如果E为8位,它的取值范围为0~255;如果E为11位,它的取值范围为0~2047。如0.5=1.0*2^-1 M=1.0,E=-1,S=0E为负数不在范围之内,所以 IEEE 754规定,存入内存时E的真实值必须再加上一个中间数:对于8位的E(float),这个中间数是127。对于11位的E(double),这个中间数是1023。刚才E=-1,按float类型,E+127=126,把126存放到E所在的空间当中(8个bit)
结果一致,为小端存储
浮点数如何往出拿
E不全为0或不全为1
这时,浮点数就采用下面的规则表示,即指数E的计算值减去127(或1023),得到真实值,再将有效数字M前加上第一位的1。比如:0.5(1/2)的二进制形式为0.1,由于规定正数部分必须为1,即将小数点右移1位,则为1.0*2^(-1),其阶码为-1+127=126,表示为01111110,而尾数1.0去掉整数部分为0,补齐0到23位00000000000000000000000,则其二进制表示形式为:0 01111110 00000000000000000000000

存放E的空间全为0
这时,浮点数的指数E等于1-127(或者1-1023)即为真实值,有效数字M不再加上第一位的1,而是还原为0.xxxxxx的小数。这样做是为了表示±0,以及接近于 0的很小的数字。
存放E的空间全为1
这时,如果有效数字M全为0,表示±无穷大(正负取决于符号位s);
浮点数列题
#include<stdio.h> int main() { int n = 9; float* pFloat = (float*)&n; printf("n的值为:%d\n", n); printf("*pFloat的值为:%f\n", *pFloat); *pFloat = 9.0; printf("num的值为:%d\n", n); printf("*pFloat的值为:%f\n", *pFloat); return 0; }
所以会打印0.0000000000
边栏推荐
- count registers in C code -- registers has one pattern
- c files always get rebuild when make -------- .PHONY in Makefile
- Analysis of 43 cases of MATLAB neural network: Chapter 28 Application Research of decision tree classifier - breast cancer diagnosis
- Detailed explanation of OpenCV function usage 11~20, including code examples
- LeetCode热题 HOT1-50
- 《MATLAB 神经网络43个案例分析》:第29章 极限学习机在回归拟合及分类问题中的应用研究——对比实验
- 大厂晋升学习方法三:链式学习法
- 毕业季 | 新的开始,不说再见
- Force deletion of namespaces in terminating state
- What are the high availability designs of yarn?
猜你喜欢

ActiveMQ knowledge summary of Message Oriented Middleware

基于WebUploader实现大文件分片上传

Kubernetes - bare metal cluster environment

【毕业季·进击的技术er】一个读研学生的唠唠嗑

《MATLAB 神经网络43个案例分析》:第28章 决策树分类器的应用研究——乳腺癌诊断

Six sides tmall has already offered. After a review of my experience, is it really that difficult to enter a big factory?

P1318 积水面积

记本地项目启动报错:无效的源发行版: 8
![[graduation season · advanced technology Er] a graduate student's chatter](/img/c2/dc77b8ffecfcb0a495e1dc8b6e7922.png)
[graduation season · advanced technology Er] a graduate student's chatter

Graduation feedback! All contributors of Apache Doris community come to receive gifts!
随机推荐
Performance analysis and test of interprocess communication methods under dual core real-time system
部署SuperMap iServer war包时的服务迁移
postmanUtils工具类,模拟postman的get,post请求
新手开店货源怎么找,怎么找到优质货源?
Talk about MySQL's locking rule "hard hitting MySQL series 15"
JS regular expression to implement the thousands separator
Tidb performance overview panel
从JedisSentinelPool获取jedis
QEMU ARM interrupt system architecture
It's 2022. Don't you hurry to learn typescript?
记本地项目启动报错:无效的源发行版: 8
Opencv function usage details 1~10, including code examples
DTS migration script sqlserver
Report on global and Chinese direct coupled actuator market demand and future development planning recommendations 2022-2027
Throw away electron and embrace Tauri based on Rust
jedispool工具类
rambbmitmq消费方
独立站优化清单丨如何有效提升站内转化率?
Jedispool tool class
2022 refrigeration and air conditioning equipment operation test paper and refrigeration and air conditioning equipment operation test skills
我们在编译器中运行可发现数据是反着存的,为什么要倒着放呢?

















