数据类型介绍
c语言的基本内置类型  注: C语言里面没有专门的字符串类型。在C语言中,字符串是被当做字符数组来处理的
类型的意义 1.使用此类型开辟空间的大小 2.如何看待内存空间
类型的基本归类
整型家族  注:char类型本质上是ASCII码值,并且有三种类型分类:char,signed char, unsigned char ,char有无符号标准未定义,取决于编译器
浮点数家族 
构造类型 
指针类型 
空指针 
常用数据的取值范围  
整型在内存中的存储
原码,反码,补码
(原码,反码,补码)是什么 数值的表现形式有很多种:比如二进制(ob),八进制(0),十进制,十六进制(ox)等 其中,整数的二进制也有三种表现形式,就是原码,反码,补码
怎么算(原码,反码,补码) 正整数对于正整数来说,三码合一,原码,反码,补码都是相同的,直接将数值按二进制翻译即可 负整数对于负整数来说
原码 直接按照正负数的形式翻译成二进制的形式(其中高位是符号位,1表示负数,0表示正数)
反码 原码的符号位不变,其他位按位取反
补码 反码符号位不变,然后加一
结论:对于整型来说,在内存中存放的是补码
为什么(要存放补码) 1.使用补码,可以将符号位和数值位统一进行处理,即不用加以区分符号位与数值位 2.补码与原码的相互转换运算相同,不需要额外电路 补码=原码取反+1 原码=补码取反+1 3.CPU只有加法器,加法和减法可以统一进行加法处理,比如1-1=1+(-1)
大小端
大小端介绍
int main()
{
int i = 10;
return 0;
}
此时我们取i的地址后得到 0x0000008DDC4FF6C4 0a 00 00 00 发现i的存储方式为“倒着存”,这就引出了大小端的概念
1.什么是大小端 大端小端都是数据在内存中存储的形式,以字节单位来讨论存储模式
大端存储 数据的低位存储在内存的高地址中,高位存储在内存的低地址中(通俗意义的顺着存) (KEIL C51)
小端存储 数据的高位存储在内存的高地址中,低位存储在内存的高地址中(通俗意义的倒着存) (X86 ARM DSP)  2.为什么会存在大小端存储 1.计算机系统中基本的单位是字节,而其中每个地址单位都对应这一个字节单位,一个字节是8个比特位,但是c语言还有其他不同的数据类型,不都是只有一个字节大小,因此存在怎么将多个字节排序的问题。 2.对于位数大于8位的16位,32位的处理器,由于寄存器的宽度大于一个字节,因此存在怎么将多个字节排序的问题。
3.设计一个程序来判断当前机器的字节序
int check_sys()
{
int i = 1;
return(*(char*)&i);
}
int main()
{
int ret = check_sys();
if (ret == 1)
{
printf("小端\n");
}
else
{
printf("大端\n");
}
return 0;
}
int check_sys()
{
union
{
int i;
char c;
}un;
un.i = 1;
return un.c;
}
如果是小端存储,即倒着存,那么第一个字节存取的就是1
浮点数在内存中的存储
浮点数的存储规则
根据国际标准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 即 S=0 M=1.01 E=2
IEEE 754规定 对于32位的浮点数,最高的1位是符号位s,接着8位是指数E,剩下的23位为有效数字  对于64位的浮点数,最高的一位是符号位S,接着的11位是指数位E,剩下的52位为有效数字M 也因为位数有限,所以浮点数在内存中保存可能不会精确保存
此外,对于有效数字M和指数E 还有一些特殊的规定
对于有效数字M来说 Md大于等于1,小于2,并且M可以写成1.xxxxx的形式 所以,计算机在保存M的时候默认这个数的第一位是1,因此可以被省去,只保存后面的小数部分 目的是可以节省存储一位有效数字
对于指数位E来说
(存入) E为一个无符号整数 若E为8位,取值为0—255;若E为11位,取值为0—2047 在科学计数法中E是可以出现负数的,因此在存入内存是E的真实值必须再加上一个中间数 对于8位的E,中间数为127;对于11位的E,中间数为1023
举例 2^10 2^10存入内存的,保存为32位浮点数的时候,必须保存成10+127=137,即10001001
(取出) 1.E不全为0或不全为1 指数E的计算值减去127(或1023),得到真实值,再将有效数字M前加上第一位的1 举例 0.5 存入 0.5的二进制形式为0.1,用IEEE表示为1.02^(-1),此时在存入E时需要将-1加上127,存入的阶码为128,二进制表示为01111110,此外M为1.0,去掉1后存入23个0,此外0.5为正数,所以第一位S为0 所以存入内存中的二进制值为 0 01111110 000000000000000000000000 取出 01111110存入阶码为128,减去中间值127得到真实值-1,所以 E为-1 M存入的是000000000000000000000000再给M补上1,得到M为1.0 首位为0,也就是S=0 得到1.02^(-1)
2.E为全0 此时 E直接就等于1-127(或者1-1023) 有效数字M也不再加上1,而是直接还原为0.xxxx的小数,目的是为了表示正负0,或者无限接近于0的一个很小的数 简记为:正负无限接近于0
3.E为全1 此时若M为全0,咋表示正负无穷大(正负取决于符号位)
例题
int main()
{
int n = 9;
float* pFloat = (float*)&n;
printf("n的值为%d\n", n);
printf("*pFloat的值为%f\n", *pFloat);
*pFloat = 9.0;
printf("n的值为%d\n", n);
printf("*pFloat的值为%f\n", *pFloat);
return 0;
}
结果如下  1.对于第一个打印,9是正整数,原反补相同,在内存中存放的都是 00000000000000000000000000001001 以整数形式存储,以整数形式打印,所以结果为整数9
2.对于第二个打印,发生强制类型转换,内存读取时以浮点数的视角读取 一个位为符号位S为0,后8位为E,E为全0,E=1-127=-126, M=0.00000000000000000001001 得到值为+0.00000000000000000001001*2^(-126) 所以打印结果为0.00000(正无限接近于0)
3.对于第三个打印,pFlaot依然是以浮点型往内存里面存储 1001.0=1.0012^3,S=0,M=1.001,E=3,也就是存储 0 10000010 00100000000000000000000 此时再以整型的角度(存放的是补码,正数则直接转换打印)来打印
4.对于第四个打印,以浮点数的形式放,以浮点数的形式取,所以是9.00000
|