目录
数据类型的介绍
类型的意义:
类型的基本归类
整形家族
浮点数家族
构造类型——自定义类型
指针类型
空类型
整形在内存中的存储
原码反码与补码
补码思想
大端小端字节序
浮点型在内存中的存储
浮点数表示形式
举例说明:
IEEE 754规定浮点数存储方式
对于有效数字M规定
对于指数E规定
从内存中取出
经典案例
数据类型的介绍
- char:字符数据类型——1字节
- short:短整型——2字节
- int:整形——4字节
- long:长整型——4字节
- long long:更长得整形——8字节
- float:单精度浮点数——4字节
- double:双精度浮点数——8字节
类型的意义:
- 使用这个类型开辟内存空间的大小(大小决定了使用范围)
- 如何看待内存空间的视角
类型的基本归类
整形家族
- 使用这个类型开辟内存空间的大小(大小决定了使用范围)
- 如何看待内存空间的视角
类型的基本归类
整形家族
浮点数家族
构造类型——自定义类型
指针类型
空类型(无具体类型)
void
函数返回类型:void test();
函数参数:void test(void);
无具体类型的指针:void* p;(任意数据的地址都可放入p但是不能用)
#include
void print(void) {
printf("hello");
}
void main() {
print();
}
整形在内存中的存储
void
函数返回类型:void test();
函数参数:void test(void);
无具体类型的指针:void* p;(任意数据的地址都可放入p但是不能用)
数据在内存中以二进制的形式储存
原码反码与补码
对于整数来说,整数的二进制有3种表示形式:原码,反码,补码。
正整数:其原码,反码,补码相同
负整数:其原码,反码,补码要进行计算
机器数:一个数在计算机中的二进制表示形式,机器数带符号,正数在最高位放0,负数放1
真值:带符号位的机器数对应的真正数值
原码:符号位加上真值的绝对值
反码:正数反码为其本身,负数反码在原码的基础上符号位不变,逐位取反。
补码:正数补码为其本身,负数补码=反码+1.
eg:-10
- 原码:10000000000000000000000000001010
- 反码:11111111111111111111111111110101
- 补码:11111111111111111111111111110110
注意:整数在内存中储存的是其二进制的补码
原因:使用补码可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理(cpu只有加法器)此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。
补码的创建是针对负数的计算,正整数的原码,反码,补码都相同
补码思想
现在是9点,如果我想调到6点;
9 - 3 -> 6 往前拨3个小时——(-3为源码) 9 + 9 -> 6 往后拨9个小时——(9为补码) 这里称12为模,写作mod12; 称9是-3以12位模的补数,记作 -3≡+9(mod 12)
由于前面9和-3互为补数且是以12为模,此刻我们先抛开负数不提得到9+3=12(反正最后在给任意一个变量加上符号,这两个数便互为补码)
一个 N 位的二进制数,可表示的最大值是2^N-1;
假设存在 x+y = 2^N-1 --> x+y+1 = 2^N;
如果此时把2^N 当做模 --> -x(如今加上负号) 和 y+1 就互为补数;
而x+y = 2^N-1,2^N-1是一个 N 位的二进制数最大的数了(就是各位是1的数),如果x和y相加真要得到这个数那么就两个从各位逐个相加一位是1那么第二个数的该位必定是0,现在我们已经知道了x和y逐个位相反,然而-x与y+1为补码啊,那么由反码定义可知-x与y必为反码。
C语言中加上一个数就等于加上这个数的补数(本质:运算溢出情况)。
运算溢出(以char为例)
char类型一字节范围:-128——127;
注意:无符号char类型一字节范围:0——255;
运算相加减遵循顺序(本质:整形提升截取)
……-128——0——127——- -128——0——127……
大端小端字节序
触发条件:数据的大小高于1字节(地址管理的内存大小)
内存有低地址和高地址之分
高字节序与低字节序
eg:1234——字节序从左到右逐渐降低
大端字节序:把数据低位字节序的内容存放在高地址出,把数据高字节序内容存放在低地址处
小端字节序:把数据高位字节序的内容存放在高地址出,把数据低字节序内容存放在低地址处
例子:00000001
不管是大端还是小端字节序,最后都能将其还原成00000001(只不过是存放方式的问题)
浮点型在内存中的存储
浮点数家族包括:float,double,long double类型。
浮点数表示范围:float.h中定义
浮点数的两种写法
- 一般写法:3.14159
- 科学计数法:1E10(1.0*10^10)
注意:浮点型指针解引用是向内存中拿一个浮点类型的数
#includevoid main() { int n = 9; float* pf =(float*) &n; printf("n=%dn", n);//9 printf("pf=%fn", *pf);//浮点数视角取0.000000 *pf = 9.0; printf("n=%dn", n);//整数视角取1091567516 printf("pf=%fn", *pf);//浮点数视角取9.000000 }
由此观之:浮点数和整数在内存中的存储方式一定有区别
浮点数表示形式
根据IEEE(电器和电子工程协会)754,任意一个二进制浮点数V可以表示成下面的形式
举例说明:
浮点数:5.5——10进制
转化为二进制
5:101
0.5:2^-1
得到:101.1——>分别对应2^2,2^1,2^0,2^-1
推出:1.011*2^2——>(-1)*0*1.011*2^2
其中:S=0,M=1.011,E=2
由此观之,只要有S、M、E储存好,那么这个浮点数也就储存好了
IEEE 754规定浮点数存储方式
对于float(32位)浮点数,最高的一位是符号位S,接着的8位是指数E,剩下的23位是有效数字M
对于double(64位)浮点数,最高的一位是符号位S,接着11位是指数E,剩下的52位是有效数字M
对于有效数字M规定
对于有效数字M,因为0= 这样做的目的是:节省一位有效数字,以32位浮点数为例,留给M的只有23位,将第一位的1舍弃以后,等于可以保存24位有效数字 如果E的数字没有填满8/11位则前面补0(反正没符号) 因此,对于(-1)*0*1.011*2^2——S=0,M=1.011,E=2 在计算机存储为:[0](0) [100 0000 1](2+127) [011 0000 0000 0000 0000 0000](011) 0100 0000 1011 0000 0000 0000 0000 0000——5.5 E不全为0或E不全为1 指数E的真实值减去127/1023,得到真实值,再将有效数字M前加上第一位的1 E全为0 1.xxxxx*2^-127——0.1xxxxx*2^-126——0.xxxxx*2^-126 E全为1 这时,如果有效数字M全为0,表示+/-无穷大(正负取决于符号位S) 理解: n=9:00000000000000000000000000001001 以整形打印就是9(原码、反码、补码均一样) 以浮点数形式拿出 [0](S) [00000000](E) [00000000000000000001001](M) E全为0——0.00000000000000000001001*2^(1-127)约等于0 *pf=9.0: 1001.0——1.001*2^3——(-1)*0*1.001*2^3 [0](S) [10000010](130——E) [00100000000000000000000](M) 01000001000100000000000000000000 以整数形式拿出(其为补码,拿出原码——就是本身) 以浮点数形式拿出——9.0对于指数E规定
从内存中取出
经典案例
#include



