数据的存储

数据类型

整型:

char(虽然是字符类型,但是字符类型存储的时候,存储字符的ASCII码值)
	unsigned char					signed char
	至于char有无符号,C语言中并没有明确规定
	大部分编译器会认为char有符号
short
	unsigned short[int]				signed short[int]
short s1;//这里s1 是有符号的  等价与下面的  
signed short s1;
//C语言中有规定定义短整型是默认有符号
unsigned short s1;//定义一个无符号短整型
int
	unsigned int						signed

浮点型:

float、double
C99中引入了long double的类型

构造类型(自定义类型):

数组类型、结构体类型、枚举类型、联合类型

指针类型:

int* pa		char* pa		float* pa		void* pa

空类型(void)

整型在内存中的存储

原码、反码、补码

计算机中的整数有三种表达方式:原码、反码、补码
三种表达方式均有符号位和数值位两部分

符号位都是用“0”表示正数,“1”表示负数

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

原码:直接翻译成二进制
反码:原码符号位不变,数值位按位取反
补码:反码 + 1

整型在内存中的存放是补码(计算机中只存在补码)

CPU的计算逻辑单元中只有加法器,减法、乘法、除法是用加法模拟的
	1 -1  等价与 1 +-1//原码:0000 0000 0000 0000 0000 0000 0000 0001  
//    +1000 0000 0000 0000 0000 0000 0000 0001
//反码:0000 0000 0000 0000 0000 0000 0000 0001  
//	  +1111 1111 1111 1111 1111 1111 1111 1110
//补码:0000 0000 0000 0000 0000 0000 0000 0001  
//    +1111 1111 1111 1111 1111 1111 1111 1111
用补码进行计算:得到的结果是:
1 0000 0000 0000 0000 0000 0000 0000 0000 
一个整型4个字节(即32个bit)显然 上面的计算完的补码最高位是33位,
内存中放不下就丢掉。结果自然是0.
使用补码可以将符号位和数值位统一处理
但用原码或者反码计算,结果往往不尽人意

有符号数、无符号数

有符号数的二进制值中,最高位是符号位,其他位为数据位。可以存储正数、负数
无符号数的二进制值中,全是数据位。只能存储正数
所以同类型下,无符号数可以表示的正数更大,但不能表示负数。而有符号数虽然能表示的正数较小,但在负值方向做了延伸(即能表示负数)
下面以一个字节为例:

//有符号数(首位为符号位)
//最大值:
0111 1111//转换为十进制为127
//最小值:
0000 0001(补码)//转换为十进制为-128
//无符号数(全是数值位)
//最大值:
1111 1111//转换为十进制为255

大小端(大小端字节序存储)

大端(储存)模式:
数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中
小端(储存)模式:
数据的低位保存在内存的低地址中,而数据的高位,保存在内存的高地址中

在计算机系统中,是以字节为单位的,每个地址单元都对应这一个字节,一个字节
为8个bit,但是在C语言中除了8bit的char之外,还有16bit的short,32bit
的long。

例如一个16bit的short类型x,在内存中的地址为0x0010,x的值为0x1122,那
么0x11为高字节,0x22为低字节,对于大端模式,就将0x11放在低地址中(即
0x0010);0x22放在高地址中(即0x0011)。小端模式恰好相反

小端模式:
在这里插入图片描述

整型提升

C语言中整型的运算总是以缺省整型类型的精度来进行的
为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型。
发生整型提升的前提是char和short类型参与整型运算,而且运算结束后,四个字节的数据将发生截断,然后才返回值(也就是说CPU返回值的字节数仍为这个数据原本类型的字节数,而不是提升后的字节数)。

意义

表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器的操作数长度
一般就是int的字节长度,同时也是CPU寄存器的长度
所以两个char类型的相加,在CPU执行时实际上要先转换为CPU内整型操作数的标
准长度

正负数的整型提升

整形提升是按照变量的数据类型的符号位来提升的(无符号整型高位补0)

char a = -1//a的原码:1000 0001  反码:1111 1110  补码:1111 1111
高位补充符号位(11111 1111 1111 1111 1111 1111 1111 1111
char b = 1//a的原码、反码、补码均为:0000 0001
高位补充符号位(00000 0000 0000 0000 0000 0000 0000 0001

截断

在C语言中,进行变量赋值的时候,如果将字节数多的数据类型赋给一个字节少的数据类型,会发生“截断”。
在这里插入图片描述

浮点型在内存中的存储

表示方法

根据国际标准IEEE,任何一个二进制浮点数可以表示成一下形式:

(-1)^ S * M * 2 ^ E
(-1)^ S:表示符号位。当S = 0,表示正数;当S = 1,表示负数。
 M表示有效数字(大于等于1,小于2)
 2 ^ E表示指数位
 eg.
 十进制的9.0,写成二进制是1001.0,相当于1.001 * 2 ^ 3
 (即(-1)^ 0 * 1.001 * 2 ^ 3)
 十进制的-9.0:(-1)^ 1 * 1.001 * 2 ^ 3

浮点数的精度误差:

像3.141596这种浮点数在计算器里面非常难保存(小数点后面写了很多位,但依
旧不能精确保存),这种时候会四舍五入

存储规则

浮点数对内部的划分:

float类型占4个字节(即32个bit位)
对于32位的浮点数,最高的1位是符号位s,接着的8位是指数E,剩下的23位为有
效数字M。

在这里插入图片描述

double类型占8个字节(即64个bit位)
对于64位的浮点数,最高的1位是符号位S,接着的11位是指数E,剩下的52位为有
效数字M。

在这里插入图片描述
IEEE对有效数字M和指数E的特殊规定:

计算机内部保存M时(1<=M<2),默认这个数的第一位是1,因此可以被舍去,只
保存小数点后面的部分。这样做是节省1位有效数字,使得浮点数精度更高。以32
位浮点数为例,将第一位的“1”舍去后,可以保存24位有效数字。

指数E是一个无符号数。如果E位8位,那么它的取值范围为0~255;如果E为11位,
那么它的取值范围为0~2047。但是,在科学计数法中,E是可以出现负数的的。所
以IEEE中规定,存入内存时E的真实值必须再加上一个中间数。对于8位的E,这个
数是127;对于11位的E,这个数是1023

vs2019是小端

E从内存中拿出来的三种情况:
1.E不全为1或不全为0:
	指数E的计算值减去127(或1023),的到真实值,再将有效数字M前加上1
2.E全为0
	指数E的真实值为1-127(或1-1023)。有效数字M不再加1
3.E全为1
	如果有效数字全为0,表示无穷大(正负取决于符号位)
  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值