声明全局变量使用的技术
——摘自uC/OS-II中文版

以下是如何定义全局
变量。众所周知,全局变量应该是得到内存分配且可以被其他模块通过C 语言中extern 关键字调用的变量。因此,必须在 .C 和 .H
文件中定义。这种重复的定义很容易导致错误。以下讨论的方法只需用在头文件中定义一次。虽然有点不易懂,但用户一旦掌握,使用起来却很灵活。表1.2
中的定义出现在定义所有全局变量的.H 头文件中。

程序清单 L 1.2 定义全局宏。
    #ifdef xxx_GLOBALS
    #define xxx_EXT
    #else
    #define xxx_EXT extern
    #endif

.H 文件中每个全局变量都加上了xxx_EXT 的前缀。xxx 代表模块的名字。该模块的.C 文件中有以下定义:

#define xxx_GLOBALS
    #i nclude "includes.h"


编译器处理.C
文件时,它强制xxx_EXT(在相应.H文件中可以找到)为空,(因为xxx_GLOBALS已经定义)。所以编译器给每个全局变量分配内存空间,而当
编译器处理其他.C 文件时,xxx_GLOBAL 没有定义,xxx_EXT
被定义为extern,这样用户就可以调用外部全局变量。为了说明这个概念,可以参见uC/OS_II.H,其中包括以下定义:

#ifdef OS_GLOBALS
    #define OS_EXT
    #else
    #define OS_EXT extern
    #endif
    OS_EXT INT32U OSIdleCtr;
    OS_EXT INT32U OSIdleCtrRun;
    OS_EXT INT32U OSIdleCtrMax;

同时,uCOS_II.H 有中以下定义:

#define OS_GLOBALS
    #i nclude “includes.h”

当编译器处理uCOS_II.C 时,它使得头文件变成如下所示,因为OS_EXT 被设置为空。

INT32U OSIdleCtr;
    INT32U OSIdleCtrRun;
    INT32U OSIdleCtrMax;

这样编译器就会将这些全局变量分配在内存中。当编译器处理其他.C 文件时,头文件变成了如下的样子,因为OS_GLOBAL 没有定义,所以OS_EXT 被定义为extern。

extern INT32U OSIdleCtr;
    extern INT32U OSIdleCtrRun;
    extern INT32U OSIdleCtrMax;

在这种情况下,不产生内存分配,而任何 .C 文件都可以使用这些变量。这样的就只需在 .H文件中定义一次就可以了。

转自 http://blog.chinaunix.net/uid-2282111-id-2113225.html

关于语句#ifdef OS_GLOBALS #define OS_EXT #else #define OS_EXT extern #endif 的说明的更多相关文章

  1. #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #endif

    情况1:#ifdef _DEBUGvirtual void AssertValid() const;                 //assert(断言)valid(有效的,正确的)virtual ...

  2. 在头文件声明全局变量和创建extern

    在头文件声明全局变量和创建extern 问题: 是否有简单的方法,在头文件里定义我的变量,同时也为它们创建extern定义? 回答: 是的.尽管这不是必需的,使用正确的宏和一个头文件还是很容易实现的. ...

  3. C++ #if #endif #define #ifdef #ifndef #if defined #if !defined详解 (转)

    (源)http://blog.csdn.net/sky1203850702/article/details/42024673 首先,让我们先从头文件开始,在很多头文件里,我们会看到这样的语句 #ifn ...

  4. #define、#undef、#ifdef、#ifndef、#if、#elif、#else、#endif、defined解释

    #define.#undef.#ifdef.#ifndef.#if.#elif.#else.#endif.defined. #define            定义一个预处理宏#undef     ...

  5. 编译预处理命令--define和ifdef的使用

    这里将对常用的预处理命令进行学习. 一.宏定义  ·defined 格式:`defined     宏名      数值 或者 `define      宏名 注意:后面没有‘;‘,和单片机不一样: ...

  6. #define 多行多语句

    #define DEBUG_ENABLE 1 #if DEBUG_ENABLE > 0 #define DEBUG_PORT UART_PORT2 #define DBG_BUF_LEN 512 ...

  7. C++头文件为什么要加#ifndef #define #endif

    #ifndef 在头文件中的作用 在一个大的软件工程里面,可能会有多个文件同时包含一个头文件,当这些文件编译链接成一个可执行文件时 ,就会出现大量“重定义”的错误.在头文件中实用#ifndef #de ...

  8. 预编译那些事#define后面只跟一个“参数”

    一般情况下,源程序中所有的行都参加编译.但是有时希望对其中一部分内容只在满足一定条件才进行编译,也就是对一部分内容指定编译的条件,这就是“条件编译”.有时,希望当满足某条件时对一组语句进行编译,而当条 ...

  9. ifndef/define/endif 的作用

    转载自百度百科 ,感谢度娘 1 2 3 #ifdef语句1 //程序2 #endif 可翻译为:如果宏定义了语句1则执行程序2. 作用:我们可以用它区隔一些与特定头文件.程序库和其他文件版本有关的代码 ...

随机推荐

  1. Windows平台下PHP环境搭建

    在Windows平台上搭建PHP的开发环境可以下载WAMP(Windows.Apache.MySQL.PHP的首字母缩写)集成化安装包.这样就不需要单独安装Apache.MySQL和PHP了. 这款软 ...

  2. Could not find result map com.lrlz.weixin.dao.SysUserDAO.SysUser

    <select id="selectByTimeCount" resultType="java.lang.Integer" parameterType=& ...

  3. SQLServer数据库转换成MySQL数据库

    由于工作需要,系统原先的SQLServer数据库要转换成MYSQL数据库,所以这两天就一直在查阅这方面的资料.最开始,我尝试从SQLServer中导出SQL文件,然后导入到MYSQL数据库中,发现报错 ...

  4. Python学习感悟

    学习任何新知识,我自己偏向于在实践中学习,这样效率更高:如果只是学习基本概念,会很枯燥. 现在的问题是:不是所有的新知识都可以在实践中学习!

  5. 11——在operator=中处理自我赋值

    在operator=函数中加一个测试: if(&rhs==this) copy and swap

  6. svn客户端命令

    记几个常用的命令. 首次拉仓库时,先要进行检出(url可以带端口号): svn checkout http://svn.example.com:9834/repos svn checkout file ...

  7. ng-class的用法

    最近在学习angular框架,ng-class是angular框架的一个指令,这里是ng-class指令的官方解释: ng-class 指令用于给 HTML 元素动态绑定一个或多个 CSS 类. ng ...

  8. HTML 兼容性

    1. 不同浏览器对HTML标记所具有的内外边距属性具有不同的定义. 2. 因此如果想消除这种差距,应该在相应的CSS部分加入以下CSS代码: *{margin:0px;padding:0px;} 优先 ...

  9. 只需三步 快速完善网站Sitemap

    越来越多的SEOer把优化的重点放在了站内优化上,细心的朋友应该查看一些前辈的robots.txt的时候不难发现,他们的robots中都加 入了一句Sitemap: http://www.dewang ...

  10. 为什么有禁用Mac系统的Spotlight的需求:

    一.为什么有禁用Mac系统的Spotlight的需求: 有的网友由于使用的是相对较老的苹果电脑在运行较新的系统:也有可能你是个速度控,受不了偶尔卡卡顿顿的操作,必须将所有导致卡顿的原因全部消除:也有可 ...