014-预处理指令-C语言笔记

学习目标

1.【掌握】枚举

2.【掌握】typedef关键字

3.【理解】预处理指令

4.【掌握】#define宏定义

5.【掌握】条件编译

6.【掌握】static与extern关键字

一、枚举

当我们要描述方向、四季、性别、学历、婚配情况等等事物的时候,我们知道这些事物的取值范围是非常有限的。比如,性别取值就男、女,四季取值就春、夏、秋、冬。类似这样的需求,C语言提供了一种构造类型枚举专门针对此类需求,由程序员自己声明一种新的数据类型,并给这个新的数据类型声明几个固定枚举值。同时,声明这个新的数据类型的变量时,给变量赋值的取值范围就只能赋值我们类型里声明的某个固定枚举值。

枚举类型的声明

语法:enum 枚举名 {枚举值1,枚举值2,...};

枚举变量的声明

语法:enum 枚举名 变量名;

变量的初始化

语法:enum 枚举名 变量名 = 枚举值;

枚举值对应的整型数值

注意:

1.枚举也是一种数据类型,类型名是(enum 枚举名),必须要加上enum关键字啊。

2.给枚举变量初始化或者赋值的时候,取值只能取枚举类型的枚举值中的某个值,不能随意赋值。

3.每一个枚举值对应都有一个整型数值的,从第一个枚举值开始从0依次递增。

4.声明一个枚举变量的时候,这个变量里面存的实际上是这个枚举值对应的整型,而不是枚举值本身。

5.枚举值命名最好能加上区分这个枚举值属于哪个枚举类型的标示,比如在枚举值前面加上枚举类型名。

实际应用:

二、typedef关键字

如果你感觉有些数据类型太长,难以记忆难以书写,我们可以使用typedef关键字为各种数据类型定义一个新名字(别名)。

语法:typedef 数据类型 别名;

typedef与普通数据类型

typedef与指针

typedef与结构体

typedef与指向结构体的指针

typedef与枚举

typedef与指向函数的指针

三、预处理指令

让我们来回顾一下C程序从编写源代码到执行需要的步骤。先编写符合C语言语法规范的源代码文件,然后编译成二进制代码的目标文件,再然后会进行链接,最终生成可执行文件。其实在编译之前,还有一个很重要的步骤,系统会自动执行,那就是执行预处理指令。预处理指令是在编译之前执行的,我们已经学过#include文件包含指令,今天我们再来整几发指令。

四、#define宏定义

在程序编译之前,会把使用宏名的地方替换成宏值的内容。注意这里的替换是纯洁的替换,无论宏值是表达式还是数值,甚至是错误代码,都会原模原样的替换。

语法:#define 宏名 宏值

无参数的宏:使用无参数宏的时候,只是纯粹的文本替换

有参数的宏:使用有参数宏的时候,需要调用宏的人传入一个值作为宏值的一部分

注意:

1.当宏值是一个表达式,宏值的语法错误不会报错,因为检查语法是在编译的时候干的。

2.当宏值是一个表达式,替换宏名也是替换源代码中使用宏名的地方,所以特别注意替换后的运算符优先级问题。

3.宏值当中如果有变量,使用宏值之前必须要先声明这个变量。

4.如果双引号中出现了宏名,其实这个不是宏名,只是和宏名很像的字符串。

5.宏可以定义在任何地方,能被使用的作用域是从定义开始到文件结束。

五、条件编译

014-预处理指令-C语言笔记

在很多情况下,我们希望程序的其中一部分代码只有在满足一定条件时才进行编译,否则不参与编译,这就是条件编译。

语法:

执行顺序:如果条件1满足,则代码1参与编译。如果条件1不满足,条件2满足,则代码2参与编译。如果条件1和条件2都不满足,则执行代码3。

第一种情况,判断宏值是否满足条件

第二种情况,判断一个宏有被定义

第三种情况,判断一个宏没有被定义

注意:

1.条件编译一定要使用宏进行条件判断,不能使用变量,因为变量的值是在程序执行的时候才赋值的。

2.#endif表示这个条件编译结束,一定不能少,不然会发生一些不可预料的事情。

3.条件编译只会编译符合条件的那一个分支编译成二进制代码。

六、static与extern关键字

static与函数

如果一个函数被static关键字修饰,只能在当前模块中使用,就相当于内部函数咯。

extern与函数

如果一个函数被extern关键字修饰,可以在当前模块中使用,也能被其他模块共享,不过默认函数就是被extern修饰的,可以省略不写。

static与变量

被static修饰的局部变量会声明在常量区中,函数执行完毕后不会被释放,只有程序执行结束才会释放。

被static关键字修饰的全局变量只能在当前模块中使用,不能被其他模块共享,相当于私有全局变量。

main.c文件

test.h文件

test.c文件

extern与变量

extern不能修饰局部变量,被extern修饰的全局变量可以在当前模块中使用,也能被其他模块共享。不过默认全局变量就是extern修饰的,所以我们可以省略(Xcode6.3前是默认加extern的,Xcode6.3后必须自己在声明里加上extern,但定义的地方可以不写)。

main.c文件

test.h文件

test.c文件

六阿哥

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: