在不同的文件中使用全局变量

时间:2015-12-06 15:50:13

标签: c

所以我要做的是在file2.c中使用file1.c中的变量。 我已经在这里看到了一些答案,但我仍然得到了和以前一样的错误。 (error: variably modified at file scope

我在file1.c上的内容是这样的:

extern int num = 0;
struct abc *do_something(int n){
    num = n;
}
/*more code below*/

现在我想在file2.c上使用num。我有这个:

#include <something.h> /*which has file1.h inside*/
int num;
struct list_t list[num]; /*error here*/

/*code that uses the initialized list below*/

我尝试使用像#define test_num num这样的东西,但它也没用。我需要列表在file2上是“全局”的,所以我可以用不同的方法。

3 个答案:

答案 0 :(得分:1)

实际上你有两个问题。第一个与您的错误相关的是,当编译器看到数组num的声明时,list的值为 unknown 。编译器不知道任何其他translation unit(包含所有包含头文件的源文件)的任何内容,它只知道它正在处理的翻译单元。

第二个问题更具理论性,并且在编译时数组的大小是固定的,并且在运行时更改变量num不会改变大小阵列。

第一个问题可以通过将num的初始化移动到实际使用它的translation unit来解决。哦,并没有将其初始化为零,零大小的数组没有多大用处。

使用mallocrealloc使用指针和动态分配可以解决第二个问题。

答案 1 :(得分:1)

list声明中的错误与全局num的定义无关,尽管这也是错误的,而是您尝试使用外部变量对数组进行维度一个功能。这是非法的,也是胡说八道。实例化numlist的值是非确定性的,即使num首先被初始化,您也要声明一个零长度的数组。

您将extern放在错误的位置。在file1.c中你应该有:

int num = 0 ;

在file2.c中:

extern int num ;

通常你会将extern声明放在头文件中 - 这允许编译器检查声明和定义之间的类型匹配,并允许在单个点的多个文件中使用正确和一致的声明例如,您应该更改类型的维护。

// file1.h
#if !defined file1_INCLUDE
#define file1_INCLUDE

extern int num ;  // Declaration

#endif
// file1.c
#include "file1.h"

int num = 0 ; // Definition/Instantiation
// file2.c
#include "file1.h"
int f()
{
    return num ;  // Use file1::num
}

所有说真的根本不使用全局变量。这是不好的做法和不必要的。更确切地说:

// file1.h
#if !defined file1_INCLUDE
#define file1_INCLUDE

  void setNum( int n ) ;
  int getNum() ;

#endif
// file1.c
#include "file1.h"

static int num = 0 ; // Protected by file scope
void setNum( int n ) { num = n ; }
int getNum() { return n ; }
// file2.c
#include "file1.h"

int f()
{
    setNum( getNum() + 1 ) ;  // Increment num (example r/w access)
    return getNum() ;
}

这有许多优点,包括:

  • 设置功能可以检查或验证
  • 变量可以通过外部函数(通过省略setter)设置为只读
  • 可以通过外部函数(通过省略getter)使变量成为只写的
  • 没有什么可以以不受控制的方式引用变量和猴子。
  • 在调试中,对变量的所有访问都可以被访问函数中的断点捕获。

进一步阅读A Pox on Globals(与嵌入式系统有关,但一般情况下也同样适用。

答案 2 :(得分:0)

要在两个文件之间共享一个全局变量,您应该知道该变量属于源文件,该文件声明没有&#34; extern&#34;。因此,它也应该在该源文件中初始化。使用extern告诉编译器,它会在链接时从其他一些目标文件中找到该变量。

正如Joachim所写,使用此全局变量时,您的数组也存在问题。