- 全局变量,在A.c文件中定义的变量,在A.h中用extern声明一下即为全局变量,B.c文件想要调用的话只需要,包含A.h即可使用
- 如果不想让其他.c文件引用本文件中的变量,加上static即可。
- include相当于把include .h文件直接带入到本源文件里,比如在b.c文件里include “A.h”,就相当于把A.h文件里所有定义的变量和函数全部拷贝了一份放入了B.c里,一个项目里,一个.h文件可能会被多个.c源文件包含,这样编译的时候就会报重复定义的错误。而且尽量不要在.h里定义变量。
- 如何在头文件里定义全局变量:
众所周知,全局变量应该是得到内存分配且可以被其他模块通过C 语言中extern 关键字调用的变量。因此,必须在 .C 和 .H 文件中定义。这种重复的定义很容易导致错误。以下讨论的方法只需用在头文件中定义一次。虽然有点不易懂,但用户一旦掌握,使用起来却很灵活。
定义全局宏。
#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#endifOS_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文件中定义一次就可以了。
**
关于函数的调用
**
1、通常做法–在A.c中定义,在A.h中extern出来,那么其他编译单元include这个A.h文件就可以使用这个变量。
2、函数如果定义在A.c文件中,或者定义在A.h文件中并且A.c文件#include了这个A.h就不用加extern,因为这两种情况下A.c文件都可以直接找到
一旦有一个函数定义在另一个B.c文件中,而你要想在A.c文件中使用的时候就必须用extern关健字声明一下,否则链接会出错。
3、此外,函数申明默认就是extern的,所以函数声明前的extern可以省略不加。钩子函数