编译预处理小结

上传人:mg****85 文档编号:34044438 上传时间:2018-02-20 格式:DOCX 页数:6 大小:19.33KB
返回 下载 相关 举报
编译预处理小结_第1页
第1页 / 共6页
编译预处理小结_第2页
第2页 / 共6页
编译预处理小结_第3页
第3页 / 共6页
编译预处理小结_第4页
第4页 / 共6页
编译预处理小结_第5页
第5页 / 共6页
点击查看更多>>
资源描述

《编译预处理小结》由会员分享,可在线阅读,更多相关《编译预处理小结(6页珍藏版)》请在金锄头文库上搜索。

1、概述一、C 语言由源代码生成可执行文件的各阶段如下:C 源程序编译预处理 编译 优化程序汇编程序 链接程序可执行文件 其中 编译预处理阶段,读取 c 源程序,对其中的伪指令(以 #开头的指令)和特殊符号进行处理。或者说是扫描源代码,对其进行初步的转换,产生新的源代码提供给编译器。预处理过程先于编译器对源代码进行处理。在 C 语言中,并没有任何内在的机制来完成如下一些功能:在编译时包含其他源文件、定义宏、根据条件决定编译时是否包含某些代码。要完成这些工作,就需要使用预处理程序。尽管在目前绝大多数编译器都包含了预处理程序,但通常认为它们是独立于编译器的。预处理过程读入源代码,检查包含预处理指令的语

2、句和宏定义,并 对源代码进行响应的转换。预处理过程还会删除程序中的注释和多余的空白字符。二、伪指令(或预处理指令)定义预处理指令是以# 号开头的代码行。# 号必须是该行除了任何空白字符外的第一个字符。#后是指令关键字,在关键字和# 号之间允许存在任意个数的空白字符。整行语句构成了一条预处理指令,该指令将在编译器进行编译之前对源代码做某些转换。预处理指令:# 空指令,无任何效果 #if 如果给定条件为真,则编译下面代码 #ifdef 如果宏已经定义,则编译下面代码#ifndef 如果宏没有定义,则编译下面代码#else #elif 如果前面的#if 给定条件不为真,当前条件为真,则编译下面代码#

3、endif #define 定义宏#undef 取消已定义的宏#line#error 停止编译并显示错误信息#pragma#include 包含一个源代码文件注意:#if #ifdef #ifndef 用法一致,其后均可与#elif #else #endif 组合使用预编译程序所完成的基本上是对源程序的“替代”工作。经过此种替代,生成一个没有宏定义、没有条件编译指令、没有特殊符号的输出文件。这个文件的含义同没有经过预处理的源文件是相同的,但内容有所不同。下一步,此输出文件将作为编译程序的输入而被翻译成为机器指令。宏指令#define#undef #define 主要用来定义符号常量(可以是数字

4、常量与字符串常量)与参数宏宏扩展:预处理过程会把源代码中出现的宏标识符(必须前后均含有空白等分隔符且不能被引号括起来才可能被视为宏)替换成宏定义时的值。宏最常见的用法是定义代表某个值的全局符号。宏的第二种用法是定义带参数的宏(宏函数),这样的宏可以象函数一样被调用,但它是在调用语句处展开宏,并用调用时的实际参数来代替定义中的形式参数。多个宏的扩展顺序是按照从上往下定义的顺序来的。宏定义符号常量的优点:定义的宏有了意义,可读性强;容易修改。参数宏中三点用法:1、# 参数出现在宏定义体中,#后面跟的宏参数 x,相当于x,但与直接写x不同的是此处的 x 会被视为宏参数。有时将 #称为字符串化运算符。

5、如:#incldue #define PSQR(x) printf(the square of #x is %d.n,(x)*(x)int main(void)int y =4;PSQR(y);PSQR(2+4);return 0;输出结果:the square of y is 16.the square of 2+4 is 36.第一次调用宏时使用“y”代替#x;第二次调用时用“2+4代#x2、#可以把前后两个字符串何在一起,一般用在变量名有规律变化时,且一般用在带参数宏中,当然也可以用于不带参数宏中(这一点与#不一样)如:#define XNAME(n) x#n这样宏调用:XNAME(4)

