编译程序之前,先由预处理器检查程序。根据程序中使用的预处理器指令,预处理器用符号缩略语所代表的内容替换程序中的缩略语。
1.编译器的处理步骤:
(2)编译器查找反斜线后面紧跟换行符的实例并删除这些实例。将多个物理行替换为一个逻辑行。
(3)编译器将文本划分为预处理的语言符号(token)序列和空白字符及注释序列(编译器会将注释序列替换为一个空格字符。所以注释序列可以出现在源代码的任何地方)。
2.预处理器(preprocessor)种类
预处理器可以使用反斜线和换行符组合可以横跨多个物理行,但是其最终只占用一个逻辑行。
第一部分:#define定义常量
#define ADD(X, Y) X + Y //compiled rightly, but not safe enough #define ADD(X, Y) ((X) + (Y)) //good #define ADD (X, Y) ((X) + (Y)) //error! No spaces between ADD and (X, Y)
如 #define NAME(N) x N 中x N就是空格符隔开的两个token。但是如果#define NAME(N) x ## N 就是将NAME(N)替换为xN.
第二部分:文件包含 #include
1
2
3
4
5
6
7
8
9
10
11
12
13
14 |
#ifndef _FILE_DEFINED #define _FILE_DEFINED typedef
struct _iobuf { char * _ptr; int
_cnt; char * _base; int
_flag; int
_file; int
_charbuf; int
_bufsiz; char * _tmpfname; } FILE ; #endif /* Not _FILE_DEFINED */ |
6,如果某个变量要多个文件共享。则可以在头文件中进行引用声明。
1
2
3 |
extern
int status; //头文件中 int
status; //源文件中 |
7,如果某个const常量需要多个文件共享。则可采用在头文件中声明static const int MAX = 100;
8,内联函数,inline function。因为编译器优化时,必须知道函数定义的内容。所以源文件调用的内联函数的定义,必须在此源文件中。inline 函数具有内部链接,可以将inline function定义放在头文件中。但是普通函数具有外部链接,则只能有一次定义。
第三部分:其它指令。因为系统变量多用宏定义。所以它们多用于更改宏定义。改变编译时编译环境,方便移植系统。
#undef指令:取消定义一个给定的#define,即使该宏之前未被定义。可用于重定义某个宏。
条件编译指令:#if、#ifdef、#ifndef、#else、#elif、#endif
,判断该标识符是否已经被#define或者是否还未被#define定义。#ifndef多用于防止多次包含同一头文件。#else作用类似if-else语句中的else,选择不同块。
如果表达式非零或者为真,则为真。#if 可以和defined运算符结合。defined(X),如果标识符X已经定义,返回1,否则返回0.#if defined优点为可以和#elif结合。
#if、#ifndef、#ifdef后面必须有对应的#endif。这样相当于if-else语句中的{},划分出指令的作用范围。
#line :指令用于重置由__LINE__和__FILE__宏报告的行号和文件名 。#error:指令使预处理器发出一条错误消息,该消息包含指令中的文本。#warning:指令是预处理器发出一条警告消息,该消息包含指令中的文本。
#line 100 //将__LINE__设置为100 #line 100 "new.c" //将__LINE__设置为100, 文件名设置为"new.c" #line "new.c" //错误,#line参数只能为上述两种形式 #error This is a example.//编译器编译到这句会报错。 #warning This is a warning//编译器编译到这句,会发出警告
第四部分:重要的C库
通用工具库:#include <stdlib.h>
快排函数qsort() 函数原型:void qsort(void *base, size_t nmemb, size_t size, int (*cmpar)(const void *, const void *));
ANSI C支持将任何数据类型指针转换为void类型指针。第一个参数为要排序的数组头部的指针,第二个参数为参与排序的项目数量。因为第一个参数为void *,所以第三个参数为数据对象的大小。第三个为排序函数,返回值分别为正,零,负,代表大,相等,小于。
原文:http://www.cnblogs.com/xyqhello/p/3632198.html