预编译(c++常问问题十二)

预编译指令指示了在程序正式编译前就由编译器进行的操作,可以放在程序中的任何位置。常见的预编译指令有:

(1)#include 指令

该指令指示编译器将xxx.xxx文件的全部内容插入此处。若用<>括起文件则在系统的INCLUDE目录中寻找文件,若用" "括起文件则在当前目录中寻找文件。一般来说,该文件是后缀名为"h"或"cpp"的头文件。

注意:<>不会在当前目录下搜索头文件,如果我们不用<>而用""把头文件名扩起,其意义为在先在当前目录下搜索头文件,再在系统默认目录下搜索。

(2)#define指令

该指令有三种用法:

第一种是定义标识,标识有效范围为整个程序,形如#define XXX,常与#if配合使用;

第二种是定义常数,如#define max 100,则max代表100(这种情况下使用const定义常数更好,原因见注1);

第三种是定义"函数",如#define get_max(a, b) ((a)>(b)?(a):(b)) 则以后使用get_max(x,y)就可以得到x和y中较大的数(这种方法存在一些弊病,见注2)。

第四种是定义"宏函数",如#define GEN_FUN(type) type max_##type(type a,type b){return a>b?a:b;} ,使用时,用GEN_FUN(int),则此处预编译后就变成了 max_int(int a,int b){return a>b?a:b;},以后就可以使用max_int(x,y)就可以得到x和y中较大的数.比第三种,增加了类型的说明。

(3)#if、#else和#endif指令

这些指令一般这样配合使用:

#if defined(标识) //如果定义了标识

要执行的指令

#else

要执行的指令

#endif

在头文件中为了避免重复调用(比如说两个头文件互相包含对方),常采用这样的结构:

#if !(defined XXX) //XXX为一个在你的程序中唯一的标示符,

//每个头文件的标识符都不应相同。

//起标识符的常见方法是若头文件名为"abc.h"

//则标识为"abc_h"

#define XXX

真正的内容,如函数声明之类

#endif

注1:因为:const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查,而对后者只进行字符替换,没有类型安全检查,并且在字符替换时可能会产生意料不到的错误(边际效应)。

注2:例如get_max(a++, b)时,a++会被执行多少次取决于a和b的大小!所以建议还是用内联函数而不是这种方法提高速度。虽然有这样的弊病,但这种方法的确非常灵活,因为a和b可以是各种数据类型。

时间: 2024-12-21 13:16:07

预编译(c++常问问题十二)的相关文章

移动构造函数(c++常问问题十六)

今天我们来讲讲c++11中引入了两个新东西 1.move constructor(移动构造函数) 2.move assignment(移动赋值) Rule of three现在变成了Rule of five(多了上面说的两个东东) class rule_of_five { char* cstring; // raw pointer used as a handle to a dynamically-allocated memory block public: rule_of_five(const

C语言的傻瓜式随笔(二):全局变量、预编译、goto

函数的作用:可以实现代码的重用. 函数只需要定义1次,那么函数中的代码就可以随意的调用.       -某不知出处的基本概念 学而时习之,如有误笔,请指正 一.goto跳转语句 goto在C语言的作用: 可以将CPU的执行跳转到当前函数的别的地方继续执行.因为会产生代码回朔,所以极易产生死循环. 注意: 1). 标签名随意,但是要符合标识符的命名规则及规范. 标识符: 那就是程序员可以自己给名字的东西 统称为标识符. 变量名.标签名.函数名. 2). goto可以往前跳 也可以往后跳. 3).

JavaScript作用域原理(二)——预编译

JavaScript是一种脚本语言, 它的执行过程, 是一种翻译执行的过程.并且JavaScript是有预编译过程的,在执行每一段脚本代码之前, 都会首先处理var关键字和function定义式(函数定义式和函数表达式). 一.变量执行之前,会被赋为undefined <p id="scope2" style="color:red"></p> function echo(p, html) { p.innerHTML += html + '&l

JS执行顺序(二)预编译

预编译当js引擎解析的时候,它会在预编译对所有声明的变量和函数进行处理. 变量提升 console.log(a); // undefinedvar a = 1;console.log(a); // 1预解析函数 f(); // 1function f() { console.log(1);};详细:javascript变量声明提升(hoisting) 分块执行代码js是按块执行代码的,所谓代码块就是使用<script>标签分隔的代码段.(下面一个栗子) <script> // 代码

.NET MVC Razor模板预编译(二)

在前面一片文章:<.NET MVC4 Razor视图预编译(一)> 里面我采用的是PrecompiledMvcViewEngineContrib组件进行预编译视图的虚拟地址注册,但是这个组件还是存在少许的bug,如:页面单独定义Layout预编译后不会起作用,而且照旧会使用没有预编译的_ViewStart.cshtml里面定义的Layout 昨天在NPOI作者Tony的群(群号:78142590)里面经过大神老衣的指点,原来是我引用的第三方类库错了,应该引用:RazorGenerator.Mv

C预编译, 预处理, C/C++头文件, 编译控制,

在所有的预处理指令中,#Pragma 指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作.#pragma指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的情况下,给出主机或操作系统专有的特征.依据定义,编译指示是机器或操作系统专有的,且对于每个编译器都是不同的. 其格式一般为: #Pragma Para 其中Para 为参数,下面来看一些常用的参数. (1)message 参数. Message 参数是我最喜欢的一个参数,它能够在编译信息输出窗口中输

常问易混淆知识点(嵌入式)

b 一.知识点1 a) 关键字volatile在编译时有什么含义?并给出三个不同使用场景的例子(可以伪代码或者文字描述).b) C语言中static关键字的具体作用有哪些 ?c) 请问下面三种变量声明有何区别?请给出具体含义int const *p;int* const p;int const* const p; a) 用volatile关键字定义变量,相当于告诉编译器,这个变量的值会随时发生变化,每次使用时都需要去内存里 重新读取它的值,并不要随意针对它作优化. 建议使用volatile变量的

iOS中的预编译指令的初步探究

看到非常好的两篇技术文,转来方便自己查看. 转自:http://www.cnblogs.com/daiweilai/p/4234336.html 开篇 我们人类创造东西的时候有个词叫做”仿生学“!人类创造什么东西都会模仿自己来创造,所以上帝没有长成树的样子而和人长得一样,科幻片里面外星人也像人一样有眼睛有鼻子……但是人类自己创造的东西如果太像自己,自己又会吓尿(恐怖谷效应),人类真是奇葩:奇葩的我们在20世纪创造了改变世界的东西——计算机(电脑),不用怀疑,这货当然也是仿生学!这货哪里长得像人了

第三十二章

道恒无名,朴虽小,而天下弗敢臣.侯王若能守之,万物将自宾.天地相合,以俞甘露,民莫之令而自均焉.始制有名,名亦既有,夫亦将知止,知止所以不殆.譬道之在天下也,犹小谷之与江海也. 第三十二章1 如何让大家都来顺服你? 各位朋友大家好,今天我们接着来聊<道德经>.今天我们不唱歌了,昨天放了一首我唱的歌,这唱歌在我这儿就是一个养生运动.因为唱歌的时候你要调呼吸,这时候是锻炼肺.我之前写过两篇文章,专门讲唱歌的,我们家有一位邻居.一位朋友,这肺间质性病变,很严重的肺病,结果人家天天唱歌,现在恢复的特别