6、展开后:x4程序:#include #define XNAME(n) x#n#define PXN(n) printf(x#n = %dn,x#n)int main(void)int XNAME(1)=12;/int x1=12;PXN(1);/printf(x1 = %dn, x1);return 0;输出结果:x1=12用在不带参数的宏中:#include #define X xx#9int main(void)int xx9;X = 10;printf(%dn, X);return 0;输出:103、可变参数宏 .和_VA_ARGS_VA_ARGS_ 是一个可变参数的宏,很少人知道这个宏

7、,这个可变参数的宏是新的 C99 规范中新增的,目前似乎只有 gcc 支持(VC6.0 的编译器不支持)。实现思想就是宏定义中参数列表的最后一个参数为省略号(也就是三个点)。这样预定义宏_VA_ARGS_就可以被用在替换部分中,替换省略号所代表的字符串。如:#define PR(.) printf(_VA_ARGS_)int main()int wt=1,sp=2;PR(hellon);PR(weight = %d, shipping = %d,wt,sp);return 0;输出结果:helloweight = 1, shipping = 2省略号只能代替最后面的宏参数。#define W(

8、x,.,y)错误!条件编译指令#if #ifdef #ifndef#elif #else#endif条件编译指令将决定那些代码被编译,而哪些是不被编译的。可以根据表达式的值或者某个特定的宏是否被定义来确定编译条件。#ifdef 宏名 只要这个宏定义了,而不管其值是否为 0,条件均为真#ifndef 宏名 #if 表达式表达式与 C 语言本身的表达式基本一至如逻辑运算、算术运算、位运算等均可以在预编译指令中使用。#if defined(宏) 或 #if defined 宏 与 #ifdef 宏#if !defined(宏) 或 #if !defined 宏 与 #ifndef 宏 一致#if 更

9、强大,如:#if defined(MAC1) & defined(MAC2)#if MAC1 = 1 均可以头文件包含指令采用头文件的目的主要是为了使某些定义可以供多个不同的 C 源程序使用。#include 预处理指令的作用是在指令处展开被包含的文件。包含可以是多重的,也就是说一个被包含的文件中还可以包含其他文件。标准 C 编译器至少支持八重嵌套包含。在程序中包含头文件有两种格式:#include #include my.h采用两种不同包含格式的理由在于,编译器是安装在公共子目录下的,而被编译的应用程序是在它们自己的私有子目录下的。一个应用程序既包含编译器提供的公共头文件,也包含自定义的私有

10、头文件。采用两种不同的包含格式使得编译器能够在很多头文件中区别出一组公共的头文件。特殊符号采用头文件的目的主要是为了使某些定义可以供多个不同的 C 源程序使用。#include 预处理指令的作用是在指令处展开被包含的文件。包含可以是多重的,也就是说一个被包含的文件中还可以包含其他文件。标准 C 编译器至少支持八重嵌套包含。在程序中包含头文件有两种格式:#include #include my.h采用两种不同包含格式的理由在于,编译器是安装在公共子目录下的,而被编译的应用程序是在它们自己的私有子目录下的。一个应用程序既包含编译器提供的公共头文件,也包含自定义的私有头文件。采用两种不同的包含格式使

11、得编译器能够在很多头文件中区别出一组公共的头文件。extern C 块extern C 块的应用#ifdef _cplusplusextern C #endif/* Assume C declarations for C+ */#ifdef _cplusplus #endif_cplusplus 是 C+的预定义宏,表示当前开发环境是 C+。在 C+语言中,为了支持重载机制,在编译生成的汇编代码中,会对函数名字进行进行一些处理(通常称为函数名字改编),如加入函数的参数类型或返回类型等,而在 C 语言中,只是简单的函数名字而已,并不加入其它信息:void show(int demo);void

12、show(double demo);C 无法区分上面两个函数的不同,因为 C 编译器产生的函数名都是 _show,而 C+编译器产生的名字则可能是 _show_Fi 和 _show_Fd,这样就很好地把函数区别开了。所以,在 C/C+混合编程的环境下, extern C 块的作用就是告诉 C+编译器这段代码要按 C 标准编译,以尽可能地保持 C+与 C 的兼容。再比如说用 C+开发了一个 DLL 库,为了能够让 C 语言也能够调用该 DLL输出(Export)的函数,需要用 extern C来强制编译器不要修改你的函数名。注释大段代码注释大段代码注释大段代码可以使用/*-*/,但不支持嵌套注释,有时容易出错。通常忽略大段代码的正确方法是使用条件编译指令,示例代码如下:#if 0.#endif

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 生活休闲 > 科普知识

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号