分享

宏定义VC

 喜欢站在山上 2022-03-16
(一)刚接触到MFC编程的人往往会被MFC 向导生成的各种宏定义和预处理指令所吓倒,但是预处理和宏定义又是C语言的一个强大工具。使用它们可以进行简单的源代码控制,版本控制,预警或者完成一些特殊的功能。但常用的并不多!
在VC.Net 普遍使用的预处理指令:
#pragma once
//只要在头文件的最开始加入这条指令就能够保证头文件被编译一次
//传统的解决办法是使用#ifdef 以及#endif 来避免头文件的重复编译
## 连接符与# 符
## 连接符号由两个井号组成,其功能是在带参数的宏定义中将两个子串(token)联接起来,从而形成一个新的子串。但它不可以是第一个或者最后一个子串。所谓的子串(token)就是指编译器能够识别的最小语法单元。具体的定义在编译原理里有详尽的解释,但不知道也无所谓。同时值得注意的是#符是把传递过来的参数当成字符串进行替代。

(二)预编译指令的用法

 预处理指令是以#号开头的代码行.。
下面是部分预处理指令:
        指令             用途
         #           空指令,无任何效果
         #include    包含一个源代码文件
         #define     定义宏
         #undef      取消已定义的宏
         #if         如果给定条件为真,则编译下面代码
         #ifdef      如果宏已经定义,则编译下面代码
         #ifndef     如果宏没有定义,则编译下面代码
         #elif       如果前面的#if给定条件不为真,当前条件为真,则编译下面代码
         #endif      结束一个#if……#else条件编译块
         #error      停止编译并显示错误信息
一、文件包含
    #include预处理指令的作用是在指令处展开被包含的文件。
二、宏
    宏定义了一个代表特定内容的标识符。预处理过程会把源代码中出现的宏标识符替换成宏定义时的值。
1).宏最常见的用法是定义代表某个值的全局符号。
2).宏的第二种用法是定义带参数的宏,这样的宏可以象函数一样被调用,但它是在调用语句处展开宏,并用调用时的实际参数来代替定义中的形式参数。
    1.#define指令
        #define预处理指令是用来定义宏的。
该指令最简单的格式是:首先神明一个标识符,然后给出这个标识符代表的代码。在后面的源代码中,就用这些代码来替代该标识符。这种宏把程序中要用到的一些全局值提取出来,赋给一些记忆标识符。     
        宏表示的值可以是一个常量表达式,其中允许包括前面已经定义的宏标识符。
        宏还可以代表一个字符串常量,例如:
            #define VERSION 'Version 1.0 Copyright(c) 2003'
    2.带参数的#define指令
        带参数的宏和函数调用看起来有些相似。
    3.#运算符
        出现在宏定义中的#运算符把跟在其后的参数转换成一个字符串。有时把这种用法的#称为字符串化运算符。
    4.##运算符
        ##运算符用于把参数连接到一起。预处理程序把出现在##两侧的参数合并成一个符号。   

三、条件编译指令
    条件编译指令将决定那些代码被编译,而哪些是不被编译的。可以根据表达式的值或者某个特定的宏是否被定义来确定编译条件。
    1.#if指令
        #if指令检测跟在制造另关键字后的常量表达式。如果表达式为真,则编译后面的代码,知道出现#else、#elif或#endif为止;否则就不编译。
    2.#endif指令
        #endif用于终止#if预处理指令。
    3.#ifdef和#ifndef     
    4.#else指令
        #else指令用于某个#if指令之后,当前面的#if指令的条件不为真时,就编译#else后面的代码。
    5.#elif指令
        #elif预处理指令综合了#else和#if指令的作用。
    6.其他一些标准指令
        #error指令将使编译器显示一条错误信息,然后停止编译。
        #line指令可以改变编译器用来指出警告和错误信息的文件号和行号。
        #pragma指令没有正式的定义。编译器可以自定义其用途。典型的用法是禁止或允许某些烦人的警告信息。
(三)#Pragma宏
(四)C语言头文件声明

在我们查看别人的源程序的时候,经常会看到别人的源码头文件中有一些比较奇怪的代码,这些代码使用来干什么的呢?比如下面这个例子:

  • 宏定义 __C_LOG_H__
      上述代码中的#ifndef __C_LOG_H__ 用来判断是否我们已经定义呢宏__C_LOG_H__, 如果没有定义则我们定义宏__C_LOG_H__,否则这个头文件在编译时候会变成一个空文件.由于有了这个宏判断,我们在以后的所有源代码中就可以重复的包含这个头文件,而不用担心头文件中的一些信息的重复定义. 
  • 宏定义 __cplusplus
      上述代码中的#ifdef __cplusplus 用来判断当前使用的编译器是C++编译器还是C编译器.如果使用C++编译器则会自动定义这个宏,否则不会定义.如果是C++编译器我们后面增加了 extern 'C' {以及后面的}用来表示我们的代码是C语言代码,这样通过C++编译器编译出来的函数库我们在C语言中也可以使用. 
  • 结构定义CLog
      上述代码中的typedef struct _CLog CLog可以用力隐藏结构CLog的内部情况.这样我们可以在源代码中指明CLog的结构成员.而在其它源代码中看不到这个结构的各个成员,起到对结构的隐藏作用

(五)VC注释宏的作用

“注释宏”是类似这样的宏:
//}}AFX_MSG_MAP
VC注释宏是给类向导用的,若要使用类向导添加成员变量和成员函数,则要保留注释宏;否则,必须手动添加。
是用于vc编辑器自动生成代码定位用的如果你把它删了相应的classwizad就不能自动生成代码了 。
你添加消息响应的时候是不是发现源代码里多了些代码?那些代码为什么会在那里出现为什么不在别的文件里出现就是因为那里有注释宏它要将代码生成在相应注释宏之间 。
这个注释是让ClassWizard能够分辨出哪些代码是它生成的,哪些是你自己写的。你自己写的代码要在这个注释之外,这样ClassWizard再修改消息映射的时候就不会管你的代码了。
限于以前的硬件速度,ClassWizard比较傻冒,所以需要这些注释宏来定位。从7.0(Visua Studio 2003)l开始,就不再需要了。新的属性页能够自动分析你的代码,为你添加或者删除代码,而无需什么特殊标记的帮忙。因此注释宏已经是历史产物了。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多