我声明了一个结构数组,并希望在一个文件中定义第一个数组组件,在另一个文件中定义第二个数组组件。以下是一个例子。
header.h
struct st1 {
int a;
int b;
}
file1.c中
struct st1 structure1[2];
我想使用不同文件中的初始化structure1组件,如下所示
file2.c中
extern struct st1 structure1[0] = { 10, 100 };
file3.c中
extern struct st1 structure1[1] = { 200, 500 };
另请注意,在file2.c
和file3.c
中,定义不在函数内部。
如果我尝试编译,链接器会抛出多个定义的错误。
在使用Google搜索后,我知道extern
的定义只能发生一次。
我们可以在不同的源代码文件中完成extern
数组的这种定义吗?
更多信息: file2.c和file3.c有常量,我将在file1.c中使用。我目前的实现是我在file2.c和file3.c中使用init()函数。 file1.c使用初始化值来决定执行过程。由于file2.c和file3.c是导出常量,我的目的是避免来自file1.c的另外两个init调用。
答案 0 :(得分:3)
我试图尽可能地理解你想要的东西,我想你需要整理下面的文件。
头文件将包含整个项目中可用的共享符号引用以及一些函数:
////// header.h //////
struct st1 {
int a;
int b;
};
extern struct st1 structure1[2];
extern void init2();
extern void init3();
然后,包含符号的实现;你也可以在这里进行初始化:
////// file1.c //////
#include "header.h"
struct st1 structure1[2];
然后,您将在其中进行结构更改的代码文件;因为这不可能在编译时发生,你需要将它包装在你可以从其他地方调用的函数中。
////// file2.c //////
#include "header.h"
void init2()
{
structure1[0] = (struct st1){10, 100};
}
////// file3.c //////
#include "header.h"
void init3()
{
structure1[1] = (struct st1){200, 500};
}
上面两个脚本都有一个初始化函数,可以调用它来写入结构。最后,一个演示行为的示例:
////// main.c //////
#include "header.h"
#include <stdio.h>
int main(void)
{
init2();
init3();
printf("s[0].a = %d, s[1].a = %d\n", structure1[0].a, structure1[1].a);
return 0;
}
像这样编译:
cc -o file file1.c file2.c file3.c main.c
答案 1 :(得分:2)
除非您的file2.c
和file3.c
被编译为不同的可执行文件,否则您的问题没有任何意义,因为某个给定的可执行文件不能具有某些相同变量的两个定义< /强>;您在大多数实施中都会收到linker错误。因此,我猜您有两个共享公共file1.c
和header.h
因此,我们假设file2.c
和file3.c
被编译到不同的程序中。所以(在Linux上)你会编译并链接file1.c
&amp; file2.c
使用
proga
计划
gcc -c -Wall -g file1.c
gcc -c -Wall -g file2.c
gcc file1.o file2.o -o proga
(或等同于Makefile
规则),您可以编译并链接file1.c
&amp; file3.c
到不同的 progb
计划
gcc -c -Wall -g file1.c
gcc -c -Wall -g file3.c
gcc file1.o file3.o -o progb
当然,所有file1.c
,file2.c
,file3.c
都有#include "header.h"
指令。显然,file1.c
的编译可以完成一次(并且make
会处理这个问题),重复使用file1.o
和proga
的对象文件progb
。 header.h
然后你可能应该在// in header.h
extern struct st1 structure1[];
structure1
并且您无法在另一个文件(实际翻译单元)中定义structure1[0]
的每个组件。因此,您无法填写file2.c
中的structure1[1]
&amp; file3.c
中的fill_first
(除非您在运行时填写一些明确的例程,例如fill_second
&amp; main
,您可以明确地调用它们,例如在{{1}的开头}})
您可以做的是(因为file2.o
仅在proga
中链接,而file3.o
仅在progb
中与file2.c
中的file3.c
具有不同的定义)在structure1
中(但定义是定义整个 // in file2.c
struct st1 structure1[2] = { {1,2}, {3,4} };
,而不是它的某些部分!)所以你可能有
// in file3.c
struct st1 structure1[3] = { {0,1}, {2,3}, {3,4} };
和
init.c
实际上,您可能有一个structure1
文件(仅包含数据的定义(如#if
),它可能会使用预处理器技巧(例如#ifdef
或proga
指令)对progb
&amp; init-proga.o
进行不同的初始化;您可能需要以不同的方式将其编译为两个不同的目标文件,例如init-progb.o
&amp; http://developer.android.com/guide/topics/media/mediaplayer.html
http://code.tutsplus.com/tutorials/create-a-music-player-on-android-song-playback--mobile-22778
,...
答案 2 :(得分:1)
在header.h
文件中
struct st1 {
int a;
int b;
};
extern struct st1 structure1[2]; /* Have your declaration here */
在您的.c
个文件中,例如file1.c
,您可以定义您的结构:
struct st1 structure1[2]; /* Define your structure here */
void func1()
{
structure[0].a = 10;
structure[0].b = 100;
}
在file2.c
:
#include "header.h" /* Make the declaration of your structure visible here */
void func2()
{
structure[1].a = 200;
structure[1].b = 500;
}
当然,在两个函数都被调用之前,结构不会被完全初始化。