【转载】C语言-预处理程序


我们可以在 C 源程序中插入传给编译程序的各中指令,这些指令被称为预处理器指令,它们扩充了程序设计的环境。现把常用的预处理命令总结如下:
1.       预处理程序
按照 ANSI 标准的定义,预处理程序应该处理以下指令:
#if
#ifdef
#ifndef
#else
#elif
#endif
#define
#undef
#line
#error
#pragma
#include
显然,上述所有的 12 个预处理指令都以符号 # 开始, ,每条预处理指令必须独占一行。
2.       #define
#define 指令定义一个标识符和一个串(也就是字符集),在源程序中发现该标识符时,都用该串替换之。这种标识符称为宏名字,相应的替换称为宏代换。一般形式如下:
#define macro-name char-sequence
这种语句不用分号结尾。宏名字和串之间可以有多个空白符,但串开始后只能以新行终止。
例如:我们使用 LEFT 代表 1 ,用 RIGHT 代表 0 ,我们使用两个 #define 指令:
#define LEFT 1
#define RIGHT 0
每当在源程序中遇到 LEFT RIGHT 时,编译程序都用 1 0 替换。
定义一个宏名字之后,可以在其他宏定义中使用 , 例如:
#define ONE 1
#define TWO ONE+ONE
#define THREE ONE+TWO
宏代换就是用相关的串替代标识符。因此,如果希望定义一条标准错误信息时,可以如下定义:
#define ERROR_MS “Standard error on input \n”
如果一个串长于一行,可在行尾用反斜线 ”\” 续行 ,如下:
#define LONG_STRING “This is a very very long \
String that is used as an example”
3.       #error
#error 指令强制编译程序停止编译,它主要用于程序调试。 #error 指令的一般形式是:
#error error-message
注意,宏串 error-message 不用双引号包围。遇到 #error 指令时,错误信息被显示,可能同时还显示编译程序作者预先定义的其他内容。
4.       #include
程序中的 #include 指令要求编译程序读入另一个源文件。被读入文件的名字必须用双引号 (“”) 或一对尖括号 (<>) 包围,例如:
#include “stdio.h”
#include <stdio.h>
都使 C 编译程序读入并编译头文件以用于 I/O 系统库函数。
包含文件中可以包含其他 #include 指令,称为嵌套包含。允许的最大嵌套深度随编译器而变。
文 件名被双括号或尖括号包围决定了对指定文件的搜索方式。文件名被尖括号包围时,搜索按编译程序作者的定义进行,一般用于搜索某些专门放置包含文件的特殊目 录。当文件名被双括号包围时,搜索按编译程序实时的规定进行,一般搜索当前目录。如未发现,再按尖括号包围时的办法重新搜索一次。
通常,绝大多数程序员使用尖括号包围标准的头文件,双引号用于包围与当前程序相关的文件名。
5.       条件编译指令
若干编译指令允许程序员有选择的编译程序源代码的不同部分,这种过程称为条件编译。
5.1#if #else #elif #endif
条件编译指令中最常用的或许是 #if,#else,#elif #endif 。这些指令允许程序员根据常数表达式的结果有条件的包围部分代码。
#if 的一般形式是:
#if constant-expression
 Statement sequence
#endif
#if 后的常数表达式为真,则 #if #endif 中间的代码被编译,否则忽略该代码段。 #endif 标记 #if 块的结束。
 
#else 指令的作用与 C 语言的 else 相似, #if 指令失败时它可以作为备选指令。例如:
#include <stdio.h>
#define MAX 100
 
Int main(void)
{
 #if MAX>99
 printf(“Compiled for array greater than 99.\n”);
 #else
 printf(“Complied for small array.\n”);
 #endif
 return 0;
}
注意, #else 既是标记 #if 块的结束,也标记 #else 块的开始。因为每个 #if 只能写一个 #endif 匹配。
 
#elif 指令的意思是“否则,如果”,为多重编译选择建立一条 if-else-if (如果 - 否则 - 如果链)。如果 #if 表达式为真,该代码块被编译,不测试其他 #elif 表达式。否则,序列中的下一块被测试,如果成功则编译之。一般形式如下:
#if expression
 Statement sequence
#elif expression1
 Statement sequence
#elif expression2
 Statement sequence
