只要你愿意 开始总比放弃好。 Roman.
愿我们都有自己的目标并正在为其不懈努力。
-----------------------------------------------------------------------
一、数据类型介绍
1. C语言中基本内置类型:
2. 类型的意义:
- 使用这个类型开辟内存空间的大小(大小决定了使用范围)
- 如何看待内存空间的视角
类的基本归类
1. 整型家族:
* 注意:char 虽然是字符类型,但是字符类型在存储的时候,存储的是字符的ASCII码值,ASCII码值是整数
* 对于有符号的数而言,可以存放在有符号的变量中;对于只有正数的数而言,可以存放在无符号的变量中
* 存储数据时:对于有符号的数而言,最高位是符号位(最高位0表示正数, 1表示负数);
对于无符号数而言,最高位也是数据位
2. 浮点数家族:
3. 构造类型(自定义类型):
4. 指针类型:指针变量是用来存放地址的
5. 空类型:
-----------------------------------------------------------------------
二、整形在内存中的存储
一)原码、补码、反码
1. 计算机中的整数有三种表示方法,即原码、反码和补码。
2. 三种表示方法均有 符号位 和 数值位 两部分,符号位都是用 0 表示 “ 正 ” ,用 1 表示 “ 负 ” ,而数值位直接将除符号外的数值翻译成二进制形式即可。
3. 负整数的三种表示方法各不相同。
- 原码: 直接将数值按正负数形式翻译成二进制(若有符号,最高位是符号位)
- 反码: 符号位不变,其他位按位取反
- 补码: 反码 + 1
4. 正整数原反补码均相同。
5. 对于整形来说:数据在内存中是以补码形式存储的。
6. 补充:4个二进制位表示1个十六进制, 3个二进制位表示1个八进制位
7. 数据超过存储,则丢掉高位 留低位
8. 注意: 对于有符号char型:补码10000000 无法减1转化为反码,会直接解析成 -128
9. 补码 转换为 原码:
10. 无符号数没有原反补码的概念,其就相当于正整数原反补码一致
11. 实例:
*注: 按打印要求进行相应的变化
二)大小端的介绍
1. 什么是大小端?
大小端:即大小端字节序存储,包括大端字节序存储和小端字节序存储
2. 存储时,是以字节为单位进行存储的
3. 大端字节序存储:把一个数据低位字节处的数据存放在高地址处,把高位字节处的数据(十六进制靠近0x)存放在低地址中
小端字节序存储:把一个数据低位字节处的数据放在低地址处,把高位字节处的数据(十六进制靠近0x)存放在高地址中
4. 为什么会出现大小端?
5. 百度2015年系统工程师笔试题:
请简述大端字节序和小端字节序的概念,设计一个小程序来判断当前机器的字节序
三)练习
相关练习参考下一个博客,以下为一些相关知识点。
1. 截断:是对补码进行操作的,保留低比特位
2. 整形提升:有符号补上的是符号位,无符号则补0
3. int 型放到 char 型,存不下,会进行截断
4. 整形提升是对补码进行提升,与打印的具体形式无关,是原来的类型根据有无符号对应的法则进行提升的,最后再看打印形式具体变化
- 任何整形提升都是按变量原来的类型去提升的
- 整形提升是对补码进行操作
- 整形提升得到补码后,再看打印的形式决定如何求原码
5. 内存中以补码形式进行存储
6. strlen : 是求字符串长度的,找的是'\0' 的位置,统计的是'\0'之前出现多少个字符
('\0'的ASCII码值是 0)
-----------------------------------------------------------------------
三、浮点型在内存中的存储
1. 补充:
2. 常见浮点数:
一)一个例子
浮点数存储的实例:
* 由打印结果可推测:整数在内存中的存储方式和浮点数在内存中的存储方式有差异
二)浮点数存储规则
上述 num 和 *pFloat 在内存中明明是同一个数,为什么浮点数和整数的解读结果会差别这么大?
- 要理解这个结果,一定要搞懂浮点数在计算机内部的表示方法。
- 根据国际标准IEEE(电气和电子工程协会) 754,任意一个二进制浮点数V可以表示成下面的形式:
* 注:IEEE 754 规定:
1) 对于 32 位的浮点数,最高的 1 位是符号位 s ,接着的 8 位是指数 E ,剩下的 23 位为有效数字 M 。
2)对于64位的浮点数,最高的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M。
* 实例:5.5的二进制表示
*注: 特殊浮点数难以存储则一般只是近似
*注:
1. IEEE 754对有效数字M和指数E,还有一些特别规定。
2. 至于指数 E ,情况就比较复杂。
1)首先, E 为一个无符号整数( unsigned int )
然后,指数E 从内存中取出还可以再分成三种情况:
2)
- E不全为0或不全为1
- E全为0
3. 解释前面的题目:
1)回到一开始的问题:为什么 0x00000009 还原成浮点数,就成了 0.000000 ?
首先,将 0x00000009(二进制:00000000 00000000 00000000 00001001) 拆分,得到第一位符号位s=0 ,后面 8 位的指数 E=00000000 ,最后 23 位的有效数字M=000 0000 0000 0000 0000 1001。
由于指数 E 全为 0 ,所以符合上述的第二种情况。因此,浮点数 V 就写成:
V=( - 1)^0 × 0.00000000000000000001001×2^(1-127 )=1.001×2^( - 146)
显然, V 是一个很小的接近于 0 的正数,所以用十进制小数表示就是: 0.000000
2)以下: 9.0 -> 1001.0 -> (-1)^0 * 1.0010 * (2^3) -> S=0 M=1.0010 E=3(指数E计算错误!! 指数E=原来真实值+127(针对8位E),所以:E=3+127=130,二进制: 10000010 ) 在内存中存储是:0(S) 10000010(E) 00100000000000000000000(M), 又按%d即有符号整型打印,则打印按整型打印:0 1000001 00010000 00000000 00000000,即:1091567616
4. 注:
*补充:比较浮点数大小不能直接用== 因为浮点数不能精确被保存
------------------------一个人所有的愤怒都来源于对自己无能的痛苦。------------------------