在C中尝试全局变量和函数

时间:2011-07-03 16:23:06

标签: c global-variables globalization

我正在尝试理解全局变量和函数如何在C中工作。我的程序使用gcc编译并正常工作,但不能使用g++进行编译。我有以下文件:

globals.h:

int i;
void fun();

globals.c:

#include "stdlib.h"
#include "stdio.h"

void fun()
{
  printf("global function\n");
}

main.c中:

#include "stdlib.h"
#include "stdio.h"
#include "globals.h"

void myfun();

int main()
{

  i=1;

  myfun();

  return 0;
}

最后, myfun.c

#include "stdlib.h"
#include "stdio.h"
#include "globals.h"

void myfun()
{
  fun();
}

使用g ++编译时出现以下错误:

/tmp/ccoZxBg9.o:(.bss+0x0): multiple definition of `i'
/tmp/ccz8cPTA.o:(.bss+0x0): first defined here
collect2: ld returned 1 exit status

任何想法为什么?我宁愿用g ++编译。

4 个答案:

答案 0 :(得分:6)

包含globals.h的每个文件都将定义“int i”。

相反,把“extern int i;”进入头文件然后把实际定义“int i = 1;”在globals.c中。

在globals.h周围设置标题保护也是明智的。

编辑:在回答您的问题时,因为#include的作用类似于剪切和粘贴。它将包含文件的内容粘贴到您调用的c文件中。当您从main.c和myfun.c中包含“globals.h”时,您将在两个文件中定义int i = 1。这个全局的值被放入可链接值表中。如果你有两次相同的变量名,那么链接器就无法分辨出它需要哪一个,你就会得到你看到的错误。而是通过在头文件的前面添加extern,您告诉每个文件“int i”在其他地方定义。显然,你需要在其他地方定义它(并且只在一个地方),所以在globals.c中定义它是完全合理的。

希望有所帮助:)

答案 1 :(得分:1)

我会在你的全局文件中添加一个include guard

#ifndef GLOBALS_H
#define GLOBALS_H

int i;
void fun();

#endif

编辑:将你的全局变更为这样(使用extern作为另一个答案描述)

globals.h

extern  int i;
extern  void fun();

globals.c

#include "stdlib.h"
#include "stdio.h"
int i;
void fun()
{
  printf("global function\n");
}

我用

编译了它
g++ globals.c main.c myfun.c

它运行正常

答案 2 :(得分:1)

这里有些不对劲;其他一些强烈推荐的事情:

globals.h:


#ifndef GLOBALS_H
#define GLOBALS_H

extern int my_global;

#ifdef __cplusplus
extern "C" {
#endif 
void fun();
#ifdef __cplusplus
}
#endif 

#endif
/* GLOBALS_H */

globals.c:


#include <stdlib.h>
#include <stdio.h>
#include "globals.h"

int my_global;

void fun()
{
  printf("global function: %d\n", my_global);
}

main.c中:


#include <stdlib.h>
#include <stdio.h>
#include "globals.h"

void myfun();

int main()
{

  my_global=1;

  myfun();

  return 0;
}

void myfun()
{
  fun();
}
  1. 你应该在标题中声明“extern int myvar”,并在一个且只有一个.c文件中实际分配“int myvar”。

  2. 您应该在每个使用“myvar”的文件中包含“globals.h” - 包括分配它的文件。

  3. 特别是如果你计划混合使用C和C ++模块,你应该使用'extern“C”来区分非C ++函数。

  4. 系统标题应为“#include&lt; some_header.h&gt;”;你自己的标题应该使用引号(#include“myheader.h”)代替。

  5. 像“i”这样的短变量名称对于严格的局部变量(如循环索引)可能没问题,但是只要你不能避免使用全局变量,就应该总是使用更长的描述性名称。

  6. 我为my_global添加了“printf”。

  7. '希望有所帮助!

答案 3 :(得分:0)

将一些旧的C代码移植到C ++时遇到了这个问题。问题是它是一个连接到数据库的项目,我想将数据库移植到c ++而不是其余的。数据库引入了一些无法移植的C依赖项,因此我需要与数据库和其他项目重叠的C代码,以g ++和gcc编译......

此问题的解决方案是将所有变量定义为.h文件中的 extern 。然后当你用gcc或g ++编译时,它会报告.c文件中缺少的符号。因此,请编辑错误消息中的.c文件,并将声明插入所有 <。 变量的.c文件中。注意:您可能必须在多个.c文件中声明它,这就是我扔的原因以及为什么我长期坚持这个问题。

无论如何,这解决了我的问题,代码现在在gcc和g ++下干净利落地编译。