一、C语言数据类型
1.引入C语言数据类型
- 汇编中的数据类型有byte、word、dword等
- 那么C语言的数据类型除了有一个作用域的概念,其他的都和汇编的数据类型相似
2.学习数据类型的三要素
- 存储数据的宽度:每种数据类型能容纳多大的数据 
  - 存储数据的格式:虽然底层都是用0、1存储,但是使用不同数据类型时要注意里面存的数据到底是什么样的
 
- 作用范围(作用域):哪里可以用、哪里不能用什么数据类型
3.C语言中的数据类型
-  如下图所示:   
二、整数类型
-  整数类型:char、short、int、long char 8bit 1字节 short 16bit 2字节 int 32bit 4字节 long 32bit 4字节 
-  那么和汇编的byte,word,dword有什么关系呢?我们举一个简单的例子来看一下 void Func(){ char cTemp = 0xFF; short sTemp = 0xFF; int iTemp = 0xFF; } void main(int argc, char* argv[]) { Func(); }
-  所以从数据宽度来说: - 如果一个数据使用char类型变量存储,翻译成汇编则会用byte数据宽度内存来存储
- 如果一个数据使用short类型变量存储,翻译成汇编则会用word数据宽度内存来存储
- 如果一个数据使用int类型变量存储,翻译成汇编则会用dword数据宽度内存来存储
 
