宏的妙用

2016-01-29 12:23 8 1 收藏

宏的妙用,宏的妙用

【 tulaoshi.com - C语言心得技巧 】

宏的妙用


作者 阿荣

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com)


1、概述
C++中出了const关键字以后,宏定义常量的功能已经不在被推荐使用。这使得宏似乎没有了用武之地。实际上,宏还可以做很多事情,笔者也难以全部列举。这里,仅仅列举几个典型的用法,希望大家能够从中获益。

2、实现多环境兼容
常见的情况是,我们实现了一个函数,希望它只在某种编译条件满足是被编译和使用。例如,我希望在源码中插入调试语句,以便以Debug方式运行时能够通过调试信息观察程序运行情况。但是,在产品发售给用户时,我又希望这些调试信息不要输出,以降低代码尺寸,提高运行性能。这一问题的解决方法就是使用宏。根据条件编译指令,对于不同的编译条件,提供不同的实现。例如:我们希望在特定的位置向日志中写入当前行号和文件名,以判断对应代码是否被执行到,可以使用下面的宏:

        #ifdef _DEBUG        #define TRACE_FILE_LINE_INFO() do{            CString str;            str.Format(_T("file=%s,line=%urn",__FILE__,__LINE__);            CFile file("logfile.txt");            file.Write(str,str.GetLength());       }while(0)       #else       #define TRACE_FILE_LINE_INFO()        #endif
上面这段代码通过#ifdef #else #endif三个条件编译指令,根据_DEBUG定义情况(该宏用于区分DEBUG版本和Release版本),决定了具体的TRACE_FILE_LINE_INFO宏函数的实现。使用者可以用如下方法使用
    TRACE_FILE_LINE_INFO();//这里显示行号和文本信息
当然,采用其他方式也可以实现这一功能,但是使用宏有以下特殊好处: 只有需要的代码才会被编译,减少了符号表的尺寸,也减少了代码尺寸 宏在编译时被展开,因此用于表示代码位置的__FILE__,__LINE__宏可以起作用,如果用函数实现,这两个宏则不能起作用。

3、用新函数替换原有函数
对于一个设计好的函数,假设它已经在一个很大的工程中到处使用,突然发现它的一个不足,想修改它的功能。也许这个新增加的功能需要一个额外的参数,但是又不想修改使用这些函数的地方。假设有两个函数必须成对使用,一个占用资源并使用,另外一个则释放资源以供其他模块使用。典型的例子是,函数一(假设为Lock)获得一个全局的锁,这个锁用于保护在多线程情况下多个线程对一个公共资源如一个全局变量的访问。问题是,这个Lock函数获得锁以后,其他线程将不能再获得这个锁,直到当前线程释放这个锁。编制Lock函数的程序员同时提供了一个 Unlock函数用于释放锁,并要求使用Lock的人必须对应的使用Unlock。调试程序时,发现线程被死锁,怀疑有人使用完Lock后忘记调用 Unlock,但是Lock和Unlock在这个大工程中都被广泛的使用,因此设计者希望Lock和Unlock都增加两个额外的参数file和line,以说明这两个函数在哪里被调用了,哪些地方被死锁以及哪些地方调用了Lock但是没有调用Unlock。假设这两个函数的原型为:
        void Lock();        void Unlock();
新设计的函数的原型是:
        void Lock(LPCTSTR szFileName,UINT uLineNo);        void Unlock(LPCTSTR szFileName,UINT uLineNo);
设计完新的函数后,项目经理希望所有模块统一使用这两个函数并提供文件名和行号信息作为参数。这样将是一个非常浩大且烦琐的工作,意味着重复性的劳动、数小时无聊的加班和工期的延误,这是谁都不愿意遇到的。使用宏可以非常轻松的解决这一切。首先,应该把新设计的函数换个名字,不妨叫它们NewLock和NewUnlock,也就是他们的原型为:
        void NewLock(LPCTSTR szFileName,UINT uLineNo);        void NewUnlock(LPCTSTR szFileName,UINT uLineNo);
这个函数原型应该放在一个头文件中,避免在多个地方重复的声明。需要用到这两个函数的cpp文件,只要包含他们原型所在的头文件即可。为了不改动使用Lock/Unlock函数的模块,在头文件中增加如下两行:
    #define Lock() NewLock(__FILE__,__LINE__)    #define Unlock() NewUnlock(__FILE,__LINE__)
这样,当不同模块使用这个函数时,宏替换功能在编译时起作用,自动使用了__FILE__和__LINE__为参数,调用了新设计的函数。调试的时候就可以根据日志来判断什么地方遗漏了调用Unlock。

4、给一个函数捆绑其他功能
上述方法修改了原来函数的设计。实际上,这两

来源:http://www.tulaoshi.com/n/20160129/1485903.html

延伸阅读
标签: word
Word中创建宏的攻略   宏其实是在我们的Word或者是Excel中,常常会碰到的一个词,也许很多的朋友,不大懂它,但是它的用处真的十分的强大。接下来,感兴趣的用户可以跟图老师小编一起学习一下在Word中创建宏的技巧。 Word 可以使用宏记录器录制一系列操作来创建宏 (宏:可用于自动执行任务的一项或一组操作。可用 Visual...
标签: 办公软件
快速输入填空题的空格线 我看到很多老师在输入填空题的空格线时,都采用先关闭输入法,后按住“Shift”+“_”的方法画空格线。用这种方法,是以半角字符画线,而且在录入过程中需要不断地切换输入法,很不方便。如果我们利用Word 2000中提供的“宏”功能,指定键盘上的一个组合键对应一段空格线,就可以在以后的输入填空题的空格线中轻松地...
标签: 电脑应用
1、单击“工具”菜单中“宏”子菜单中的“宏”命令。 2、在“宏名”框中,单击要运行的宏 (宏:可用于自动执行任务的一项或一组操作。可用 Visual Basic for Applications 编程语言录制宏。)的名称。 如果该宏没有出现在列表中,请在“宏的位置”框中选择其他的文档、模板 (模板:是指一个或多个文件,其中所包...
标签: 电脑应用
可以使用宏记录器录制一系列操作来创建宏 (宏:可用于自动执行任务的一项或一组操作。可用 Visual Basic for Applications 编程语言录制宏。),也可以在 Visual Basic 编辑器 (Visual Basic 编辑器:一种环境,用于编写新的 Visual Basic for Applications 代码和过程,并编辑已有的代码和过程。Visual Basic 编辑器包括完整的调试工具...
标签: 电脑应用
打开Word 2003,单击“工具”菜单,指向“宏”,在下一级菜单再单击“宏” 在“宏”列表框中单击要删除的宏名,然后再单击右侧的“删除”按钮 弹出“是否删除宏”的提示对话框,单击“是” 删除完后会出现“关闭”按钮,单击该按钮来关掉宏窗口 删除宏方案的步骤 单击菜...

经验教程

772

收藏

7
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部