2022年VC预处理指令和宏定义 .pdf
《2022年VC预处理指令和宏定义 .pdf》由会员分享,可在线阅读,更多相关《2022年VC预处理指令和宏定义 .pdf(10页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、刚接触到MFC 编程的人往往会被MFC 向导生成的各种宏定义和预处理指令所吓倒,但是预处理和宏定义又是C 语言的一个强大工具。使用它们可以进行简单的源代码控制,版本控制,预警或者完成一些特殊的功能。一个经典的例子使用预处理与宏定义最经典的例子莫过于加在一个头文件中以避免头文件被两次编译。试想这种的情况,有一个文件headerfile.h 它被包含在 headerfile1.h 中,同时在 headerfile2.h 中也被包含了,现在有一个CPP文件, implement.cpp 包含了 headerfile1.h 和 headerfile2.h:#include “ headerfile1.
2、h”#include “ headerfile2.h”假设 headerfile.h 中定义了一个全局变量iglobal 。int iglobal; 在编译的时候编译器两次编译headerfile,也就会发现 iglobal 被定义了两次, 这时就会发生变量重定义的编译错误。传统的解决办法是使用#ifdef 以及#endif 来避免头文件的重复编译,在上面的例子中,只需要加上这么几行:#ifndef smartnose_2002_6_21_headerfile_h #define smartnose_2002_6_21_headerfile_h int iglobal; 名师资料总结 - -
3、-精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 10 页 - - - - - - - - - #endif仔细的考虑上面的宏定义,会发现当编译器编译过一次headerfile.h以后, smartnose_2002_6_21_headerfile_h 这个宏就被定义了, 以后对 headerfile.h的编译都会跳过 int iglobal 这一行。当然 smartnose_2002_6_21_headerfile_h 这个宏是可以任意定义的,但是这个宏本身不能和其它文件中定义的宏重复,所以
4、MFC 在自动生成的文件中总是使用一个随机产生的长度非常长的宏,但我觉得这没有必要,我建议在这个宏中加入一些有意义的信息,比方作者,文件名,文件创建时间等等,因为我们有时候会忘记在注释中加入这些信息。在 VC.net 中我们不会再看见这些宏定义了, 因为在这里会普遍使用一个预处理指令:#pragma once只要在头文件的最开始加入这条指令就能够保证头文件被编译一次,这条指令实际上在 VC6 中就已经有了,但是考虑到兼容性并没有太多的使用它。源代码版本控制当我们为许多平台开发多个版本的时候预编译指令和宏定义也能够帮我们的忙。假设我们现在为Windows 和 Linux 开发了一套软件,由于这两
5、种系统的不同,我们不得不在程序控制源代码的版本。比方内存的分配,我们可以在 LINUX 上使用标准 C 的 malloc 函数,但是我们希望在Windows 上使用 HeapAlloc API。下面的代码演示了这种情况:名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 10 页 - - - - - - - - - main() .#ifdef _WINDOWS_PLATFORM HeapAlloc(5); #else malloc(5); #endif .当我们在 WIND
6、OWS 平台上编译此程序的时候, 只需要定义 _WINDOWS_PLATFORM 这个宏,那么 HeapAlloc 这条语句就能够起作用了。这样就能够让我们在同一个文件中为不同的平台实现不同版本的代码,同时保持程序的良好结构。在许多情况下,我们还可以为一个方法使用不同的算法,然后用宏定义来针对不同的情况选择其中的一个进行编译。 这在 MFC 应用程序中是使用得最多的。最明显的就是文件中经常存在的#ifdef _DEBUG .some code .#endif这样的代码,这些代码在应用程序的调试版(DEBUG)中会发挥其作用。#Pragma 指令在所有的预处理指令中,#Pragma 指令可能是最
7、复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作。其格式一般为名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 10 页 - - - - - - - - - #Pragma Para 其中 Para 为参数,下面来看一些常用的参数。message 参数。 Message 参数是我最喜欢的一个参数,它能够在编译信息输出窗口中输出相应的信息,这对于源代码信息的控制是非常重要的。其使用方法为:#Pragma message( “消息文本 ”)当编译器遇到这条
8、指令时就在编译输出窗口中将消息文本打印出来。当我们在程序中定义了许多宏来控制源代码版本的时候,我们自己有可能都会忘记有没有正确的设置这些宏, 此时我们可以用这条指令在编译的时候就进行检查。假设我们希望判断自己有没有在源代码的什么地方定义了_X86 这个宏可以用下面的方法#ifdef _X86 #Pragma message(“ _X86 macro activated!”)#endif当我们定义了 _X86 这个宏以后, 应用程序在编译时就会在编译输出窗口里显示“_X86 macro activated!”。我们就不会因为不记得自己定义的一些特定的宏而抓耳挠腮了。另一个使用得比较多的pragm
9、a参数是 code_seg 。格式如:名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 10 页 - - - - - - - - - #pragma code_seg( section-name,section-class )它能够设置程序中函数代码存放的代码段,当我们开发驱动程序的时候就会使用到它。最后一个比较常用的就是上面所说的#pragma once 指令了。VC 预定义的宏在 VC 中有一类宏并不是由用户用#define 语句定义的,而是编译器本身就能够识别它们。
10、这些宏的作用也是相当大的。让我们来看第一个, 也是 MFC 中使用得最频繁的一个 :_FILE_ 。当编译器遇到这个宏时就把它展开成当前被编译文件的文件名。好了,我们马上就可以想到可以用它来做什么,当应用程序发生错误时,我们可以报告这个错误发生的程序代码在哪个文件里,比方在文件test.cpp中有这样的代码:try char * p=new(char10); catch(CException *e ) TRACE(“ there is an error in file: %sn” ,_FILE_);在程序运行的时候,如果内存分配出现了错误,那么在调试窗口中会出现thereis an error
11、 in file: test.cpp 这句话,当然,我们还可以把这个错误信息显示在别的名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 10 页 - - - - - - - - - 地方。如果我们还能够记录错误发生在哪一行就好了,幸运的是,与_FILE_宏定义一样,还有一个宏记录了当前代码所在的行数,这个宏是_LINE_ 。使用上面的两个宏,我们可以写出一个类似于VC 提供的 ASSERT 语句。下面是方法#define MyAssert(x) if(!(x) Messag
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 2022年VC预处理指令和宏定义 2022 VC 预处理 指令 定义
限制150内