-  如果存入数据的数据宽度大于数据类型宽度,还是和汇编一样,从低位开始向高位存储,存储规定的数据宽度,多余的高位数据舍弃 void Func(){ char cTemp = 0x12345678; //byte short sTemp = 0x12345678; //word int iTemp = 0x12345678; //dword } void main(int argc, char* argv[]) { Func(); }      
-  整数类型分为有符号(signed)和无符号(unsigned)两种: -  但是在内存中存储的方式完全一样:计算机不管数据有无符号,它就只把数据化成二进制按照指定的数据宽度存在内存中    
-  只是在做运算的时候需要注意有无符号的区别 void Func(){ char x = 0xFF; unsigned char y = 0xFF; printf("%d",x); printf("%d",y); }  
-  还有在比较的数据大小时,也要注意有无符号的区别: -  如果一个有符号和一个无符号数比较,那么最终汇编语言会使用有符号数比较的跳转指令JBE、JG等 void Func(){ char x = 0xFF; unsigned char y = 0xFF; if(x>y){ printf("x>y"); } }  
-  如果两个有符号数比较,最终汇编语言会使用比较有符号数的跳转指令 void Func(){ char x = 0xFF; char y = 0xFF; if(x>y){ printf("x>y"); } }  
-  如果两个无符号数比较,最终汇编语言会使用比较无符号数的跳转指令 void Func(){ unsigned int x = 0xFFFF; unsigned int y = 0xFF; if(x>y){ printf("x>y"); } }  
 
-  
 
-  
三、浮点类型
1.浮点类型
- float和double
- float数据类型宽度为32位;double数据类型宽度为64位
2.小数在内存中存储方式
-  十进制、十六进制等整数在可以转化成对应的二进制最终存入内存,但是小数无法像整数那样对样转化成二进制数,但是小数如果想存入内存,它也要想办法转成二进制,那么小数是如何存储的呢? 
-  float和double在存储方式上都是遵从IEEE的规范的 -  float的存储方式:   
-  double的存储方式:   
 
-  
-  尾数部分宽度越长,表示小数的精确度越高,因为有些小数部分表示为二进制数是无限循环的,比如1.3。0.3用二进制表示即不断的乘2:每次乘完2取整数部分作为二进制数,小数部分如果为0,则结束,如果不为0,则取出小数部分继续乘2。那么1.3表示为二进制为1.0100110 0100110 …无限循环下去,如果使用float存储,那么尾数部分精确到了23位;如果使用double存储,那么尾数部分就精确到了52位 
3.将float类型转换为内存存储格式
-  先将这个实数的绝对值化为二进制格式(不管正负,转换分为小数部分和整数部分) 
-  将这个二进制格式实数的小数点左移或右移n位,直到小数点移动到第一个有效数字(1)的右边 
-  从小数点右边第一位开始数出二十三位数字放入第22到第0位(不够的用0补) 
-  如果实数是正的,则在第31位放入“0”,否则放入“1” 
-  如果n是左移得到的,第30位放入“1”。如果n是右移得到的或n=0,则第30位放入“0” 
-  如果n是左移得到的,则将n减去1后化为二进制,并在左边加“0”补足七位,放入第29到第23位 如果n是右移得到的或n=0,则将n化为二进制后在左边加“0”补足七位,再各位求反,再放入第29到第23位 
-  接着将得到的32位每4位一组,化成十六进制方便我们表示 
4.举例说明
-  8.25转换成浮点数存储: -  整数部分8转换成二进制为: 10008/2 0 ↑ //不断的除以2,取余数 4/2 0 | 2/2 0 | 1/2 1 |
-  小数部分0.25转换成二进制为: 100.25*2 0 | //不断的乘2,取整数部分 0.5*2 1 ↓ //直到小数部分为0结束
-  所以最终8.25用二进制表示为1000.10 
 
-  
-  小数点左移三位,小数点移到第一个有效数字的右边,接着用科学计数法表示: - 因为十进制数100.1可以表示为1.001*102。所以二进制1000.10移动后可以表示为:1.00010 * 23
 
-  从小数点右边第一位开始数出二十三位数字放入第22到第0位 -  因为小数点右边开始为00010,所以将00010后面再补0,一共补充到总长度为22位即可   
 
-  
-  因为8.25是正数,则在第31位放入“0”   
-  因为小数点当时是左移3位得到的1.00010 * 23,则在指数部分的首位即30位放入“1”   
-  因为小数点是左移3位得到的1.00010 * 23,所以3-1=2化成二进制为10,接着在左边补0,补充到总长度为7即可   
-  化成十六进制为:0x41080000 0100 0001 0000 1000 0000 0000 0000 0000 0x41080000
四、字符的存储
1.英文字符的存储
-  可以这样存: char x = 'A';也可以这样存:char y = 65
-  ASCII编码: -  ASCII 码使用指定的 7 位或 8 位二进制数组合来表示 128 或 256 种可能的字符 - 标准 ASCII 码使用7 位二进制数来表示所有的大写和小写字母,数字 0 到 9、标点符号,以及在美式英语中使用的特殊控制字符(最高位,即第八位永远都是0)
- 扩展 ASCII 码允许将每个字符的第8 位用于确定附加的128 个特殊符号字符、外来语字母和图形符号
 
-  常用的字符对应的ASCII码为: 二进制 十进制 十六进制 字符 0011 0000 48 30 0 0011 0001 49 31 1 0011 0010 50 32 2 0011 0011 51 33 3 0011 0100 52 34 4 0011 0101 53 35 5 0011 0110 54 36 6 0011 0111 55 37 7 0011 1000 56 38 8 0011 1001 57 39 9 0100 0001 65 41 A 0100 0010 66 42 B 0100 0011 67 43 C 0100 0100 68 44 D 0100 0101 69 45 E 0100 0110 70 46 F 0100 0111 71 47 G 0100 1000 72 48 H 0100 1001 73 49 I 0100 1010 74 4A J 0100 1011 75 4B K 0100 1100 76 4C L 0100 1101 77 4D M 0100 1110 78 4E N 0100 1111 79 4F O 0101 0000 80 50 P 0101 0001 81 51 Q 0101 0010 82 52 R 0101 0011 83 53 S 0101 0100 84 54 T 0101 0101 85 55 U 0101 0110 86 56 V 0101 0111 87 57 W 0101 1000 88 58 X 0101 1001 89 59 Y 0101 1010 90 5A Z 0110 0001 97 61 a 0110 0010 98 62 b 0110 0011 99 63 c 0110 0100 100 64 d 0110 0101 101 65 e 0110 0110 102 66 f 0110 0111 103 67 g 0110 1000 104 68 h 0110 1001 105 69 i 0110 1010 106 6A j 0110 1011 107 6B k 0110 1100 108 6C l 0110 1101 109 6D m 0110 1110 110 6E n 0110 1111 111 6F o 0111 0000 112 70 p 0111 0001 113 71 q 0111 0010 114 72 r 0111 0011 115 73 s 0111 0100 116 74 t 0111 0101 117 75 u 0111 0110 118 76 v 0111 0111 119 77 w 0111 1000 120 78 x 0111 1001 121 79 y 0111 1010 122 7A z 
 
-  
2.中文字符的存储
-  GB2312编码规则: - 天朝专家把那些127号之后的奇异符号们(即EASCII)取消掉,规定:一个小于127的字符的意义与原来相同,但两个大于127的字符连在一起时,就表示一个汉字,前面的一个字节(他称之为高字节)从0xA1用到 0xF7,后面一个字节(低字节)从0xA1到0xFE,这样我们就可以组合出大约7000多个简体汉字了。在这些编码里,还把数学符号、罗马希腊的 字母、日文的假名们都编进去了,连在ASCII里本来就有的数字、标点、字母都统统重新编了两个字节长的编码,这就是常说的"全角"字符,而原来在127号以下的那些就叫"半角"字符了
 
-  **所以截取一个字符串的一段,如何区分是英文还是中文?**就看这个字节数值的范围,如果小于128就表示英文;如果大于则是汉字的两字节截取了一半 
-  GB2312表:可以看到如果最终计算机存储的是0xB0A1,那么使用GB编码规则,这两个字节的值就表示 啊这个汉字。但是注意:是计算机中存储的值为0xB0A1,而计算机内存中是按字节为单位倒着存的,强调过很多次了,所以我们实际上用啊的时候要写成0xA1B0  
五、作业
-  将float类型的12.5转换成16进制 -  将12.5用二进制表示: 整数部分: 12 化成二进制--> 1100 小数部分: 0.5 化成二进制--> 1 因为0.5*2=1.0 1 综上12.5化成二进制为1100.1
-  小数点左移到第一个有效位的右边,此时用科学计数法表示为:1.1001*23。故左移了3位 
-  将此时的小数位从21位依次存到0位,如果不够则补0   
-  因为12.5是正数,所以31位为0   
-  又因为小数部分是左移,所以30位为1   
-  且因为小数二进制时左移3位得到的,所以3-1=2化成二进制为10,将10存入指数部分,不够的左边补0   
-  最后每四位一组化成十六进制为 0100 0001 0100 1000 0000 0000 0000 0000 0x41480000
 -  综上12.5转成十六进制为:0x41480000,存储在内存中为(倒着存入)00 00 48 41 
-  验证一下:   
 
-  










