本文内容基于《C程序设计语言·现代方法》而写,旨在帮助自我梳理知识,辅助书籍为《明解C语言·入门篇》。
会慢慢补充和完善内容。
C语言中,常见的数据类型为算术类型,大体可分为整数类型和浮点类型。C89、C99各有其划分算术类型的标准。
C89中采用整值类型(integral type)来统称整数类型、字符类型和枚举类型;而C99中则扩展了整数类型的含义,使其包含了字符类型和枚举类型。
具体如下:
对整数类型,根据其有无符号,可划分为有符号整型、无符号整型。(同理,字符类型也可如此划分为有符号字符和无符号字符)。
有无符号的划分涉及到整型在计算机内部的表示方式,即与二进制、反码、补码等有关的内容,此处有待补充。 (包括浮点数的长度、精度,都与其有关)。
对于整型数值,可用类型说明符(type specifier) signed、unsigned 来指定其有无符号。默认情况下,C语言中的整型变量都是有符号的,无符号整数主要用于系统编程和底层与机器相关的应用中。
除了以有无符号划分,根据储存长空间的大小,整型又可划分为短整型(short int)、长整型(long int) 等,C99中还提供了 长长整型(long long int) 。上述整数类型同样有有无符号之分。并在C99中,称其为标准有符号整型和标准无符号整型,此外C99还允许在具体实现时定义扩展的数类整型(也包括有符号和无符号类型)。
- 关于整数类型的书写
unsigned、signed;short、long、long long 等说明符的的书写顺序对整数类型无影响,即一种类型可有多种书写方式。同时,C语言还允许省略单词 int 来缩写整数类型名称。
- 一些小规则
①类型通常拥有取值范围;
②标准规定,short取值范围 ≤ int取值范围 ≤ long int 取值范围≤long long int取值范围。
- 数据类型的数值范围
①不同编译器中,所给定的类型取值范围不同。
②C语言编译器中,头文件以宏定义的形式定义了字符类型以及其他整型的数值范围。通过调用该头文件,即可判断编译器下各类整型、字符类型所表示的取值范围。
③如下:
C语言允许使用十进制、八进制、十六进制三类方式来表示整数常量。实际储存方式为二进制。其中,八进制和十六进制适用于底层程序编写。
以十为基数的整型常量称为十进制常量,包含数字0~9,且一定不能以0开头。
以八为基数的整型常量称为八进制常量,包含数字0~7,必须以0开头。形式为:0fff
以十六为基数的整型常量称为十六进制常量,包含数字0 ~ 9和字母 a ~ f,必须以ox开头。形式为:0xff(大小写随意)
由于数据类型有其规定范围,在进行算术运算时,结果若超出数值限定的范围,就会发生溢出现象。
整数溢出根据有无符号来判断。无符号整型发生溢出是有定义的,有符号整型发生溢出程序行为是未定义的。
整数类型并不能表示所有实数,故需要能储存带小数点的数据类型,C语言提供了三种浮点类型。
即:
单精度浮点数(float);
双精度浮点数(double);
扩展精度浮点数(long double)。
C99中,浮点类型分为实浮点类型和复数类型(float_Complex、double_Complex、long double_Complex)
关于浮点数的精度、长度及其内部表示,此处涉及一些二进制、反码补码知识,后续补充。
默认情况下,浮点常量以双精度浮点数的形式储存,在需要时double类型的值自动转化为float类型的值。
若要强制编译器以 float 或 long double 类型储存浮点数,对float类型,需要在末尾加上字母f/F,对long double类型,需要在末尾常量上加上字母l/L。
例:
float a=0.6f long double b=57.2L
故对以float类型表示的数值,最好在其后加上字母F/f,否则编译器默认其为double类型。
C语言把字符当作整数处理,字符常量实际上是int类型而不是char类型。当计算中出现字符时,C语言只是使用了与之对应的整数值。
基于上述可知,char类型也分为有符号字符和无符号字符。对于没有声明的字符,由编译器确定其为有符号类型还是无符号类型。
C语言允许混合使用基本类型,但计算机执行算术运算时,则要求操作数的数位量相同,且其储存方式也相同。因此,C编译器中会生成一些指令,使得类型不同的操作数得以转换类型,从而满足计算机运算的需求。
根据是否有程序员介入,类型转换分为隐式转换(implicit conversion)和显示转换(explicit conversion)。
无需程序员介入,编译器可自动处理的这类转换,即隐式转换。此外,C语言还允许程序员使用强制运算符执行显示转换。
常见的隐私转换如下:
思维导图如下:
实例如下:
注意事项:应避免无符号类型和有符号类型的混用。(原因还有待理解和补充)
遵循规则:把赋值运算符右侧的表达式转换成左侧变量的类型。
若变量类型储存大和精度 ≥ 表达式类型大小精度,则无太大障碍,否则有问题。
比如:float浮点类型的数被赋值给int类型,小数部分丢失;long int赋值给int类型,超出int数值范围可能会得到无意义的结果。
C99中由于增添了一些类型以及扩充了整数类型的定义,故隐式转换和C89中略有不同。
C99中整数转换等级排序:
任一操作数类型是浮点类型的情况,若两操作数都不是复数型,则规则与C89相似,由低到高找能满足要求的最小范围类型。
两个操作数类型都不是浮点型的情况,依此尝试如下规则:
精髓之处在于取“最狭小的”数据类型。
作用:可以很大程度上控制数值类型。
格式:(数据类型)表达式
//类型转换表达式: (数据类型)表达式 //实际例子: (int)5.7 //根据整数类型的特征,浮点数5.7实际储存值为整数5
C语言视强制类型转换符为一元运算符,其优先级高于二元运算符。
(float) a / b ((float) a) / b
待补……



