{$cluname}

科伟奇论坛 » 嵌入式软件 » C语言中的编译预处理命令详解


‹‹上一主题 | 下一主题›› 查看 3720
发表一个新帖子 发表回复

标题 C语言中的编译预处理命令详解 在百度搜索本主题 [ 搜 ] [ 打印 ] [ 推荐 ] [收藏帖子] [ 收藏到新浪VIVI] [ 订阅 ]

会飞的鱼 (附小一年级)
楼主   [点击复制本网址] [ 字体: ] [ 编辑 ] [ 报告 ] [评分]
Rank:1
Rank:1
UID 118
帖子 7
积分 21 点
金币 36 枚
魅力 15 度
注册 2009年12月15日
C语言中的编译预处理命令详解
1、概述
C编译系统在对程序进行通常的编译之前,先进行预处理。C提供的预处理功能主要有以下三种:
(1) 宏定义
(2) 文件包含
(3) 条件编译
上述三种功能分别用宏定义命令、文件包含命令、条件编译命令来实现。由于预处理命令不是C语句,为了和一般的C语句相区分,这些命令以符号“#”开头。
2、宏定义
       (1) 不带参数的宏定义:用一个指定的标识符(即名字)来代替一个字符串,它的一般形式为
       #define 标识符字符串
       说明:
?           宏名一般习惯用大写字母表示,以便与变量名相区别;
?           使用宏名代替一个字符串,可以减少程序中重复书写某些字符串的工作量;
?           宏定义是用宏名代替一个字符串,也就是作简单的替换,预编译时不作正确性检查,只有在编译已被宏展开的源程序时才会发现错误并报错;
?           宏定义不是C语句,不必在行末加分号。如果加了分号则会连分号一起进行置换;
?           #define 命令出现在程序中函数的前面,宏名的有效范围为定义命令之后到本源文件结束。
?           可用#undef命令终止宏定义的作用域;
?           在进行宏定义时,可以引用已定义的宏名,可以层层置换;
?           对程序中用双引号括起来的字符串内的字符,即使与宏名相同,也不进行置换;
?           宏定义是专门用于预处理命令的一个专用名词,它与定义变量的含义不同,只作字符替换,不分配内存空间。
(2) 带参数的宏定义:不是进行简单的字符串替换,还要进行参数替换。其定义的一般形式为
#define 宏名(参数表) 字符串
字符串中包含在括号中指定的参数。
说明:
?           对带参数的宏的展开只是将语句中的宏名后面括号内的实参字符串代替#define命令行中的形参。
?           在宏定义时,在宏名与带参数的括号之间不应加空格,否则将空格以后的字符都作为替代字符串的一部分。
带参数的宏定义与函数的区别:
?           函数调用时,先求出实参表达式的值,然后代入形参;而是用带参数的宏只是进行简单的字符替换。
?           函数调用是在程序运行时处理的,分配临时的内存单元;而宏展开则是在编译时进行的,在展开时并不分配内存单元,不进行值的传递处理,也没有返回值的概念。
?           对函数中的实参和形参都要定义类型,二者的类型要求一致,如不一致应进行类型转换;而宏不     存在类型问题,宏名无类型,它的参数也无类型,只是一个符号代表,展开时代入指定的字符即可。宏定义时,字符串可以是任何类型的数据。
?           调用函数时只可得到一个返回值,而用宏可以设法得到几个结果。
?           使用宏次数多时,宏展开后源程序长,因为每展开一次都使程序增长;而函数调用不使源程序变长。
?           宏替换不占运行时间,只占编译时间;而函数调用则占运行时间(分配单元、保留现场、值传递、返回)
3、“文件包含”处理
       所谓“文件包含”处理是指一个源文件可以将另外一个源文件的全部内容包含进来,即将另外的文件包含到本文件之中。C语言提供了#include命令来实现“文件包含”的操作。其一般形式为
       #include“文件名”
      
       #include<文件名>
       说明:
?           一个include命令只能指定一个被包含文件,如果要包含n个文件,要用ninclude命令。
?           如果文件1包含文件2,而文件2要用到文件3的内容,则可在文件1中用两个include命令分别包含文件2和文件3,而且文件3应该出现在文件2之前。这样,如果文件2只被文件1包含而不会出现在其它场合,则在文件2中无须再包含3
?           在一个被包含文件中又可以包含另一个被包含文件,即文件包含是可以嵌套的。
?           被包含文件与其所在的文件在预编译后已成为同一个文件(而不是两个文件),因此,如果被包含文件中有全局静态变量,它也在包含它的文件中有效,不必用extern声明。
?           #include命令中,文件名可以用双引号或尖括号括起来,二者都是合法的。其区别是用尖括号时,系统到存放C库函数头文件所在的目录中寻找要包含的文件,这称为标准形式。用双引号时,系统先在用户当前目录中寻找要包含的文件,如找不到,再按标准方式查找。一般来说,调用库函数时用尖括号包含相关头文件以节约查找时间,调用用户编写的头文件(要放在当前目录下)一般用双引号。
4、条件编译
       一般情况下,源程序中所有的行都参加编译,但有时希望对其中一部分内容只在满足一定条件才进行编译,也就是对其中一部分内容指定编译的条件,这就是“条件编译”。条件编译有以下几种形式:
       (1) #ifdef 标识符
                     程序段1
          #else
                     程序段2
          #endif
       它的作用是当指定的标识符已经被#define命令定义过,则在程序编译阶段只编译程序段1,否则编译程序段2。其中#else部分可以没有。
(2) #ifndef 标识符
                     程序段1
#else
                     程序段2
        #endif
它的作用是若标识符未被定义过则编译程序段1,否则编译程序段2
(3) #if 表达式
                     程序段1
#else
                     程序段2
        #endif
     它的作用是当指定的表达式值为真(非零)时就编译程序段1,否则编译程序段2
       虽然直接用if语句也可以达到要求,但是用条件编译可以减少被编译的语句,从而减少目标程序的长度,减少运行时间。




此用户离线!
共计在线时长30分钟2009/12/15 11:32:08
[ 资料 ] [ 短信 ] [ 好友 ] [ 文集 ] [ 引用 ] [ 回复 ] 点击返回顶部

« 首页1 »1/共1页


查看积分策略说明快速回复你的内容
快捷回复标题 (选填) 快捷插入表情图标
验 证 码  点击获取验证码
快捷回复内容

自动复制

Powered by TEAM 2.0.5 Release - ACC © 2005 Team5 Studio All rights reserved