“#”预处理
2013-09-18 14:53
148 查看
预处理功能主要包括宏定义,文件包含,条件编译三部分。分别对应宏定义命令,文件包含命令,条件编译命令三部分实现。
预处理过程读入源代码,检查包含预处理指令的语句和宏定义,并对源代码进行响应的转换。预处理过程还会删除程序中的注释和多余的空白字符。
预处理指令是以#号开头的代码行。#号必须是该行除了任何空白字符外的第一个字符。#后是指令关键字,在关键字和#号之间允许存在任意个数的空白字符。整行语句构成了一条预处理指令,该指令将在编译器进行编译之前对源代码做某些转换。
指令 用途
# 空指令,无任何效果
#include 包含一个源代码文件
#define 定义宏
#undef 取消已定义的宏
#if 如果给定条件为真,则编译下面代码
#ifdef 如果宏已经定义,则编译下面代码
#ifndef 如果宏没有定义,则编译下面代码
#elif 如果前面的#if给定条件不为真,当前条件为真,则编译下面代码
#endif 结束一个#if……#else条件编译块
#error 停止编译并显示错误信息
#else 如果前面的#if给定条件不为真,则编译下面代码
#error 指令将使编译器显示一条错误信息,然后停止编译
#line 指令可以改变编译器用来指出警告和错误信息的文件号和行号
#pragma 指令没有正式的定义。编译器可以自定义其用途。典型的用法是禁止或允许某些烦人的警告信息
文件包含
包含指令不仅仅限于.h头文件,可以包含任何编译器能识别的C/C++代码文件,包括.c、.hpp、.cpp、.hxx、.cxx等,甚至.txt、.abc等等都可以。
预处理器发现 #include 指令后,就会寻找指令后面<>中的文件名并把这个文件的内容包含到当前文件中。被包含文件中的文本将替换源代码文件中的#include指令, 就像你把被包含文件中的全部内容键入到源文件中的这个位置一样。
宏
#define只作用在当前文件本身的全局范围。
条件编译
条件编译指令将决定哪些代码被编译,而哪些是不被编译的。可以根据表达式的值或者某个特定的宏是否被定义来确定编译条件。
1.#if、#else、#elif和#endif指令
#if
表达式1
语句段1
#elif
表达式2
语句段2
#else
语句段3
#endif
2.#ifdef、#ifndef和#endif指令
#ifdef 宏名
语句段
#endif
#ifndef 宏名
语句段
#endif
例子:
文件包含
#include "file.h"
#include "file.h"
效果等效于如下图所示:(文本替换)
条件编译
只编译一次,灰色部分表示不被编译
宏的作用域是当前文件,test.cpp file1.cpp #include "file.h"
在#ifndef中定义变量,可能出现的问题:
#ifndef _FILE_H
#define _FILE_H
int iTest;
};
#endif
在vc中链接时就出现了iTest重复定义的错误,而在c中成功编译。
结论:
(1)、当你第一个使用file.h的.cpp文件生成.obj的时候,int i 在里面定义了。当另外一个使用file.h的.cpp文件再次[单独]生成.obj的时候,int i 又被定义。连接在一起时,就会出现重复定义.
(2)、把源程序文件扩展名改成.c后,按照C语言的语法对源程序进行编译,而不是C++。在C语言中,若是遇到多个int i,则自动认为其中一个是定义,其他的是声明。
(3)、C语言和C++语言连接结果不同,可能(猜测)是在进行编译的时候,C++语言将全局变量默认为强符号,所以连接出错。C语言则依照是否初始化进行强弱的判断的。(猜测)
解决方法:
(1)、把源程序文件扩展名改成.c。
(2)、推荐解决方案: .h中只声明 extern int i; 变量一般不要定义在.h文件中。
预处理过程读入源代码,检查包含预处理指令的语句和宏定义,并对源代码进行响应的转换。预处理过程还会删除程序中的注释和多余的空白字符。
预处理指令是以#号开头的代码行。#号必须是该行除了任何空白字符外的第一个字符。#后是指令关键字,在关键字和#号之间允许存在任意个数的空白字符。整行语句构成了一条预处理指令,该指令将在编译器进行编译之前对源代码做某些转换。
指令 用途
# 空指令,无任何效果
#include 包含一个源代码文件
#define 定义宏
#undef 取消已定义的宏
#if 如果给定条件为真,则编译下面代码
#ifdef 如果宏已经定义,则编译下面代码
#ifndef 如果宏没有定义,则编译下面代码
#elif 如果前面的#if给定条件不为真,当前条件为真,则编译下面代码
#endif 结束一个#if……#else条件编译块
#error 停止编译并显示错误信息
#else 如果前面的#if给定条件不为真,则编译下面代码
#error 指令将使编译器显示一条错误信息,然后停止编译
#line 指令可以改变编译器用来指出警告和错误信息的文件号和行号
#pragma 指令没有正式的定义。编译器可以自定义其用途。典型的用法是禁止或允许某些烦人的警告信息
文件包含
包含指令不仅仅限于.h头文件,可以包含任何编译器能识别的C/C++代码文件,包括.c、.hpp、.cpp、.hxx、.cxx等,甚至.txt、.abc等等都可以。
预处理器发现 #include 指令后,就会寻找指令后面<>中的文件名并把这个文件的内容包含到当前文件中。被包含文件中的文本将替换源代码文件中的#include指令, 就像你把被包含文件中的全部内容键入到源文件中的这个位置一样。
宏
#define只作用在当前文件本身的全局范围。
条件编译
条件编译指令将决定哪些代码被编译,而哪些是不被编译的。可以根据表达式的值或者某个特定的宏是否被定义来确定编译条件。
1.#if、#else、#elif和#endif指令
#if
表达式1
语句段1
#elif
表达式2
语句段2
#else
语句段3
#endif
2.#ifdef、#ifndef和#endif指令
#ifdef 宏名
语句段
#endif
#ifndef 宏名
语句段
#endif
例子:
文件包含
#include "file.h"
#include "file.h"
效果等效于如下图所示:(文本替换)
条件编译
只编译一次,灰色部分表示不被编译
宏的作用域是当前文件,test.cpp file1.cpp #include "file.h"
在#ifndef中定义变量,可能出现的问题:
#ifndef _FILE_H
#define _FILE_H
int iTest;
};
#endif
在vc中链接时就出现了iTest重复定义的错误,而在c中成功编译。
结论:
(1)、当你第一个使用file.h的.cpp文件生成.obj的时候,int i 在里面定义了。当另外一个使用file.h的.cpp文件再次[单独]生成.obj的时候,int i 又被定义。连接在一起时,就会出现重复定义.
(2)、把源程序文件扩展名改成.c后,按照C语言的语法对源程序进行编译,而不是C++。在C语言中,若是遇到多个int i,则自动认为其中一个是定义,其他的是声明。
(3)、C语言和C++语言连接结果不同,可能(猜测)是在进行编译的时候,C++语言将全局变量默认为强符号,所以连接出错。C语言则依照是否初始化进行强弱的判断的。(猜测)
解决方法:
(1)、把源程序文件扩展名改成.c。
(2)、推荐解决方案: .h中只声明 extern int i; 变量一般不要定义在.h文件中。
相关文章推荐
- 数据预处理——One-hot编码
- 浅谈c语言预处理知识
- 【C语言】熟悉预处理标识符和宏
- VPX板卡 基于XC7K325T的3U VPX FMC接口数据收发预处理平台
- 数据预处理(python,R matlab 对同一个数据转换)
- php_pdo 预处理语句详解
- C语言预处理命令总结大全
- PDO:什么是预处理?
- WebRTC音频预处理单元APM的整体编译及使用
- C++ 预处理命令
- 1.预处理,生成预编译文件(.文件): Gcc –E hello.c –o hello.i 2.编译,生成汇编代码(.s文件): Gcc –S hello.i –o hello.s 3.汇编,生成目标文件(.o文件): Gcc –c hello.s –o hello.o 4.链接,生成可执行文件: linux笔记
- (Python实现)数据PCA降维白化和L2归一化-深度学习实践常用数据预处理
- Spring中BeanPostProcessors【1】简单预处理
- C++拓展笔记1-2:浅谈C++编程中可能会用到的预处理指令
- Codeforces Round #394 (Div. 2) C. Dasha and Password 贪心+预处理+枚举
- 预处理编译汇编链接各步骤详解
- 跟着百度学PHP[14]-PDO的预处理语句1
- java通过匹配合并数据(数据预处理)
- 数据分析之数据预处理
- 数据预处理:独热编码(One-Hot Encoding)