.
.
.
#elif expression
 Statement sequence
#endif
5.2#ifdef #ifndef
条件编译的另一个方法是使用编译指令 #ifdef #ifndef ,分别表示“如果已定义”和“如果未定义”。 #ifdef 的一般形式如下:
#ifdef macro-name
 Statement sequence
#endif
如果 macro-name 原先已经被一个 #define 语句定义,则编译其中的代码块。
#ifndef 的一般形式是:
#ifndef macro-name
 Statement sequence
#endif
如果 macro-name 当前未被 #define 语句定义,则编译其中的代码块。
#ifdef #ifndef 都可以使用 #else #elif 语句。
 
#inlucde <stdio.h>
#define T 10
 
Int main(void)
{
 #ifdef t
 Printf(“Hi T\n”);
 #else
 Printf(“Hi anyone\n”);
 #endif
 #ifndef M
 Printf(“M Not Defined\n”);
 #endif
 
 Return 0;
}
6.       #undef
#undef 指令删除前面定义的宏名字。也就是说,它“不定义”宏。一般形式为:
#undef macro-name
7.       使用 defined
#ifdef 之外,还有另外一种确定是否定义宏名字的方法,即可以将 #if 指令与 defined 编译时操作符一起使用。 defined 操作符的一般形式如下:
defined macro-name
如果 macro-name 是当前定义的,则表达式为真,否则为假。
例如,确定宏 MY 是否定义,可以使用下列两种预处理命令之一:
#if defined MY
#ifdef MY
也可以在 defined 之前加上感叹号 ”!” 来反转相应的条件。例如,只有在 DEBUG 未定义的情况下才编译。
#if !defined DEBUG
 Printf(“Final Version!\n”);
#endif
使用 defined 的一个原因是,它允许由 #elif 语句确定的宏名字存在。
8.       #line
#line 指令改变 __LINE__ __FILE__ 的内容。 __LINE__ __FILE__ 都是编译程序中预定义的标识符。标识符 __LINE__ 的内容是当前被编译代码行的行号, __FILE__ 的内容是当前被编译源文件的文件名。 #line 的一般形式是:
#line number “filename”
其中, number 是正整数并变成 __LINE__ 的新值;可选的“ filename ”是合法文件标识符并变成 __FILE__ 的新值。 #line 主要用于调试和特殊应用。
9.       #pragma
#pragma 是编译程序实现时定义的指令,它允许由此向编译程序传入各种指令。例如,一个编译程序可能具有支持跟踪程序执行的选项,此时可以用 #pragma 语句选择该功能。编译程序忽略其不支持的 #pragma 选项。 #pragma 提高 C 源程序对编译程序的可移植性。
10.  预处理操作符 # ##
有两个预处理操作符: # ## ,它们可以在 #define 中使用。
操作符 # 通常称为字符串化的操作符,它把其后的串变成用双引号包围的串。例如:
#include <stdio.h>
#define mkstr(s) #s
int main(void)
{
 Printf(mkstr(I like C));
 
 Return 0;
}
 
预处理程序把以下的语句:
Printf(mkstr(I like C));
变成
Printf(“I like C”);
操作符 ## 把两个标记拼在一起,形成一个新标记。例如:
#include <stdio.h>
#define concat(a,a) a##b
 
int main(void)
{
 Int xy = 10;
 Printf(“%d”,concat(x,y));
 Return 0;
}
预处理程序把以下语句:
Printf(“%d”,concat(x,y));
变成
Printf(“%d”,xy);
操作符 # ## 主要作用是允许预处理程序对付某些特殊情况,多数程序中并不需要。
11.  预定义宏
C 规范了 5 个固有的预定义宏,它们是:
__LINE__
__FILE__
__DATE__
__TIME__
__STDC__
 
__LINE__ __FILE__ 包含正在编译的程序的行号和文件名。
__DATE__ 和内容形如 month/day/year( / / ) 的串,代表源文件翻译成目标码的日期。
__TIME__ 中的串代表源代码编译成目标码的时间,形如 hour:minute:second( 时:分:秒 )
如果 __STDC__ 的内容是十进制常数 1 ,则表示编译程序的实现符合标准 C
 
 
Over, 呵呵,有点累,呵呵,希望对想了解 C 语言预处理命令的人有帮助。 ^-^
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值