C语言预处理命令解析
时间:2016-12-16作者:华清远见
C语言的源代码中可以包括各种编译指令,这些指令就称之为预处理命令。虽然它们实际上不是c语言的一部分,但却扩展了c程序设计的环境,预处理程序和注释简化程序开发过程,并且提高程序的可读性。然而这些命令是在编译前由预处理程序对源文件的预处理文件进行加工。 预处理是在c语言编译的4个阶段(预处理、编译、汇编、链接)的第一个阶段。 C语言的预处理功能有一下3种: 1,宏定义 2,文件包含 3,条件编译 分别用宏定义命令、文件包含命令、条件编译命令实现,为了与其他的c语句区别,预处理命令以符号#开头。 下面领着大家逐个了解学习这些预处理命令。 一:宏定义: 不带参数的宏定义 一般形式: #define 标识符 字符串 作用:用一个特定的标识符来代表一个字符串。 如:#define PI 3.1415926 在编译处理时,把程序中在该命令之后的所有PI都用“3.1415926”替换。这个标识符(名字)称为“宏名”,在预编译时将宏名替换成字符串的过程叫做“宏展开”。 注意: 1,宏名一般习惯用大写来表示; 2,用宏名代替一个字符串,可以减少在程序书写的过多的繁琐的事件,当需要某一个常量时,只需要改变#define命令即可; 3,宏定义简单的说就是置换,不做正确性检查,假如写错了,预处理也会照样带入,只有在编译已被宏展开的源程序时才报错; 4,宏定义不是语句,不需要分号; 5,宏定义程序中函数的外部,作用范围是在定义之后到本源程序结束; 6,可以使用#undef命令终止宏定义作用域;例如: #define H 9.9 main() { ...........; } #undef H gg() { .............;} 以上可以看出:H的作用域就只有在main起作用。 7,宏定义时,可以使用已经定义的宏定义,可以层层置换; 8,对程序中用双引号括起来的字符,即使与宏名相同,也不会进行置换(printf()函数的格式化输出); 9,宏定义与定义变量含义不一样,只做字符替换,不会分配空间; 带参数的宏: 定义的一般形式: #define 宏名(参数列表) 字符串 例如:
注意: 1,对带参数的宏展开,只是将语句中的宏名后面的括号内的实参字符串代替#define命令行中的参数; 2,宏定义时,宏名与带参数的括号不得有空格; 带参数的宏定义与函数的区别: 函数调用时,先求出实参表达式的值,然后带形参; 而使用带参数的宏只是进行简单的字符替换; 函数调用是在程序运行时处理的,分配临时的内存单元; 而宏展开是在编译时进行的,在展开时并分配内存单元,不进行值的传递处理,也没有“返回值”的概念; 函数中的实参和形参都要定义类型,二者类型要求一致,若不一致,应进行类型转换; 而宏不存在类型问题,宏名无类型,参数也无类型,展开时带入指定的字符即可。宏定义时,字符串可以是任何类型的数据; 调用函数可以得到一个返回值; 而用宏可以设法得到几个结果; 使用宏次数多时,展开后源程序长; 而函数调用不会使源程序变长; 宏替换不占运行时间,只占编译时间; 而函数调用则占运行时间(分配单元、值传递、返回等等); 二:文件包含 含义:指将其他文件的内容全部包括进来,即将另外的文件内容包含到本文件中。 用法: #include<文件名> 或#include”文件名” #include<文件名>与#include“文件名”的差异。 使用<>和""的区别:使用尖括号时,系统到存放C库函数的头文件的目录中去找要包含的文件,这称为标准方式。使用引号时,系统优先在用户当前目录下查找要包含的文件,若找不到,再按标准方式查找。 说明: 1,一个include命令只能指定一个被包含文件,若要包含n个文件,要用n个include命令; 2,如果一个文件包含了1.h,而文件1.h用到了3.h的内容,则可在文件中如下定义: #include“1.h” #include“2.h” 3,文件包含可以嵌套,即在一个被包含文件,又可以包含另一个文件 三:条件编译 一般情况下,源程序中所有的文件都要参加编译。但有时只需要程序的一部分代码进行编译,这时就要指定编译条件,这就是条件编译。 条件编译有以下几种形式: 用法1: #ifdef 标识符 程序段1 #else 程序段2 #endif 说明:当定义过标识符,则编译程序段1,否则编译程序段2。#else部分可以省略,即: #ifdef 程序段1 #endif 用法2: #ifndef 标识符 程序段1 #else 程序段2 #endif 说明:与上一种类似,只不过将ifdef换成ifndef。当未定义过标识符,则编译程序段1,否则编译程序段2。#else部分可以省略 用法3: #if 表达式 程序段1 #else 程序段2 #endif 说明:当指定的表达式是真(非零)的时候,编译程序段1,否则编译程序段2。#else部分可以省略 以下示例(防止头文件重复包含):
发表评论
|