预编译
分类:C++
之前了解到防止文件重复包含但是没有细想是如何实现的,今天仔细思考了一下。
- #pragma once
这是用于Windows平台编译器的注记语句,具体实现跟编译器有关。在这里不做过多讨论,应该就是在编译器中实现了这样一种注记,在#pragma once语句之后的代码都会通过文件包含检验。具体用法比较简单,但是最大的问题就是不能跨平台使用。
- #ifndef
预编译头有很多用处,其实就是一种宏定义语句。
先介绍用来处理防止头文件包含时的方式(一般防止文件包含指的都是源文件在使用#include语句时会包含所对应的头文件,但是可能会出现几个源文件都会用到同一个头文件的情况,一般时在头文件中声明源文件中实现,如果不作处理编译器就会认为程序中同时存在两处或多出声明,则会报错。这还跟编译器有关,在C语言中,允许一个程序中有多出声明,但是C++则不允许,所以有的在C中能够编译的代码在C++中不一定能够编译。)
#ifndef __FILENAME_H__#define __FILENAME_H__#include <FILENAME.h>//programme;#endif
其中的 __FILENAME_H__ 是宏名,可以是任意值,不过一般由:文件名+H 来命名,表示此头文件。
具体原理就是在第一个编译的源文件中,读到#ifndef __FILENAME_H__ 表示如果没有定义此宏,则#define(定义此宏),再编译后面的代码。在第二个源文件中,如果之前已经有源文件包含FILENAME.h头文件则已经定义了__FILENAME_H__宏,则不会执行下面的语句,直接通过#endif结束,如果没有包含,则编译下面的语句。这样就实现了头文件的防止重复包含。
这其实是一种很好的设计模式,巧妙的利用了宏定义语句的特点(全局有效),利用这个特性,可以设计编译开关。
##ifdef DEBUG
#define _DEBUG(X)
printf("%s\n",X);
#else
#define _DEBUG(X)
#endif
这个用来控制调试版本(debug)和发行版本(release)很方便。
宏定义语句的作用还有很多,可能大家已经发现了,其实就可以像分支跳转语句一样使用,所以更多功能实现交给伟大的读者。
如果有收获,可以请我喝杯咖啡!