C语言程序概述(四)

来源:互联网 发布:php的存储过程调用 编辑:程序博客网 时间:2024/05/17 10:38

C程序设计第9章:预处理命令
C语言提供的预处理功能主要有以下3种:1)宏定义;2)文件包含;3)条件编译
一、 宏定义
1. 不带参数的宏定义
用一个指定的标识符(即名字)来代表一个字符串,它的一般形式为
’#define标识符 字符串(这就是在前文已经介绍过的定义符号常量)
例:#define PI 3.1415926
它的作用是在本程序文件中用指定的标识符PI来代替“3.1415926”这个字符串,在编译预处理时,将程序中在该命令以后出现的所有的PI都用“3.1415926”代替。
有关宏定义的使用,需注意以下几点:
1 )宏名习惯采用大写,以便与普通变量区分;
2 )宏定义不是C语句,所以不能在行尾加分号;否则,宏展开时,会将分号也算在内
3 )在宏展开时,预处理程序仅按宏定义简单替换宏名,不做任何检查。如果有错误,只能由编译器在编译宏展开后的源程序时发现。
4 )宏定义的位置是任意的,宏名的有效范围是从定义命令处到本模块结束。通常写在文件开头处。
5 )宏调用时,是原样替换,不进行任何转换。
2. 带参数的宏定义
语法格式:#define 宏名(参数列表) 符号串序列
说明:宏定义的参数称为形参,只有参数名,没有数据类型,宏调用中的参数为实参。为了避免出错,在定义带参数的宏时,符号串序列内的形参通常要用括号括起来。
例: 带参数宏定义#define ADD(x, y) (x) + (y)
调用:total = ADD(6, 4*7);
替换规则:在编译预处理时,程序中凡是宏调用的地方一律按#define命令中的符号串序列从左到右进行替换(原样),再将宏调用的实参依次替换形参。对于符号串序列中不是参数字符的(如„(‟ 、„)‟、‟+‟等),则保留不变。
带参数的宏与函数的区别:
1)函数调用先求实参表达式的值,再代入形参;带参数的宏只是进行简单的字符替换,宏
展开的时候并不对实参表达式求值。 
2)函数调用是在程序运行时处理的,为形参分配临时的内存单元。而宏则是在编译前进行
的,不分配内存空间。
3)函数的参数需要数据类型,而宏不用。宏替换不占运行时间,只占编译时间,而函数调用则占运行时间(分配单元、保留现场、值传递、返回)。
‘#define常量定义与typede数据类型定义的异同点: #define P_INT int* //在编译前执行 (原样替换) typedef int* P_INT //在编译时执行
相同点:都是定义了一个int指针类型的别名
不同点:用#define时,P_INT a, b;相当于int* a, b;即int*a; int b;此时b不是int*,而是int 用typedef时,P_INT a, b;相当于int *a; int *b;
二、 “文件包含”处理
文件包含指一个源文件可以将另外一个源文件全部内容包含进来。常用于引用其他模块定义的变量类型、函数、宏定义等。这一过程通过预处理命令#include来完成。文件包含预处理语句的一般形式有两种:
(1)#include <文件名>:用<>时,系统到存放C库函数头文件所在的目录(即C编译系统的include子目录)中寻找要包含的文件(这称为标准方式,一般是系统文件)

2)#include “文件名” :用””时,系统先在用户创建工程所在的目录中寻找要包含的文件,若找不到,再按标准方式查找(即再按<>方式查找,一般是用户自定义的文件) 处理过程:预编译时,用被包含文件的内容取代该预处理命令。注:一个程序常常由许多文件组成,为了方便管理,常常将函数定义在.c文件中,而将函数的声明语句放在与.c文件同名的头文件(.h文件)中,这样就可以通过编译预处理实现函数的声明三、条件编译
通常情况下,源程序的所有语句都参加编译,但有时候也希望只对其中满足条件的语句进行编译,此时就要用到条件编译。条件编译是指编译器在开始编译前,根据条件编译指令,保留复合条件的程序块,而舍弃不符合条件的程序块。
条件编译的一般形式如下:
’#ifdef 标识符 程序块1 #else 程序块2 #endif ‘

功能:如果标识符已经被#define命令定义过,则在程序编译时只对程序块1进行编译,否则,只对程序块2进行编译。
如果将#ifdef换成#ifndef,则刚好相反,如果标识符没被#define命令定义过,则编译程序块1,否则编译程序块2。

0 0