了解数制的分类
熟悉数据类型的分类
掌握整型数据类型的使用方法
掌握浮点型数据类型的使用方法
掌握字符型数据类型的使用方法
掌握不同数据类型之间的转化规则
掌握使用typedef定义类型的方法
二进制
八进制
十六进制
数制间的转换
二进制是计算技术中广泛采用的一种数制。二进制数据是用0和1两个数码来表示的数。它的基数为2,进位规则是逢二进一,借位规则是借一当二,目前的计算机全部采用二进制系统。0和1是二进制数字符号,运算规则简单,操作方便,因为每一位数都可以用任何具有两个稳定状态的元件表示,所以二进制易于用电子方式实现。
八进制进位规则是逢八进一,借位规则是借一当八的数制,由0~7共8个数字组成。八进制整数必须以0开头,即以0作为八进制数的前缀,八进制数通常是无符号数,如04、017等。
十六进制规则是逢十六进一,借位规则是借一当十六的数制,由0~9和A~F共16个数字组成(A代表10,F代表15),也常用于计算机计算。在C语言中,十六进制数以0x开头,如0x1A、0xFF等。
整型常量的表示方法
整型变量
整型变量的分类
整型变量的溢出
整型常量简称整常数或整数。在C语言中,整型常量根据数制的不同包括二进制、十进制、八进制、十六进制,并且各种数制均有正(+)负(﹣)之分,正数的+可省略。例如,0、﹣12、255、1、32767等都是整型数据。整型常量是不允许出现小数点和其他特殊符号的。
整型变量是用来存储整数的,可以是正数或者负数。
整型在内存中是以二进制的形式存放的,一般情况下,整型变量在内存中占用4个字节,也就是32位。
整型变量又可具体分为好几种,最基本的整型变量是用类型说明符int声明的符号整型。
整型变量可以是长整型、短整型或像上面定义的普通符号整型。
需要注意的是:
(1) 用signed对整型变量进行有符号指定是多余的,因为除非用unsigned指定为无符号型,否则整型都是有符号的。
(2) 当一个变量有多种特性时,声明关键字的顺序可以任意。
在使用不同的数据类型时,需要注意的是不要让数据超出范围,这也就是常说的数据溢出。对于整数来说,C语言不提供溢出的任何警告或提示,其只是简单地给出不正确的结果。溢出通常产生一个负数。对于有符号整数来说,如果对其最大值再加1,结果将变为最小值。这有点类似于在环形跑道上跑步,终点又是起点。
浮点型常量的表示方法
浮点型变量
浮点型变量的类型
C语言中的浮点数(floating point number)就是平常所说的实数。在C语言中,它有两种表示形式:
(1) 十进制数形式:由数字0~9和小数点组成。
(2) 指数形式:由十进制数加阶码标志e或E以及阶码(只能为整数,可以带符号)组成。
浮点型变量又称实型变量,用来存储带有小数的实数。浮点型变量分为单精度型(float)、双精度型(double)和长双精度型(long double)三类,浮点型变量定义的格式和书写规则与整型变量相同。
与整型变量不同,它是按指数形式存储。
字符常量
字符变量
字符串常量
字符常量分为一般字符常量和转义字符。一个字符常量在计算机的存储中占据一个字节。
1. 一般字符常量:一般字符常量是用单引号引起来的一个普通字符,其值为该字符的ASCII值。如'a'、'A'、
2. 转义字符:除了正常显示的字符外,还有一些控制符是无法通过正常的字符形式表示的,如常用的回车、换行、退格等。因此,C语言还使用了一种特殊形式的字符常量,这种特殊字符称为转义字符。
字符串常量是由一对双引号括起的字符序列。字符串常量和字符常量是不同的量。它们之间主要有以下区别:
(1) 字符常量由单引号引起来,字符串常量由双引号引起来。
(2) 字符常量只能是单个字符,字符串常量则可以含一个或多个字符。
(3) 可以把一个字符常量赋予一个字符变量,但不能把一个字符串常量赋给一个字符变量。在C语言中没有相应的字符串变量。这是与BASIC 语言不同的。但是可以用一个字符数组来存放一个字符串常量。
(4) 字符常量占一个字节的内存空间。字符串常量占的内存字节数等于字符串占的字节数加1。增加的一个字节中存放字符"\0"(ASCII值为0)。这是字符串结束的标志。
隐式转换
显式转换
C语言中设定了不同数据参与运算时的转换规则,编译器就会悄无声息地进行数据类型的转换,进而计算出最终结果,这就是隐式转换。隐式转换又称为自动转换,转换时应遵循以下规则。
(1) 若参与运算的量类型不同,则先转换成同一类型,然后再进行运算。
(2) 转换按数据长度增加的方向进行,以保证精度不降低。如int型和long型运算时,先把int量转换成long型后再进行运算。
(3) 所有的浮点运算都是以双精度进行的,即使仅含float型量运算的表达式,也要先转换成double型,再做运算。
(4) char型和short型参与运算时,必须先转换成int型。
(5) 在赋值运算中,赋值号两边量的数据类型不同时,赋值号右边量的类型将转换为左边量的类型。如果右边量的数据类型长度比左边长时,将丢失一部分数据,这样会降低精度,丢失的部分按四舍五入向前舍入。
进行隐式转换编译器是会产生警告的,提示程序存在潜在的隐患。如果非常明确地希望转换数据类型,就需要用显式转换。
在使用显式转换时应注意以下问题。
(1) 类型说明符和表达式都必须加括号(单个变量可以不加括号),如把(int)(x+y)写成(int)x+y则表示把x转换成int型之后再与y相加。
(2)无论是强制转换还是自动转换,都只是为了本次运算的需要而对变量的类型进行的临时性转换,不改变数据说明时对该变量定义的类型。
促进跨平台开发
定义类型别名
定义复杂的声明别名
typedef与#define
用typedef可定义与平台无关的类型。
定义一个称为BAN的浮点类型,在平台一上,让它表示的最高精度类型:
typedef long double BAN;
在不支持long double的平台二上,改为:
typedef double BAN;
在连double都不支持的平台三上,改为:
typedef float BAN;
当跨平台时,只用修改typedef本身,不用对其他源代码做任何修改。
typedef使用最多的地方是创建易于记忆的类型名,用它来将程序员的意图归档。但是typedef并不创建新的类型,它仅仅为现有类型添加一个同义字。
1. 定义基本数据类型别名
2. 定义数组别名
3. 定义指针别名
4. 定义结构体别名
为复杂的声明定义一个新的简单的别名。只要在原来的声明里逐步用别名替换一部分复杂声明,如此循环,把带变量名的部分留到最后替换,得到的就是原声明的最简化版。
理解复杂声明可用“右左法则”:从变量名看起,先往右,再往左,碰到一个圆括号就调转阅读的方向;括号内分析完就跳出括号,还是按先右后左的顺序,如此循环,直到整个声明分析完。
#define是预处理指令,在编译预处理时进行简单的替换,不进行正确性检查。而typedef是在编译时处理的,它在自己的作用域内给一个已经存在的类型定义一个别名,使用typedef定义的变量类型的作用范围为所定义的函数或者文件内。
注意:
(1) typedef是定义了一种类型的新别名,不同于宏,它不是简单的字符串替换。
(2) typedef在语法上是一个存储类的关键字,例如:auto、extern、mutable、static、register等,虽然它并不真正影响对象的存储特性。