预处理的那点事儿
来源:互联网 发布:淘宝网药假吗 编辑:程序博客网 时间:2024/05/16 12:14
编译一个C程序的第一个步骤就是对它进行预处理,在平常学习的时候,很多人认为预处理就是include和define两种。其实在预处理里,这两个只能算是常用的,下面将把ANSI标准定义的C语言预处理指令为大家罗列出来。
除了上面所说的外,还有以下的宏:
_ LINE_:表示正在编译的文件的行号;
_ FILE_:表示正在编译的文件的名字;
_ DATE_:表示编译时刻的日期字符串;
_ TIME_:表示编译时刻的时间字符串;
_ STDC_:判断该文件是不是定义标准C程序;
1.宏定义
<1>数值宏定义
在平时写代码的时候,我们经常会定义一些数值,例如PI的值为3.14,但在后续应用中可能需要提高精度,此时需要将所有在代码中出现的PI都改掉,这样的工作量非常大。一般来说,我们会在代码的最前端写上:#define PI 3.14 这样子在需要用3.14的时候都写得是PI,需要改动的时候只需要改动这个宏定义。
注意:编译器在编译的时候,会将代码中所有的PI都换成我们定义的具体数值。
<2>表达式宏定义
当然,除了可以宏可以定义数值,表达式这种也是可以的。
例如:表示一年有多少秒 #define SUM 60* 60* 24* 365
那么如果定义的是一个宏函数呢?
比如求一个数x的平方。就可以写成:#define SUM(x) x*x
当x=10 ,编译的时候就是10 * 10。可当表达式比较复杂,我们写出的可能是(10+x) *(10+x),我们想表达的是(10+x)这个数的平方,可编译器执行时,它会这样理解:10+x *10+x ,这个就和我们期望的有点差距了,所以当我们要用宏去定义函数表达式之类的时候,一定要注意表达式的优先级!
<3>.#undef
#undef是用来取消宏定义的,用法如下:
#define PI 3.1415925
……
#undef
在#undef后的PI,值就不在是3.1415925了。
2.条件编译
在预处理里很重要的一类就是条件编译,条件编译的意思就是说在某种情况下,我们需要执行第一段程序,当在另一种情况下时,需要执行另一段。最常见的应该是我们用的一些软件包,当操作位数是32位时,是怎样,换成64位又怎样。下面就说条件编译的三种形式:
<1>
#ifdef 标识符
…A…
#else
…B…
#endif
如果标识符已被#define定义,则对A进行编译,否则对B进行编译。如果没有else,可直接省略这段。变成:
#ifdef 标识符
…A…
#endif
<2>
#ifndef 标识符
…A…
#else
…B…
#endif
如果标识符没有被#define定义,则对A进行编译,否则对B进行编译。
<3>
#if 常量表达式
…A…
#else
…B…
#endif
如果常量表达式为真,则对A进行编译,否则对B进行编译。所以这种形式可以让程序在不同的条件下完成不同的功能。
3.文件包含
文件包含是预处理的一个重要功能,它可以把多个源文件进行编译,生成一个目标文件。每次在我们写代码的时候,首先会引用头文件,这就是一个最常见的文件包含。
#include<文件名>和#include”文件名”到底有什么差异?
用尖括号括起来的表示预处理需要带系统规定的路径下去获得这个文件。
双引号表示预处理先去当前路径下去查找这个文件,如果查找不到再去查找系统指定的路径信息。
4.#pragma
关于pragma的用法我们用的最多的是:#pragma once
#pragma once
只要在头文件中最开始接入这条指令就可以避免头文件被多次编译。
5.函数与宏的不同之处
之前在前面说了如何定义一个宏函数,很多人就宏和函数傻傻分不清楚了。接下来,用一个表格展现一下:
6.预处理
当一个程序写好后,第一步是进行预处理。预处理的目的是:宏定义的具体化;去掉注释;展开头文件;条件编译。预处理完成生成的是“.i”文件,当这一步进行完后,开始进行编译。编译主要是将C语言转换成汇编语言,当这个工作完成后,生成“.s”文件。接下里进行的是汇编阶段,这个阶段的主要工作是将汇编语言变成二进制,生成“.o”文件。最后进入链接阶段,完成“合并段表”和“符号表的合并及符号的重定义”。每个阶段都有自己的任务,共同配合完成整个预处理的过程。
- 预处理的那点事儿
- VSS的那点事儿
- 就业的那点事儿
- 程序员的那点事儿
- Copy的那点事儿~
- String 的那点事儿
- RecyclerView的那点事儿
- CardView的那点事儿
- SurfaceView的那点事儿
- OC 的那点事儿
- C 的那点事儿
- 工作的那点事儿
- 加班的那点事儿
- .cn域名的那点事儿
- 关于Contacts的那点事儿
- 关于Contacts的那点事儿(续)
- Switch和Enum的那点事儿
- Objective-C: delegate的那点事儿
- Android软键盘调用及隐藏
- MyEclipse/Eclipse右键New菜单项的自定义设置
- Android软Watchdog源码分析
- hdu2571 动态规划
- 【bailian 1062】昂(mai)贵(nv)的(de)聘(fu)礼(qin)
- 预处理的那点事儿
- ssh框架的面试归纳(一)
- HTML5快速上手之10:与表格有关的基本指令
- JS手风琴插件
- JSTL学习小结——setLocale中的value值汇总
- Codeforce 724C. Ray Tracing By Assassin
- 刨根问底U3D---从Profile中窥探Unity的内存管理
- SVG 动画详解
- PowerDesigner使用教程