一、枚举类型的定义
1、基本数据类型
>指针
>空类型 void
>构造类型:数组、结构体、共用体
在实际问题中,有些变量的取值被限定在一个有限的范围内。例如,一个星期内只有七天,一年只有十二个月。如果把这些量说明为整体,字符型或其它类型显然是不妥当的。
C语言提供了一种称为“枚举”的类型。在“枚举”类型的定义中列举出所有可能的取值,被说明为该“枚举”类型的变量取值不能超过定义的范围。
应该说明的是,枚举类型是一种基本数据类型,而不是一种构造类型,因为它不能再分解为任何基本类型。
2、枚举类型的定义
枚举类型定义的一般形式为:
enum 枚举类型名{枚举值1,枚举值2,枚举值3......};
在枚举值表中应罗列出所有可用值。这些值也称为枚举元素。
例如:该枚举名为weekday,枚举值共有7个,即一周中的七天。凡被说明为weekday类型变量的取值只能是七天中的某一天。
定义一个变量,保存一周的第几天
enum weekday{zhouyi,zhouer,zhousan,zhousi,zhouwu,zhouliu,zhouri};
3、枚举变量的定义和使用
1>枚举类型变量
如同结构和联合一样,枚举变量也可用不同的方式说明,即先定义后说明,同时定义说明或直接说明。设有变量a,b,c被说明为上述的weekday。
可采用下述任一种方式:
先定义枚举后定义枚举变量:
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;
2>枚举类型变量的初始化
a=sun;
b=tue;
c=fri;
3>枚举变量的使用
printf("%d\n",a);
说明:枚举类型定义完成以后,系统会自动给枚举的每个元素都会赋值一个整形的初值
默认初值:从第一个元素开始值为0,以后各元素的值,是上一个元素的值+1
下面我们用实例来看看
打印如下:
总结:
在枚举类型定义中,默认为nan的值为0
改进如下:
打印如下:
总结:
在枚举类型定义中,进过我们设定nan的值为4
二、typedef关键字介绍
C语言中的结构类型:
结构数据、空、构造、指针、定义类型
1、概念及语法格式
C语言不仅提供了丰富的数据类型,而且还允许由用户自己定义类型说明符,也就是说允许由用户 为数据类型取 ”别名“
typedef定义的一般形式为:
typedef 原类型名 新类型名;
其中原类型名中含有定义部分,新类型名一般用大写表示,以便于区别。
有时也可用宏定义来代替typedef的功能,但是宏定义是由预处理完成的
而typedef则是在编译时完成的,后者更为灵活方便
2、typedef使用方法
1>基本数据类型
例如,有整形量a、b、其说明如下:
int a,b;
其中 int 是整形变量的类型说明符。int 的完整写法为 integer,为了增加程序的可读性,可把整形说明符用typedef定义为:
typedef int INTEGER
这以后就可用INTEGER来代替 int 作整形变量的类型说明了。
例如:
INTEGER a, b;
等效于:
int a, b;
2>用在数组,给数组起别名
typedef int sz[5]; //sz相当于具有了”数组的功能“,
sz定义的变量都是一个数组,并且长度为5,存储的内容是int类型的
例如:
打印如下
3>给结构体取别名
struct person
{
char *name;
int age;
};
typedef struct person p; //这表明结构体person可以用 p来代替
//现在用p来定义一个结构体变量并且初始化
p p1={"移动",10086};
实例如下
程序代码如下:
打印如下:
4>给枚举类型取别名
//先定义枚举类型
enum sex{nan,nv};
//给枚举类型起别名
typedef enum sex isex;
//用别名来定义枚举变量
isex s1=nan;
实例如下:
程序代码如下:
打印如下:
5>给函数指针起别名
//定义指针函数
int (*p)(int ,int);
//给函数中的指针起别名
typedef int (*FUN)(int,int); //这个别名FUN就像上面的数组sz一样具有相同的功效
用FUN定义的变量是一个函数指针变量
//定义函数指针变量
FUN f1;
f1=jia;
实例如下:
打印如下:
三、预处理指令
1、基本概念
以“#”号开头的为预处理命令。如包含命令#include,宏定义命令#define等。在源程序中这些命令都放在函数之外,而且一般都放在源文件的前面,它们称为预处理部分
所谓预处理是指在进行编译的第一遍扫描(词法扫描和语法分析)之前所作的工作。预处理是C语言的一个重要功能,它由预处理程序负责完成。当对一个源文件进行编译时,系统将自动引用预处理程序对源程序中的预处理部分作处理,处理完毕自动进入对原程序的编译。
C语言提供了多种预处理功能,如宏定义、文件包含、条件编译等。合理地使用预处理功能编写的程序便于阅读、修改、移植和调试,也有利于模块化程序设计。
2、宏的概念
被定义为“宏”的标识符称为“宏名”。在编译预处理时,对程序中所有出现的“宏名”,都用宏定义中的字符串区代换,这称为“宏代换”或“宏展开”。
宏定义是由源程序中的宏定义命令完成的,宏代换是由预处理程序自动完成的。在C语言中,“宏”分为有参数和无参数两种。
3、无参数宏
无参数宏的宏名后不带参数。其定义的一般形式为:
#define 标识符 字符串
其中的“#”表示这是一条预处理命令。凡是以“#”开头的均为预处理命令。“define”为宏定义命令。“标识符”为所定义的宏名。“字符串”可以是常量、表达式、字符串等。
无参数宏使用注意事项
1>习惯上宏名用大写字母表示,以便于与变量区别。但也允许用小写字母
2>宏定义是用宏名来表示一个字符串,在宏展开时又以该字符串取代宏名,这只是一种简单的代换,字符串中可以含任何字符,可以是常数,也可以是表达式,预处理程序对它不作任何检查。如有错误,只能在编译已被宏展开后的源程序时发现。
3>宏定义不是说明或语句,在行末不必加分号,如加上分号则连分号也一起置换
4>宏定义必须写在函数之外,其作用域为宏定义命令起到源程序结束。如要终结其作用域可使用#undef命令。
通过实例来看看宏定义
程序如下:
打印如下:
下面我们进过改一下宏定义看看效果
程序代码如下
打印如下:
总结:
从上图可以看出宏定义是直接带入展开,它并不会做任何检查和运算
4、有参宏定义
C语言允许宏带有参数。在宏定义中的参数称为形式参数,在宏调用中的参数称为实际参数。
对带参数的宏,在调用中,不仅要展开,而且要用实参取去代换参数。
带参宏定义的一般形式为:
#define 宏名(参数表) 字符串
在字符串中含有各个参数。
实例如下
程序代码如下
打印如下
5、有参宏使用注意事项
1>带参宏定义中,形参之间可以出现空格,但是宏名和形参表之间不能有空格出现
2>在带参宏定义中,形式参数不分配内存单元,因此不必作类型定义。而宏调用中的实参有具体的值。要用它们去代换形参,因此必须作类型说明。这是与函数中的情况不同的。在函数中,形参和实参是两个不同的量,各有自己的作用域,调用时要把实参值赋予形参,进行“值传递”。而在带参宏中,只是符号代换,不存在值传递的问题。
3>在宏定义中的形参是标识符,而宏调用中的实参可以是表达式
4>在宏定义中,字符串内的形参通常要用括号括起来以避免出错。
5>宏定义也可用来定义多个语句,在宏调用时,把这些语句又代换到源程序内。
例题:
使用有参宏实现判断两个数的大小
程序如下
打印如下
6、typedef 和#define 的区别
#define 和 typedef 的区别
应注意用宏定义表示数据类型和用typedef定义说明符的区别。
宏定义只是简单的字符串代换,是在预处理完成的
而typedef是在编译时处理的,它不是作简单的代换,而是对类型说明符重新命名。被命名的标识符具有类型定义说明的功能
实例如下
程序如下
打印如下
总结:
从这里可以看出#define 和 typedef区别是很大的
#define INT1 int //表示在程序中有INT1出现的地方用 int来代替
typedef int INT //表示 INT是int的另一个名字,INT具有int的功能