preprocessor-宏
来源:互联网 发布:gogoing知乎 编辑:程序博客网 时间:2024/06/07 09:47
为了让计算机能够识别并运行程序,所有的源代码必须转变为能够被计算机识别的机器码,转换的过程(以C语言为例)大致可以分为预处理-->编译-->汇编-->链接四个步骤。
预处理指令是指程序中以#开始的语句,主要包括以下四种类型:
(1) 宏定义指令.(#define,#undef # ##)。
#define主要进行代码替换。#undef用于取消某个宏的定义。操作符#适用的格式:
#define macro_function(x,y,z,...) #x#y#z....
操作符#宏函数的参数列表替换到替换列表中。
规则:
1. 参数的首或尾含有一个或者多个空白字符,那么空白字符将会被删除,参数中间的大于一个连续的空白字符会保留一个空白字符。
2. 如果参数中含有字符串文本,并且字符串中含有反斜杠\,当宏展开时,会在反斜杠'\'的前面添加一个反斜杠\。(注意转义字符)
3. 如果参数中含有双引号'',当宏展开时,会在双引号的前面添加一个反斜杠\。(注意转义字符)
4. 如果在替换列表中有多个##操作符或者#操作符,操作符处理的顺序不确定。
(原文: if more than one ##operator or # operator appears in the replacement list of a macro definition, the order of evaluation of operators is not defined.)
5. 如果宏展开的结果并不是一个有效的字符串文本,造成的结果也不确定。
( 原文: if the result of the macro expansion is not valid character string literal, the behavior is undefined.)
操作符##:
规则:
1.操作符##不能出现在替换列表中的首或者尾。
2. 操作符##的作用是将两个token 连接成一个token,这里的token 并不一定是宏函数的参数,文本也行,例如,
#define xy(x,y) x##y
连接的顺序从左到右,即是将x连接到y;x##y 和x ## y是等价的。原因是,##的作用是先进行分割,可以详见http://kenshinf.blog.51cto.com/1088256/252541
3. 连接发生在宏展开之前,也就是说如果x,y 中有一个或者两个是宏,那么先将xy连接发生在其展开之前,如果连接之后还是一个有效的宏名称,那么还可以进一步展开。
4. 如果替换列表中含有多于一个##操作符或者#操作符,操作符处理的顺序不确定。
(2) 条件编译指令(conditional inclusions).(#ifdef,#ifndef,#if,#endif,#else 和 #elif)
这些指令告诉预处理器在某一个条件下包含或者摒弃部分代码。(3)#行号控制(line control).(#line).
为了方便编译器能够准确直观的将编译错误信息显示给用户,预处理器通常会在适当的地方插入该指令。该指令会影响__LINE__的值。代码片段:
/** ** This example illustrates #line directives. **/#include <stdio.h>#define LINE200 200//#line 100void func_1(){ printf("Func_1 - the current line number is %d\n",__LINE__);}//#line LINE200void func_2(){ printf("Func_2 - the current line number is %d\n",__LINE__);}int main(void){ func_1(); func_2(); while(1) { }}
执行结果:
Func_1 - the current line number is 10
Func_2 - the current line number is 16
取消对#line的注释时,执行结果为:
Func_1 - the current line number is 102
Func_2 - the current line number is 202
(4)错误处理指令(#error).该指令能够使得预处理器在预处理阶段产生错误消息,从而导致编译错误.该指令通常与条件编译指令一起使用,在预编译阶段进行检查。
eg.#define BUFFER_SIZE 255#if BUFFER_SIZE < 256#error "BUFFER_SIZE is too small."#endif
编译输出结果:
test.cpp:103:2: error: #error "BUFFER_SIZE is too small."
(5)警告指令(#warn).与#error用法基本一致,预编译阶段产生报警。
将上述代码"#error "BUFFER_SIZE is too small""中的#error改为#warning,则编译结果为:test.cpp:103:2: error: #warning "BUFFER_SIZE is too small."
(6) 文件包含指令(file inclusion directives).
#include "xxxx" 表示xxx为用户自定义文件#include <xxxx> 表示xxx为系统定义魏建.
(7) #pargma.用于设定编译器的状态或者指示编译器完成一些特定的动作.常用语法:#pragma para.该指令较复杂,本文不对此做详细介绍.
- preprocessor-宏
- 宏(preprocessor)系列 chips
- Xcode定义Preprocessor Macros,编译宏。
- Xcode定义Preprocessor Macros,编译宏。
- Objective-C 预处理器(The Preprocessor) 宏
- PReprocessor Macros : 全局宏命令的应用
- Xcode定义Preprocessor Macros编译宏
- iOS 利用Preprocessor Macros预定义宏Debug
- iOS用全局宏的概念 preprocessor macros
- Preprocessor Directives
- C preprocessor
- C preprocessor
- C preprocessor
- The preprocessor
- Preprocessor directives:预处理指令,宏定义,行控制,条件包含,错误提示,源文件包含,Pragma
- iOS用全局宏的概念理解xcode中的设置 preprocessor macros
- Predefined Shader preprocessor macros //预定义的着色器预处理宏
- boost::preprocessor库简介
- QMetaObject::connectSlotsByName: No matching signal for问题的解决方法
- 判断是否是日期格式YYYYMM
- Mac OS 下的 Django,pip,virtualenv 和 homebrew 环境的搭建
- SQL Union和SQL Union All用法
- 【你有成功特质吗?】
- preprocessor-宏
- poj 1149 Pigs 网络流-最大流 建图的题目(明天更新)-已更新
- c语言结构体
- java垃圾回收机制
- HDU1711-----Number Sequence-----裸的KMP
- PythonChallenge 挑战之路 Level-25
- ViewController的生命周期分析和使用
- 写一个HTML页面,实现以下功能,左键点击页面时显示“您好”,右键点击 时显示“禁止右键”。并在2分钟后自动关闭页面。
- Qt for Embedded Linux (嵌入式linuxQT)