外部变量

时间:2010-05-26 07:15:26

标签: c

如何使用标头中定义的变量,并使用extern在多个源文件中使用它们。 我收到了多个定义错误。

1 个答案:

答案 0 :(得分:9)

遵循的一条好规则是:“不要在头文件中定义事物”。 声明您想要的所有内容,但定义应限制为非标头。 声明只是一个存在某事的通知。 定义实际上定义了它是什么。

本指南背后的基本原理是准确防止您所看到的情况 - 将事物定义两次(或更多),因为头文件包含在多个编译单元中。

为避免这种情况,您可以使用以下内容:

myprog.h:
    extern int myVar;     // a declaration.

myprog.c:
    #include "myprog.h"
    int myVar = 7;        // a definition.

otherbit.c:
    #include "myprog.h"
    int fn (void) {
        myVar = 12;
        return myVar;
    }

上述定义只会以myprog.o结尾,您不会在otherbit.o中获得另一个副本,以免在链接时出现问题。

撇开正确的封装将使这些全局变量成为一个非常糟糕的主意,这就是我的方式。

封装的方式是这样的:

myprog.h:
    int getMyVar (void);
    void setMyVar (int);

myprog.c:
    #include "myprog.h"
    static int myVar = 7;
    int getMyVar (void) { return myVar; }
    void setMyVar (int n) {
        // Error checks on n here.
        myVar = n;
    }

otherbit.c:
    #include "myprog.h"
    int fn (void) {
        setMyVar (12);
        return getMyVar();
    }

封装基本上是信息隐藏。这意味着你应该以尽可能少的暴露内部工作来完成工作,以免你打开其他代码潜入隐藏的可能性,并使你的假设无效(见下文)或者让你以后更难改变你的内心运作。

一个典型的例子是,如果您希望myVar变量限制在0到359(包括角度)的范围内。使用封装,您只需使用:

void setMyVar (unsigned int n) { myVar = n % 360; }

从不必须担心它无效。你可以安全地假设,除了内存损坏,myVar将始终在所需的范围内。如果一些流氓用户代码可以进入并且只是这样做,你就不会有这种确定性:

myVar = 32767;

你不知道。您可能需要满足所需范围之外的值,或者在所有功能开始时将其强制设置为有效范围:

myVar = myVar % 360;

这是糟糕的编码习惯,完全没必要。