8.1 枚举类型
-
在实际问题中,有些变量的取值被限定在一个有限的范围内。例如,一个星期内只有七天,一年只有十二个月。为此,C语言提供了一种称为“枚举”的类型。枚举类型比整型或者字符型更为准确、合适
-
在“枚举”类型 的定义中列举出所有可能的取值,被说明为该“枚举”类型的变量取值不能超过定义的范围
- 即凡被说明为枚举类型,变量的取值只能是范围中的某值
-
枚举类型是一种基本数据类型,而不是一种构造类型,因为它不能再分解为任何基本类型
-
定义:
-
一般形式:
enum 枚举名{枚举值表};
枚举值表中罗列出所有可用值。这些值也称为枚举元素
-
-
说明:
-
先定义,后说明
enum weekday{ sun,mou,tue,wed,thu,fri,sat }; enum weekday a,b,c;
-
同时定义说明
enum weekday{ sun,mou,tue,wed,thu,fri,sat }a,b,c;
-
直接说明
enum { sun,mou,tue,wed,thu,fri,sat }a,b,c;
-
-
赋值:
-
枚举类型是常量,不能再使用赋值语句中赋值
-
枚举元素本身由系统定义了一个序号的数值,从 0 开始顺序为 0,1,2,……
-
只能把枚举值赋予枚举变量,不能把元素的数值直接赋予枚举变量
-
示例:
enum weekday { sun,mon,tue,wed,thu,fri,sat } a,b,c; a=sun; b=mon;
-
如一定要把数值赋予枚举变量,则必须用强制类型转换
a=(enum weekday)2;
意义是将顺序号为 2 的枚举元素赋予枚举变量 a
-
-
枚举元素不是字符常量也不是字符串常量,使用时不要加单、双引号
-
8.2 类型定义符 typedef
-
C语言不仅提供了丰富的数据类型,而且还允许由用户自己定义类型说明符,允许由用户为数据类型取“别名”
-
使用类型定义符 typedef 即可用来完成此功能
-
一般定义形式:
typedef 原类型名 新类型名
原类型名中含有定义部分
新类型名一般用大写表示,以便于区别
-
-
例如:有整型变量 a,b,说明为
int a,b;
,可把整型说明符用 typedef 定义为:typedef int INTEGER
。这以后就可用 INTEGER 来代替 int 作整型变量的类型说明了:INTEGER a,b;
-
意义:用 typedef 定义数组、指针、结构等类型带来很大的方便,不仅使程序书写简单而且使意义更为明确,因而增强了可读性
typedef char NAME[20]; NAME a1,a2,a3; //等效为 char a1[20],a2[20],s1[20],s2[20]
typedef struct stu { char name[20]; int age; char sex; } STU; STU body1,body2;
-
有时也可用宏定义来代替 typedef 的功能,后者更为灵活方便
- 宏定义是由预处理完成的
- typedef 则是在编译时完成的
8.3 位运算
-
前面介绍的各种运算都是以字节作为最基本位进行的。但在很多系统程序中常要求在位(bit)级进行运算或处理
-
C语言提供了位运算的功能,这使得 C语言也能像汇编语言一样用来编写系统程序
-
六种位运算符:
运算符 说明 描述 & 按位与 参与运算的两数各对应的二进位相与。只有对应的两个二进位均为 1 时,结果位才为 1,否则为 0。参与运算的数以补码方式出现 | 按位或 参与运算的两数各对应的二进位相或。只要对应的二个二进位有一个为 1 时,结果位就为 1。参与运算的两个数均以补码出现 ^ 按位异或 参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为 1。参与运算数仍以补码出现 ~ 取反 对参与运算的数的各二进位按位求反 << 左移 把“<<”左边的运算数的各二进位全部左移若干位,由“<<”右边的数指定移动的位数,高位丢弃,低位补 0 >> 右移 把“>>”左边的运算数的各二进位全部右移若 干位,“>>”右边的数指定移动的位数
对于有符号数,在右移时,符号位将随同移动。当为正数时,最高位补 0,而为负数时,符号位为 1,最高位是补 0 或是补 1 取决于编译系统的规定- 除了取反运算符是单目运算符外,其他均为双目运算符
-
位域(位段)
-
是指把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。这样就可以把几个不同的对象用一个字节的二进制位域来表示。例如在存放一个开关量时,只有 0 和 1 两种状态,用一位二进位即可
-
定义:位域定义与结构定义相仿
struct 位域结构名 {位域列表};
-
位域列表:
类型说明符 位域名:域名长度
-
示例:
struct bs { int a:8; int b:2; }
-
-
定义说明:
-
一个位域必须存储在同一个字节中,不能跨两个字节。如一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。也可以有意使某位域从下一单元开始
struct bs { unsigned a:4; unsigned :0; /*空域*/ unsigned b:4; /*从下一单元开始存放*/ unsigned c:4; }
a 占第一字节的 4 位,后 4 位填 0 表示不使用,b 从第二字节 开始,占用 4 位,c 占用 4 位
-
位域不允许跨两个字节,因此位域的长度不能大于一个字节的长度,也就是说不能超过 8 位二进位
-
位域可以无位域名,这时它只用来作填充或调整位置。无名的位域是不能使用的
struct k { int a:1; int :2; /*该 2 位不能使用*/ int b:3; int c:2; };
-
-
位域变量的说明与结构变量说明的方式相同,此处略
-
使用:
位域变量名·位域名
-
位域在本质上就是一种结构类型,不过其成员是按二进位分配的。
-
位域使得可在高级语言中实现数据的压缩,节省存储空间,同时也提高了程序的效率
-