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

C 在不同的文件中使用全局变量,c,C,所以我要做的是在file2.c中使用file1.c中的变量。 我已经在这里看到了一些答案,但是我仍然得到了和以前一样的错误。(错误:在文件范围内进行可变修改) 我在file1.c上看到的内容如下: extern int num = 0; struct abc *do_something(int n){ num = n; } /*more code below*/ 现在我想在file2.c上使用num。我有这个: #include <something.h> /*which

所以我要做的是在file2.c中使用file1.c中的变量。 我已经在这里看到了一些答案,但是我仍然得到了和以前一样的错误。(
错误:在文件范围内进行可变修改

我在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*/
#include/*其中包含file1.h*/
int-num;
结构列表\u t列表[num]/*这里出错*/
/*使用以下已初始化列表的代码*/

我试着使用类似于
#define test_num
的东西,但它也不起作用。我需要列表在文件2中是“全局”的,这样我就可以用不同的方法使用它。

实际上您有两个问题。与错误相关的第一个问题是,当编译器看到数组
列表的声明时,
num
的值未知。编译器不知道其他任何东西(包含所有头文件的源文件),只知道当前正在处理的翻译单元

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

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


第二个问题可以通过使用指针和使用
malloc
realloc
的动态分配来解决。要在两个文件之间共享一个全局变量,您应该知道该变量属于未声明为“extern”的源文件。因此,它也应该在该源文件中初始化。使用extern告诉编译器它将在链接时从其他对象文件中找到变量


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

列表中的错误与全局
num
的定义无关,尽管这也是不正确的,但您正试图使用函数外部的变量对数组进行尺寸标注。这是非法的,也是无稽之谈。实例化
list
num
的值是不确定的,即使首先初始化了
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


上面所说的一切都不使用globals。这是不好的做法,没有必要。而是:

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

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

#endif


这有许多优点,包括:

  • 设置功能可以进行范围检查或验证
  • 外部函数可以将变量设置为只读(通过省略setter)
  • 变量只能由外部函数写入(通过省略getter)
  • 任何东西都不能引用变量并以不受控制的方式使用它
  • 在调试中,访问函数中的断点可以捕获对变量的所有访问

进一步阅读(与嵌入式系统相关,但同样适用于一般情况。

不要使用全局变量。通常以tesrs@EdHeal:那是“泰瑟枪”还是“眼泪”?我真的希望是“泰瑟枪”;-)有一条评论提到了file1.h,但问题中没有提到file1.h。该死的电话是tearsHi,我确实需要/希望阵列的大小相同。但是关于
num
未知的问题,我认为通过在文件1上初始化它并在文件2上使用它之前进行更改,可以解决这个问题。我会查一下你的链接。
// 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() ;
}