C语言-变量的存储


类型描述
char通常是一个字节(八位), 这是一个整数类型。
int整型,4 个字节,取值范围 -2147483648 到 2147483647,最高位表示符号
float

单精度浮点值。单精度是这样的格式,1位符号,8位指数,23位小数。

double

双精度浮点值。双精度是1位符号,11位指数,52位小数。

void表示类型的缺失。

注意:变量的名称可以由字母、数字和下划线字符组成。它必须以字母或下划线开头。

1、signed char类型的存储

  有符号类型变量在存储时,是存储变量的补码。无符号变量存储时,储存原码

1.1 原码

  最高位为符号位,0表示正数,1表示负数。
  例如:
  X = 0b11 (3),四比特表示原码 = 0011(3) ;
  X = - 0b11(-3) ,四比特表示原码 = 1011(11) ;

1.2 反码

  最高位为符号位,0表示正数,1表示负数。
  正数的反码等于本身,负数的反码除符号位外,各位取反:
  例如:
  X = 0b11 (3),四比特表示原码 = 0011(3),对应反码为 = 0011(3) ;
  X = - 0b11(-3) ,四比特表示原码 = 1011(11),对应反码为 = 1100(12) ;

1.3 补码

  最高位为符号位,0表示正数,1表示负数。
  正数的补码等于本身,负数的补码等于反码+1:
  例如:
  X = 0b11 (3),四比特表示原码 = 0011(3),对应反码为 = 0011(3) ,补码为 = 0011(3);
  X = - 0b11(-3) ,四比特表示原码 = 1011(11),对应反码为 = 1100(12),补码为1101(13) ;

1.4存储补码的作用

为了方便展示,把变量简化成为4bit 。

二进制原码存储表示值反码存储表示值补码存储表示值
0000000
0001111
0010222
0011333
0100444
0101555
0110666
0111777
1000-8-7-8
1001-1-6-7
1010-2-5-6
1011-3-4-5
1100-4-3-4
1101-5-2-3
1110-6-1-2
1111-7-8-1
  计算机不会减法的,只会加法,加法就相当于从上往下递增,例如:一个数2,需要+2,就从上往下数2,结果就是4,这就是计算机的加法。如果是原码存储直接相加,正数部分没问题,到了有负数显然是不对的,例如-2+1,原码储存直接相加为-3,明显不正确;反码储存相加部分正确,到了-6和-7的反码-1和-8这里就不对了。所以对补码储存进行了一个+1操作后,每一个的下面一个都是上面一个的+1。就和无符号时候的加法一样的,相加超过15的直接溢出舍弃。eg:-2-3=?,-2补码储存的二进制为1110,-3补码存储的二进制为1101,因此-2-3=1110+1101=11011,超过1111的舍弃,结果为1011,1011补码存储的值对应为-5,结果正确。

注意:把首尾连接,形成一个圆看,更加容易理解。

2、float的存储

1.1储存格式

  C语言中,对于浮点类型的数据采用单精度类型(float)和双精度类型(double)来存储,float数据占用32bit, double数据占用64bit
无论是单精度还是双精度在存储中都分为三个部分:

  • 符号位(Sign) :0代表正,1代表为负
  • 指数位(Exponent):用于存储科学计数法中的指数数据,并且采用移位存储
  • 尾数部分(Mantissa):尾数部分

其中float的存储方式如下图所示:
在这里插入图片描述

而双精度的存储方式为:
在这里插入图片描述

2.2转换流程

  1. 把小数转换成二进制数
  2. 用科学计数法表示
  3. 指数部分+127存放在指数位,小数部分存放在尾数部分

解析:

  1. +127原因:指数范围是-127~+128,为了表示负数,+127做偏移
  2. 为什么只存储小数部分:二进制除0外,无论什么数,用科学计数法都是整数1开头,因此没必要存储整数1,eg:1.0001010111*e^1010

2.3 float存储示例

以数字6.5为例,看一下这个数字是怎么存储在float变量中的:

  1. 先来看整数部分,模2求余可以得到二进制表示为110。
  2. 再来看小数部分,乘2取整可以得到二进制表示为.1
  3. 拼接在一起得到110.1然后写成类似于科学计数法的样子,得到1.101*2^2 。
  4. 从上面的公式中可以知道符号为正,尾数是101,指数是2。
  5. 符号为正,那么第一位填0,指数是2,加上偏移量127等于129,二进制表示为10000001,填到2-9位,剩下的尾数101填到尾数位上即可
SEEEEEEEEMMMMMMMMMMMMMMMMMMMMMM
0100000011010000000000000000000
  1. 内存中二进制数01000000 11010000 00000000 00000000表示的就是浮点数6.5

2.4 范围

最大值表示范围:[-3.4028235E38, 3.4028235E38]

-1.1111111 1111111 11111111*2^127=-3.4028235E38

符号指数尾数
11111 1110111 1111 1111 1111 1111 1111

-1.1111111 1111111 11111111*2^127=3.4028235E38

符号指数尾数
01111 1110111 1111 1111 1111 1111 1111
注意:为什么不是2^128呢,因为指数为128有特殊含义,稍后介绍。

最小正值为:1.1754943508222875079687365372222e-38

1.000*2^-126

符号指数尾数
00000 0001000 0000 0000 0000 0000
注意:为什么不是2^-127呢,因为也有特殊含义,稍后介绍。

2.5 精度

  float最少能保证7~8位的有效数值,因为23位的位数,实则是24位位数能表示的范围是0-16777216,7位能全部表示,8位部分能表示,因此超过16777216的整数部分就不能准确的表示了,同样的小数部分也不是都能准确表示的,小数分辨率可以很高也可以很低,具体看小数占多少位,最多可以占-126位。当整数比较大,接近20位二进制才能表示时,小数位就只有4位了,这时精度就只有2^-4=0.0625。

2.6 float 特殊值

  我们知道float存储浮点数的形式是(±)1.b *2^c,因为尾数位前面一直是个1,所以无论b和c取什么样的值,都无法得到0,所以在float的表示方法中有一些特殊的约定,用来表示0已经其他的情况。
  float的内存表示指数位数有8位,范围是[0, 255],考虑偏移量实际的指数范围是[-127,128],但实际情况下指数位表示一般数字时不允许同时取0或者同时取1,也就是指数位的实际范围是[-126,127],而指数取-127和128时有其特殊含义,具体看下面表格:

在这里插入图片描述

参考地址

https://www.lidihuo.com/c/c-tokens.html
https://blog.csdn.net/slience_J/article/details/51965009
https://blog.csdn.net/ly_w1989/article/details/50213011
https://blog.csdn.net/albertsh/article/details/92385277

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值