一、整数和浮点数
整数和浮点数不仅是书写方式不同,而且对计算机而言,它们的存储方式也不同。
1. 1 整数
整数是没有小数部分的数,计算机以二进制的形式存储整数。
1.2 浮点数
计算机把浮点数分为小数部分和指数部分来表示,并且分开存储这两部分。因此,7.00 和 7 虽然在数值上相同,但它们的存储方式不同。
浮点数通常只是实际值的近似值。例如,7.0 可能被存储成浮点值6.999999 ,精度只有 6 或 7 位。因此使用 float 进行比较时,不能使用 == ,只能使用 > 或 < 。
过去,浮点数运算比整数运算慢。但现在许多CPU里都包含浮点处理器,缩短了速度上的差距。
二、基本数据类型
2.1 int类型
int类型是有符号整形。
早期的16位IBM PC使用16位来存储一个int值,现在个人计算器一般是32位,所以是32位存储一个int值。ISO C标准规定int的取值范围最小是-32768~32767。
2.2 其他整数类型
C 语言提供了多种整数类型,因为C语言让程序员针对不同情况选择不同的类型,不同的整数类型可以表示不同的取值范围。
short——最大的short类型整数小于或等于最大的int类型整数,short类型至少占16位。
long——该类型可表示的整数大于或等于最大的int类型整数,long类型至少占32位。
long long——该类型可表示的整数大于或等于最大的long类型整数,long long至少占64位。
2.3 char类型
通常,char类型占8位,C语言把一字节定义为char类型占用的 bit 位。
C语言把字符常量是为int类型而非char类型,该数只占8位。例如:在int为32为的、char为8位的ASCLL系统中
char grade = ‘B’ , 本来 ‘B’ 对应的数值66应该存储在32位的存储单元中,但现在却可以存在8位的存储单元中。利用这种特性,定义一个字符常量 ‘FATA’ ,即把四个独立的8位ASCLL码存储在一个32位的存储单元中,如果把它赋给 char 类型的变量grade,那么只有最后8位有效,即grade的值为 ‘E’ 。
2.4 _Bool类型
C99 标准添加了 _Bool 类型,以发明此类型的英国数学家的名字命名。
_Bool 用 1 表示 true,用 0 表示 false ,因此 _Bool 也是一种整数类型。
2.5 可移植类型:stdint.h 和 inttype.h
C 语言提供了许多有用的整数类型,但某些类型名在不同的系统中的功能不一样,因此 C99 新增了两个头文件 stdint.h 和 inttype.h ,以确保C语言的类型在个系统中的功能相同。
2.6 float、double 和 long double
float占32位,其中8位表示指数的值和符号,剩下24位用于表示非指数部分(尾数)及其符号。
注意:
1、some = 2.0 * 4.0;
通常,2.0 和 4.0 会被存储成 64 位的 double 类型,使用双精度进行乘法运算,然后再把结果截断成float类型的宽度,这样做虽然计算精度更高,但是会减慢程序的运行速度。应该在浮点数后面加上 f 或 F 覆盖默认设置。
2、浮点值上溢和下溢
如果计算结果太大,超出当前类型能表达的范围时,就会发生上溢,在这种情况下,会设置为 inf 或 infinity (或者具有无穷含义的其他内容);当除以一个很小的数时,可能会发生下溢,例如在4位有效数字的表示下:
a = 0.1234E-10,用 a 除以 10,那么因为有效数字有限,所以会变成 0.0123,3 被损失。
3、舍入错误
例:
float a, b;
b = 2.0e20 + 1;
a = b - 2.0e20;
printf("%f \n", a);
该段代码的输出结果并不是 1 ,因为计算机缺少足够的小数位来完成正确的运算。2.0e20 是 2 后面有 20 个 0。如果把该数加 1,那么发生变化的是第 21 位数,因此要想正确运算,程序至少要存储21位数字,然而 float 类型的数字通常只有 6 或 7 位有效数字。所以程序的运行结果一定不是 1 。如果是 b = 2.0e4,那么会得到想要的结果。
2.7 复数和虚数类型
2.8 其他类型
C 语言的基本数据类型就是上述7种,还有从基本类型衍生的其他类型,包括数组、指针、结构体和联合。
三、使用数据类型
1、C 语言遇到数据类型不匹配时,会自动转换,如:
int a = 3.0;
float b = 3.1415926536
a 会被截断成 3,b 会被截断成3.141593。
2、sizeof(),strlen() 等返回值为 size_t 类型的函数,使用 %zd 来进行转换。
四、参数和陷阱
C 语言中的 printf() 和 scanf() 与其他的函数不太一样,它们的参数个数和类型是可变的,使用第一个参数表明后续还有多少个参数,即第一个字符串中的转换说明与后面的参数一 一对应。如果对应不上去,则会出现意想不到的错误。
五、刷新输出
pirntf() 何时把输出发送到屏幕上?
1、缓冲区满了;
2、遇到换行符;
3、需要用户输入