使用“.h”文件中的结构
Use of struct from ".h" file
假设我有一个包含结构的头文件。
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 吗?
如果在函数中写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
header 并在 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
时,编译器知道
header 文件,first
是一个可以在另一个文件中定义的全局变量
编译单元。在这种情况下,它在 a.c
本身中定义。
现在当你编译 b.c
: gcc b.c -c -o b.o
时,编译器知道
header 文件,first
是一个可以在另一个文件中定义的全局变量
编译单元。它没有在 b.c
中定义,所以编译器会让 linker
处理这个。
当您 link 您的程序:gcc a.o b.o othermodules.o -o myprogram
,
linker 将知道在哪个 object 文件中定义了变量 first
并将
为程序访问此变量时创建正确的偏移量。
在这种情况下,如果您在 main
中执行此操作。
#include "your_header.h"
#include "other_headers.h"
int main(void)
{
foo();
bar();
}
然后 bar
将 覆盖在 foo
中设置的 first.a
和 first.b
的值,
因为 first
是一个全局变量。
假设我有一个包含结构的头文件。
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 吗?
如果在函数中写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
header 并在 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
时,编译器知道
header 文件,first
是一个可以在另一个文件中定义的全局变量
编译单元。在这种情况下,它在 a.c
本身中定义。
现在当你编译 b.c
: gcc b.c -c -o b.o
时,编译器知道
header 文件,first
是一个可以在另一个文件中定义的全局变量
编译单元。它没有在 b.c
中定义,所以编译器会让 linker
处理这个。
当您 link 您的程序:gcc a.o b.o othermodules.o -o myprogram
,
linker 将知道在哪个 object 文件中定义了变量 first
并将
为程序访问此变量时创建正确的偏移量。
在这种情况下,如果您在 main
中执行此操作。
#include "your_header.h"
#include "other_headers.h"
int main(void)
{
foo();
bar();
}
然后 bar
将 覆盖在 foo
中设置的 first.a
和 first.b
的值,
因为 first
是一个全局变量。