预处理器(Preprocessor)的产生:当C 还在发展阶段时,发展的工程师了解到 C 需要有能力来处理 named constants, macros 还有 include files,其解决之道为将代码交给编译器(compiler)前使用预处理器来辨识并处理其该处理的 constructs。其实 预处理器 只是一个特殊化的文字编辑器(text editor)。
最简单的用法为:
#define FOO bar
如:
#define SIZE 20
int main() {
printf("%d",SIZE);
return 0;
}
C 允许使用者去检查preprocessor 执行之后的输出(output),使用以下 command:
#cc –E filename.c
程式也可以#define 在preprocessor 中使用
#define DIE \
fprintf(stderr,"Fatal Error:Abort\n");exit(8);
如:
#include <stdio.h>
#define DIE \
fprintf(stderr,"Fatal Error:Abort\n");exit(8);
int main() {
if(1<0)
DIE;
printf("you are right!\n");
return 0;
}
const vs #define
因为在#define一开始出来的时候, C 的 const 还未出现,但是建议尽量使用const 因为const 可以被C compiler 检查syntax , 遵守scope 规则而且可以用在包括structureclass在内的C constant而#define 一般只能用在定义constant
#define 配上#ifdef,#endif或#ifndef, #endif 也可以变成debug的好工具,同时也可以用在跨平台的coding上,如下:
#include <stdio.h>
#define DEBUG
int main() {
#ifdef DEBUG
printf("Debugging program puts here\n");
#endif
return 0;
}
也可以加上#else来做
#include <stdio.h>
#define DEBUG
int main() {
#ifndef DEBUG
printf("not debugging version\n");
#else
printf("debugging version\n");
#endif
return 0;
}
也可以用compiler 来#define,一般的格式为 –Dsymbol或-Dsymbol=value,如原始码参上,而在commandline 下指令:
#gcc -DDEBUG -g -o hi big.c
而对此程式码…
#include <stdio.h>
int main() {
#ifndef DEBUG
printf("not debugging version\n");
#else
printf("debugging version\n");
#endif
printf("%d\n",MAX);
return 0;
}
下指令:
#gcc -DMAX=10 -o hi big.c
大部份的C compiler 会自动定义一些 system-dependent的symbol,如:Turbo C++ 定义 _ _TURBOC_ _和_ _MSDOS_ _然后ANSI标准的compiler定义_ _STDC_ _大部份的UNIX compiler为了系统定义名,如 SUN, VAX, Celerity,等而_ _unix_ _总是在所有的UNIX机器中定义。
Include files
一般我们在用的
#include <stdio.h>
这是告诉preprocessor 将stdio.h置入程式,而stdio.h称为header file,一般而言,这些档案在linux 会在/usr/include;而在MS-DOS/Windows会在compiler指定安装的路径上。
而local include file 则会使用以下的方式:
#include “shanwu.h”
也可以用一个relative path:
#include “…/../shanwu.h”
或是一个absolute path(应避免使用,会造成程式nonportable):
#include “ /home/shanwu/Desktop/header/shanwu.h”
在windows 系统不是使用 “/” 而是使用 “\”,如下图
如a.h和b.h都有#include c.h的话,而我们如果需要有a.h 和 b.h 的话,c.h 便要加上
#ifndef_C_H_INCLUDED_
#define_C_H_INCLUDED_
#endif
避免产生重复定义 “c.h”的情况。重复定义一个常数不是错误,但重覆定义一个数据结构或 union 则是。
Parameterized Macros
C的preprocessor之macro也可以有parameters如:
#include<stdio.h>
#defineSQR(x) ((x)*(x))
int main() {
printf("%d\n",SQR(13));
return 0;
}
其实preprocessor 的功能不只这些,更进一步的知识请参考 C reference manual
练习:用micro来测一个数是否能被10整除
#include <stdio.h>
#define check(x) {if((x)%10!=0)printf("TRUE\n");else printf("FALSE\n");}
int main()
{
check(12)
return 0;
}
#define check(x) { \
if((x)%10!=0) \
printf("TRUE\n"); \
else \
printf("FALSE\n"); \
}