我正在使用C,并且我需要一个字符串文字,该字符串文字可以在一个main
文件的.c
函数中发现,以便可以在完全不同的.c
中访问文件。
我尝试过的操作:我在标头中声明了指向字符串文字的指针为extern
,在一个.c
文件中定义了它,并试图在第二个{ {1}}文件。由于第二个(正在访问的)文件中缺少定义,因此编译失败。
简而言之:
file1.h :
.c
file1.c :
extern char *global;
file2.c :
#include "file1.h"
int main() {
//some code
extern char *global = some_struct->data;
//more code
}
由于#include "file1.h"
int do_stuff() {
//some code
some_function(global);
//more code
}
是在global
中定义的file1.h
中声明的,并且它的值是在file1.c
中访问的,所以我希望它能编译。但是,对于未定义的变量,file2.c
的编译失败。
如果相关,file2.c
中的main
函数始终是程序中运行的第一个函数。
答案 0 :(得分:2)
在主要
中extern char *global = some_struct->data;
是错误的,如果您想分配 global do:
global = some_struct->data;
以及一些需要在全局范围内定义 global 的地方:
char *global;
因此,例如 main 变为:
#include "file1.h"
char *global;
int main() {
//some code
global = some_struct->data;
//more code
}
答案 1 :(得分:0)
您正在接近,但还没到那儿。全局变量还必须在全局范围内定义,并且您会遇到声明和定义之间的差异(它们很容易实现绕错了方向,但词语与想法无关紧要)。通常,引入变量的语句将同时声明和定义,但对于在模块之间共享的全局变量却不是这样:
在您的file1.h
中,您正确地声明了全局范围内的char*
变量。包含此文件的任何人(例如file2.c
)都会“看到”具有该名称的变量,并且所有模块都将进行干净地编译,而extern
关键字则明确表明您仅声明它存在,尚未为其创建存储。那就是您想要的,因为您不想意外地使用此名称创建多个冲突的全局变量。当最终将已编译的模块链接在一起时,链接器将查找为全局预留的实际内存存储空间,并正确连接所有引用。
但是在您的情况下,这将无法正确发生,因为尽管您已经向世界宣布此全局存在,但您尚未实际为变量创建存储!
您仍然需要在file1.h
的全局范围内(功能之外)执行此操作:
char * global;
这将创建具有与extern声明匹配的名称的实际变量,因此链接器将能够正确地组装模块。
所以
#include "file1.h"
// Define global:
char * global;
int main() {
// Assign a value to the global variable:
global = some_struct->data;
//more code
}
请注意,您没有在该文件中重新声明extern或任何内容,也没有在global
中重新定义main
的类型,因为它已经存在,并且可以对其进行分配或看看它的价值。您也不要在此处使用关键字extern
,它是此变量的“主页”模块。
声明和定义通常是同时完成的,例如,在函数中声明局部变量时。可从不同模块访问的全局变量依赖于将工作分成两个单独的想法,以使同事,编译器和链接器工具链都不会因您的意图而混淆。