假设我有一个包含结构的头文件文件。
Struct aa
{
int a;
int b;
};
在a.c
文件中,我包含了该头文件,而我
struct aa first;
然后使用first.a
和first.b
进行更改。
在b.c
文件中,我包含了该头文件,而我
struct aa first;
然后使用first.a
和first.b
进行更改。
我可以做b.c
中做过的事吗?联系是如何完成的?它会覆盖这些值吗?它是如何工作的?
或者我应该在任何地方使用extern吗?
答案 0 :(得分:2)
如果你在函数中写struct aa first;
,
// a.c
#include "your_header.h"
void foo(void)
{
struct aa first;
first.a = 18;
first.b = 19;
...
}
// b.c
#include "your_header.h"
void bar(void)
{
struct aa first;
first.a = 21;
first.b = 22;
...
}
然后变量分别是foo
和bar
的局部变量
碰巧有相同的名字,但不是同一个变量。所以
first
中bar
的初始化不会以任何方式影响变量
first
中的foo
。
如果你想要一个全局变量,那么不同的编译单元(意思是
不同的.c
文件,例如a.c
和
b.c
可以访问,然后您需要将变量声明为extern
标题并在a.c
或b.c
中定义。
// your_header.h
#ifndef YOURHEADER_H
#define YOURHEADER_H
struct aa {
int a;
int b;
};
// the "extern" tells the compiler that the
// variable might be defined somewhere else,
// it it's not in the current compile unit,
// it won't give you an error.
extern struct first;
#endif
// a.c
#include "your_header.h"
// a.c defines in this compile unit the global
// variable. This information is important for the linker as well
struct first;
void foo(void)
{
first.a = 10;
first.b = 11;
}
//b.c
#include "your_header.h"
void bar(void)
{
first.a = 100;
first.b = 200;
}
现在编译a.c
:gcc a.c -c -o a.o
时,编译器就知道了
头文件first
是可以在另一个中定义的全局变量
编译单位。在这种情况下,它在a.c
本身中定义。
现在编译b.c
:gcc b.c -c -o b.o
时,编译器就知道了
头文件first
是可以在另一个中定义的全局变量
编译单位。它没有在b.c
中定义,因此编译器将允许链接器
处理这件事。
当您关联程序时:gcc a.o b.o othermodules.o -o myprogram
,
链接器将知道变量first
定义在哪个目标文件中
为程序访问此变量时创建正确的偏移量。
在这种情况下,如果您在main
。
#include "your_header.h"
#include "other_headers.h"
int main(void)
{
foo();
bar();
}
然后bar
将覆盖first.a
中设置的first.b
和foo
的值,
因为first
是一个全局变量。