How do I use extern to share variables between source files?
我知道C中的全局变量有时有
这与跨源文件共享变量有关,但它是如何精确工作的?我在哪里使用
使用
理解定义变量并声明变量:好的。
- 当编译器得知变量存在(这是它的类型);它不分配在该点存储变量。
- 当编译器为指定的变量。
您可以多次声明一个变量(尽管一次就足够了);在给定范围内只能定义一次。变量定义也是一个声明,但不是所有变量声明是定义。好的。声明和定义全局变量的最佳方法
声明和定义全局变量的干净、可靠的方法是使用包含变量的
头包含在定义变量的源文件中以及引用变量的所有源文件。对于每个程序,一个源文件(并且只有一个源文件)定义变量。同样,一个头文件(并且只有一个头文件)应该声明变量。头文件非常重要;它可以在独立的tus(翻译单元-思考源文件)并确保一致性。好的。
虽然还有其他方法,但这种方法很简单,可靠。由
1 | extern int global_variable; /* Declaration of the variable */ |
文件1.C
1 2 3 4 5 6 7 | #include"file3.h" /* Declaration made available here */ #include"prog1.h" /* Function declarations */ /* Variable defined here */ int global_variable = 37; /* Definition checked against declaration */ int increment(void) { return global_variable++; } |
文件2.C
1 2 3 4 5 6 7 8 9 | #include"file3.h" #include"prog1.h" #include <stdio.h> void use_it(void) { printf("Global variable: %d ", global_variable++); } |
这是声明和定义全局变量的最佳方法。好的。
接下来的两个文件完成了
所示的完整程序使用函数,因此函数声明蹑手蹑脚地进来。C99和C11都要求在函数之前声明或定义它们使用(而C90没有,原因很好)。我在头中的函数声明前面使用关键字
1 2 | extern void use_it(void); extern int increment(void); |
前C
1 2 3 4 5 6 7 8 9 10 11 12 13 | #include"file3.h" #include"prog1.h" #include <stdio.h> int main(void) { use_it(); global_variable += 19; use_it(); printf("Increment: %d ", increment()); return 0; } |
prog1 使用prog1.c 、file1.c 、file2.c 、file3.h 和prog1.h 。
文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | # Minimal makefile for prog1 PROGRAM = prog1 FILES.c = prog1.c file1.c file2.c FILES.h = prog1.h file3.h FILES.o = ${FILES.c:.c=.o} CC = gcc SFLAGS = -std=c11 GFLAGS = -g OFLAGS = -O3 WFLAG1 = -Wall WFLAG2 = -Wextra WFLAG3 = -Werror WFLAG4 = -Wstrict-prototypes WFLAG5 = -Wmissing-prototypes WFLAGS = ${WFLAG1} ${WFLAG2} ${WFLAG3} ${WFLAG4} ${WFLAG5} UFLAGS = # Set on command line only CFLAGS = ${SFLAGS} ${GFLAGS} ${OFLAGS} ${WFLAGS} ${UFLAGS} LDFLAGS = LDLIBS = all: ${PROGRAM} ${PROGRAM}: ${FILES.o} ${CC} -o $@ ${CFLAGS} ${FILES.o} ${LDFLAGS} ${LDLIBS} prog1.o: ${FILES.h} file1.o: ${FILES.h} file2.o: ${FILES.h} # If it exists, prog1.dSYM is a directory on macOS DEBRIS = a.out core *~ *.dSYM RM_FR = rm -fr clean: ${RM_FR} ${FILES.o} ${PROGRAM} ${DEBRIS} |
指南
只有专家才能打破规则,而且必须有充分的理由:好的。
- 头文件只包含
extern 变量声明-从不static 或非限定变量定义。 - 对于任何给定的变量,只有一个头文件声明它(spot-单点真理)。
- 源文件从不包含变量的
extern 声明-源文件始终包含声明它们的(唯一)头文件。 - 对于任何给定的变量,只有一个源文件定义变量,最好也初始化它。(尽管没有必要显式初始化为零,没有伤害,可以做点好事,因为一个特定的程序中的全局变量)。
- 定义变量的源文件还包括确保定义和声明一致。
- 函数不需要使用
extern 声明变量。 - 尽可能避免使用全局变量-改用函数。
此答案的源代码和文本在我的SOQ(堆栈溢出问题)Github上的存储库SRC/SO-0143-3204标准子目录。好的。
如果你不是一个经验丰富的C程序员,你可以(也许应该)停止阅读。好的。定义全局变量的方法不太好
有了一些(实际上是许多)C编译器,您就可以摆脱也调用了变量的"common"定义。这里的"common"是指Fortran中用于共享的技术。源文件之间的变量,使用(可能已命名)公共块。这里所发生的是,许多文件中的每一个都提供了变量的定义。只要不超过一个文件提供初始化定义,然后,各种文件最终共享了变量:好的。文件10C
1 2 3 4 5 | #include"prog2.h" int i; /* Do not do this in portable code */ void inc(void) { i++; } |
文件11C
1 2 3 4 5 | #include"prog2.h" int i; /* Do not do this in portable code */ void dec(void) { i--; } |
文件12C
1 2 3 4 5 6 7 | #include"prog2.h" #include <stdio.h> int i = 9; /* Do not do this in portable code */ void put(void) { printf("i = %d ", i); } |
此技术不符合C标准的字母和"一个定义规则"-这是官方未定义的行为:好的。
J.2 Undefined behavior
Ok.
An identifier with external linkage is used, but in the program there
does not exist exactly one external definition for the identifier, or
the identifier is not used and there exist multiple external
definitions for the identifier (6.9).Ok.
§6.9 External definitions ?5
Ok.
An external definition is an external declaration that is also a
definition of a function (other than an inline definition) or an
object.
If an identifier declared with external linkage is used in an
expression (other than as part of the operand of asizeof or
_Alignof operator whose result is an integer constant), somewhere in
the entire program there shall be exactly one external definition for
the identifier; otherwise, there shall be no more than
one.161)Ok.
161) Thus, if an identifier declared with external linkage
is not used in an expression, there need be no external definition for
it.Ok.
然而,C标准也在资料性附录J中将其列为常见的扩展。好的。
J.5.11 Multiple external definitions
Ok.
There may be more than one external definition for the identifier of
an object, with or without the explicit use of the keyword extern; if
the definitions disagree, or more than one is initialized, the
behavior is undefined (6.9.2).Ok.
因为不总是支持这种技术,所以最好避免使用它,特别是当您的代码需要可移植时。使用这种技术,您也可以以无意的类型结束双关语。如果其中一个文件声明
接下来的两个文件完成了
1 2 3 | extern void dec(void); extern void put(void); extern void inc(void); |
丙二丙
1 2 3 4 5 6 7 8 9 10 11 12 | #include"prog2.h" #include <stdio.h> int main(void) { inc(); put(); dec(); put(); dec(); put(); } |
prog2 使用prog2.c 、file10.c 、file11.c 、file12.c 、prog2.h 。
警告
正如我在这里的评论中提到的,以及我对类似的问题,使用多个全局变量的定义导致未定义的行为(J.2;§6.9),这是标准的说法"任何事情都可能发生"。可能发生的事情之一是程序的行为和您的一样期待;J.5.11说,大约,"你可能更幸运比你应得的多"。但是一个依赖外部变量的多个定义的程序-带或不带显式"extern"关键字-不是严格的符合程序,不保证在任何地方工作。等价的:它包含一个可能或可能不显示自己的bug。好的。违反准则
当然,有很多方法可以打破这些准则。有时,可能有一个很好的理由违反指导方针,但是这种场合是极不寻常的。好的。福斯提字母名称(P)说明1:如果主定义的变量不包括EDOCX1 0。Then each file that includes the header creates a tentative definition从变量。As noted previously,this will often work,but the C standard does not确保这是工作。好的,好的。断裂之王字母名称(P)说明2:If the header defines and initializes the variable,they only1 Source file in a given program can use the header.因为头头是分享信息的主要渠道,所以它是一个比特沉默。To create one that can only be used 11.好的,好的。塞尔顿字母名称(P)说明3:If the header defines a static variable(with or without)Initialization,they each source file ends up with its own private全球变量的版本。好的,好的。(P)如果变量实际上是一个完整的阵列,例如,这可能会导致To extreme duplication of code.It can,very occasionally,be a敏感的方式来实现一些效果,但这是非常不寻常的。好的,好的。摘要(P)先用我的头技术It works reliably and everywhere.注意,特别是,主宣布以东X1为英文字母Included in every file that used it-including the one that defines it.This ensures that everything is self-consistent.好的,好的。(P)类似的关注与声明和定义的功能-Analogous Rules Apply.But the question was about variables specifically,so I've kept theAnswer to variables only.好的,好的。原创答案的结尾(P)如果你不是一个经验C程序,你应该停止阅读在这里。好的,好的。(P)Late Major Addition好的,好的。避免代码复制(P)Some concern that is sometimes(and legislately)raised about theDeclarations in Headers,Definitions in Source'Mechanism describedThere is that there are two files to be kept synchronized-the headerand the source.This is usually followed up with an observations that aMacro can be used so the header serves double duty-normally宣布变量,但当一个特定的宏观在设定之前Header is included,it defines the variables instead.好的,好的。(P)另一个关注可能是,变量需要被定义为a number of"main programs".这通常是一个土豆的问题;你Can simply introduce a c source file to define the variables and linkThe object file produced with each of the programs.好的,好的。(P)一个类型的计划工作类似于此,使用原始的全球变量伊留斯特好的,好的。牛排字母名称排骨字母名称页:1字母名称(P)下一份两份文件完成了EDOCX1的来源好的,好的。方案3.h字母名称方案3.c字母名称
- 爱德华X1
初始变量(P)The problem with this scheme as shown is that it does not provide for3.Initialization of the global variable.与C99或C11和可变ArgumentLists for macros,you could define a macro to support initialization too.(with C89 and no support for variable argument lists in macros,there is no)Easy way to handle arbitrarily long initializers.)好的,好的。立体字母名称(P)Reverse contents of EDOCX1 theocx1 plus 10 welcxy and EDOCX1 English 11 locks,fixing bug identified byDenis Kniazhev好的,好的。页:1字母名称牛排字母名称(P)Clearly,the code for the oddball structure is not what you'd normallyWrite,but it illustrates the point.The first argument to the second援引EDOCX1的英文字母12是EDOCX1的英文13和继续争论这个例子中的单数是英文字母14。无C99或类似支持For variable argument lists for macros,initializers that need to计算商品是一个很大的问题。好的,好的。(P)Correct Header EDOCX1 English 15 included(Instead of EDOCX1)Denis Kniazhev好的,好的。(P)下一份两份文件完成了EDOCX1的来源好的,好的。 prog4.h
1 2 3 | extern int increment(void); extern int oddball_value(void); extern void use_them(void); |
prog4.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
- 使用
prog4.c prog4 ,file1b.c ,file2b.c ,prog4.h ,file3b.h 。
标题:
任何头应该保护对reinclusion,所以那型 (枚举的定义,struct或联盟的类型或类型,一般做标注) 因为问题。冰的标准技术对身体的包裹 头一集控球后卫如: </P >好。
1 2 3 4 5 6 | #ifndef FILE3B_H_INCLUDED #define FILE3B_H_INCLUDED ...contents of header... #endif /* FILE3B_H_INCLUDED */ |
"头两次indirectly included可能会问。例如,如果
进一步的,它开始对山羊,狡猾的,因为你可能
所以,你需要TO INCLUDE身体部
但是,它可以让做的太受A标注不当的约束。 "让一个新的集并部文件名称: </P >好。
-
external.h 外部定义的宏,等。 -
file1c.h (特别是通过对define类型,struct oddball ,oddball_struct 类型)。 -
file2c.h 到define或DECLARE全局变量。 - 这defines
file3c.c 全局变量。 -
file4c.c 这简单的使用全局变量。 -
file5c.c "节目,你可以define DECLARE和当时的全局变量。 -
file6c.c "节目,你才可以define(DECLARE attempt到全局变量)。
在这些例子中,
"限制这到工作是: </P >好。
external.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | /* ** This header must not contain header guards (like must not). ** Each time it is invoked, it redefines the macros EXTERN, INITIALIZE ** based on whether macro DEFINE_VARIABLES is currently defined. */ #undef EXTERN #undef INITIALIZE #ifdef DEFINE_VARIABLES #define EXTERN /* nothing */ #define INITIALIZE(...) = __VA_ARGS__ #else #define EXTERN extern #define INITIALIZE(...) /* nothing */ #endif /* DEFINE_VARIABLES */ |
file1c.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #ifndef FILE1C_H_INCLUDED #define FILE1C_H_INCLUDED struct oddball { int a; int b; }; extern void use_them(void); extern int increment(void); extern int oddball_value(void); #endif /* FILE1C_H_INCLUDED */ |
file2c.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | /* Standard prologue */ #if defined(DEFINE_VARIABLES) && !defined(FILE2C_H_DEFINITIONS) #undef FILE2C_H_INCLUDED #endif #ifndef FILE2C_H_INCLUDED #define FILE2C_H_INCLUDED #include"external.h" /* Support macros EXTERN, INITIALIZE */ #include"file1c.h" /* Type definition for struct oddball */ #if !defined(DEFINE_VARIABLES) || !defined(FILE2C_H_DEFINITIONS) /* Global variable declarations / definitions */ EXTERN int global_variable INITIALIZE(37); EXTERN struct oddball oddball_struct INITIALIZE({ 41, 43 }); #endif /* !DEFINE_VARIABLES || !FILE2C_H_DEFINITIONS */ /* Standard epilogue */ #ifdef DEFINE_VARIABLES #define FILE2C_H_DEFINITIONS #endif /* DEFINE_VARIABLES */ #endif /* FILE2C_H_INCLUDED */ |
file3c.c
1 2 3 4 5 | #define DEFINE_VARIABLES #include"file2c.h" /* Variables now defined and initialized */ int increment(void) { return global_variable++; } int oddball_value(void) { return oddball_struct.a + oddball_struct.b; } |
file4c.c
1 2 3 4 5 6 7 8 9 10 | #include"file2c.h" #include <stdio.h> void use_them(void) { printf("Global variable: %d ", global_variable++); oddball_struct.a += global_variable; oddball_struct.b -= global_variable / 2; } |
file5c.c
1 2 3 4 5 6 7 | #include"file2c.h" /* Declare variables */ #define DEFINE_VARIABLES #include"file2c.h" /* Variables now defined and initialized */ int increment(void) { return global_variable++; } int oddball_value(void) { return oddball_struct.a + oddball_struct.b; } |
file6c.c
1 2 3 4 5 6 7 | #define DEFINE_VARIABLES #include"file2c.h" /* Variables now defined and initialized */ #include"file2c.h" /* Declare variables */ int increment(void) { return global_variable++; } int oddball_value(void) { return oddball_struct.a + oddball_struct.b; } |
下一completes源文件的源(主程序提供一
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
- 使用
prog5.c prog5 ,file3c.c ,file4c.c ,file1c.h ,file2c.h ,external.h 。 - 使用
prog5.c prog6 ,file5c.c ,file4c.c ,file1c.h ,file2c.h ,external.h 。 - 使用
prog5.c prog7 ,file6c.c ,file4c.c ,file1c.h ,file2c.h ,external.h 。
本方案避免很多问题。你只运行到一个问题,如果A 标题是defines变量(如
你可以不完全的问题,进行全面的revising
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | /* Standard prologue */ #if defined(DEFINE_VARIABLES) && !defined(FILE2D_H_DEFINITIONS) #undef FILE2D_H_INCLUDED #endif #ifndef FILE2D_H_INCLUDED #define FILE2D_H_INCLUDED #include"external.h" /* Support macros EXTERN, INITIALIZE */ #include"file1c.h" /* Type definition for struct oddball */ #if !defined(DEFINE_VARIABLES) || !defined(FILE2D_H_DEFINITIONS) /* Global variable declarations / definitions */ EXTERN int global_variable INITIALIZE(37); EXTERN struct oddball oddball_struct INITIALIZE({ 41, 43 }); #endif /* !DEFINE_VARIABLES || !FILE2D_H_DEFINITIONS */ /* Standard epilogue */ #ifdef DEFINE_VARIABLES #define FILE2D_H_DEFINITIONS #undef DEFINE_VARIABLES #endif /* DEFINE_VARIABLES */ #endif /* FILE2D_H_INCLUDED */ |
"问题"应该成为"include
1 2 3 | #define DEFINE_VARIABLES #include"file2c.h" #undef DEFINE_VARIABLES |
在源代码(SO的头域的值不会改变大学
1 2 | #define HEADER_DEFINING_VARIABLES"file2c.h" #include"externdef.h" |
externdef.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /* ** This header must not contain header guards (like must not). ** Each time it is included, the macro HEADER_DEFINING_VARIABLES should ** be defined with the name (in quotes - or possibly angle brackets) of ** the header to be included that defines variables when the macro ** DEFINE_VARIABLES is defined. See also: external.h (which uses ** DEFINE_VARIABLES and defines macros EXTERN and INITIALIZE ** appropriately). ** ** #define HEADER_DEFINING_VARIABLES"file2c.h" ** #include"externdef.h" */ #if defined(HEADER_DEFINING_VARIABLES) #define DEFINE_VARIABLES #include HEADER_DEFINING_VARIABLES #undef DEFINE_VARIABLES #undef HEADER_DEFINING_VARIABLES #endif /* HEADER_DEFINING_VARIABLES */ |
这是越来越convoluted A点,但表明是安全的(使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | /* Declare variables */ #include"file2d.h" /* Define variables */ #define HEADER_DEFINING_VARIABLES"file2d.h" #include"externdef.h" /* Declare variables - again */ #include"file2d.h" /* Define variables - again */ #define HEADER_DEFINING_VARIABLES"file2d.h" #include"externdef.h" int increment(void) { return global_variable++; } int oddball_value(void) { return oddball_struct.a + oddball_struct.b; } |
file8c.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | /* Standard prologue */ #if defined(DEFINE_VARIABLES) && !defined(FILE8C_H_DEFINITIONS) #undef FILE8C_H_INCLUDED #endif #ifndef FILE8C_H_INCLUDED #define FILE8C_H_INCLUDED #include"external.h" /* Support macros EXTERN, INITIALIZE */ #include"file2d.h" /* struct oddball */ #if !defined(DEFINE_VARIABLES) || !defined(FILE8C_H_DEFINITIONS) /* Global variable declarations / definitions */ EXTERN struct oddball another INITIALIZE({ 14, 34 }); #endif /* !DEFINE_VARIABLES || !FILE8C_H_DEFINITIONS */ /* Standard epilogue */ #ifdef DEFINE_VARIABLES #define FILE8C_H_DEFINITIONS #endif /* DEFINE_VARIABLES */ #endif /* FILE8C_H_INCLUDED */ |
file8c.c
1 2 3 4 5 6 7 8 9 10 | /* Define variables */ #define HEADER_DEFINING_VARIABLES"file2d.h" #include"externdef.h" /* Define variables */ #define HEADER_DEFINING_VARIABLES"file8c.h" #include"externdef.h" int increment(void) { return global_variable++; } int oddball_value(void) { return oddball_struct.a + oddball_struct.b; } |
下两个档案完整的源
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
文件9C
1 2 3 4 5 6 7 8 9 10 | #include"file2d.h" #include <stdio.h> void use_them(void) { printf("Global variable: %d ", global_variable++); oddball_struct.a += global_variable; oddball_struct.b -= global_variable / 2; } |
prog8 使用prog8.c 、file7c.c 、file9c.c 。prog9 使用prog8.c 、file8c.c 、file9c.c 。
但在实践中,这些问题不太可能发生,尤其是如果你接受标准建议好的。避免全局变量
这次展览错过了什么吗?好的。
招供:这里概述的"避免重复密码"计划是开发是因为问题影响了我所处理的一些代码(但不是我自己的代码)。对第一部分中概述的计划有点担心。答案。然而,最初的计划只给你两个保存变量定义和声明的修改位置同步,这是比有练习变量向前迈出的一大步。分散在整个代码库中的声明(这真的很重要当总共有数千个文件时)。但是,代码在名为
注意:这些是玩具程序,几乎没有足够的代码来制作它们。有点意思。例子中有重复可以删除,但不是为了简化教学解释。(例如:
假设你有两个
完整样品:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | $ cat test1.c int test1_var = 5; $ cat test2.c #include <stdio.h> extern int test1_var; int main(void) { printf("test1_var = %d ", test1_var); return 0; } $ gcc test1.c test2.c -o test $ ./test test1_var = 5 |
extern是用于声明变量本身驻留在另一个翻译单元中的关键字。
因此,您可以决定在一个翻译单元中使用一个变量,然后从另一个单元访问它,然后在第二个单元中声明它为extern,这个符号将由链接器解析。
如果不将其声明为外部变量,则会得到两个同名但完全不相关的变量,以及变量的多个定义错误。
我喜欢把外部变量看作是对编译器的承诺。
当遇到extern时,编译器只能找到它的类型,而不能找到它的"所在位置",因此它无法解析引用。
你在说,"相信我。在链接时,此引用将是可解析的。"
extern告诉编译器相信您这个变量的内存是在别处声明的,因此它不会尝试分配/检查内存。
因此,您可以编译一个引用外部的文件,但是如果没有在某个地方声明该内存,则不能链接该文件。
对于全局变量和库很有用,但是很危险,因为链接器不进行类型检查。
添加
extern的正确解释是您向编译器说明一些事情。您告诉编译器,尽管当前不存在,但链接器将以某种方式找到声明的变量(通常在另一个对象(文件))。然后,不管你是否有一些外部声明,链接器将是找到所有东西并将其组合在一起的幸运的人。
在C语言中,文件中的一个变量,例如example.c是给定的局部作用域。编译器期望该变量的定义位于同一个文件example.c中,如果找不到该变量,则会引发错误。另一方面,函数在默认情况下具有全局范围。因此,您不必显式地提到编译器"look dude…您可以在这里找到这个函数的定义"。对于包含其声明的文件的函数来说就足够了。(实际调用头文件的文件)。例如,考虑以下两个文件:实例C
1 2 3 4 5 6 |
1、C
1 | int a = 5; |
现在,当您使用以下命令将两个文件编译在一起时:
步骤1)cc-o示例.c示例1.c步骤2)
您得到以下输出:a的值<5>
extern关键字用于将变量标识为全局变量。
It also represents that you can use the variable declared using extern
keyword in any file though it is declared/defined in other file.
Linux下的gcc实现11
1 2 3 4 5 6 7 8 9 10 11 |
编译和decompile:
1 2 | gcc -c main.c readelf -s main.o |
输出包含:
1 2 3 | Num: Value Size Type Bind Vis Ndx Name 9: 0000000000000000 4 OBJECT GLOBAL DEFAULT 3 not_extern_int 12: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND extern_int |
系统V ABI规格更新11章解释了:"符号表"
SHN_UNDEF This section table index means the symbol is undefined. When the link editor combines this object file with another that defines the indicated symbol, this file's references to the symbol will be linked to the actual definition.
这是基本的行为给予
从现在的工作,它是在左翼做最终的项目,但
4.8在GCC的测试。
C++内联变量17
17在C + +,你可能想使用内联变量而不是外部的人,他们是简单的使用(可以定义只在头一次强大的(支持)和更多的constexpr)。湖:什么'是const静态均值在C和C + +?
如果不希望程序访问变量或函数,可以使用
1 2 3 4 5 6 7 8 9 | declare | define | initialize | ---------------------------------- extern int a; yes no no ------------- int a = 2019; yes yes yes ------------- int a; yes yes no ------------- |
声明不会分配内存(内存分配变量必须定义(定义)的通道。这只是另一个视图上简单的外部关键字。其他答案是真正伟大的。
首先,
这可以被
你要小心与xc8约declaring a变量在每一个相同的类型的文件你可以erroneously,,在一个文件中声明的东西
这个问题是我在论坛的一些优雅的15年前的A系统*湖"www.htsoft.com http:/ /"所有showflat.php论坛/ / / / / / / 0的数18766 CAT / / 0 / / 0 # 18766页"
但这似乎链接不再工作……
所以我会很快;它试图解释;为使文件global.h.
在它下面的声明
1 2 3 4 5 6 7 | #ifdef MAIN_C #define GLOBAL /* #warning COMPILING MAIN.C */ #else #define GLOBAL extern #endif GLOBAL unsigned char testing_mode; // example var used in several C files |
现在,在main.c文件
1 2 3 | #define MAIN_C 1 #include"global.h" #undef MAIN_C |
本main.c均值的变量将被作为一个
现在在其他的文件包括global.h想简单它被作为一个外部的一个文件。
1 | extern unsigned char testing_mode; |
但它会被作为一个
旧论坛后可能解释这一位更适合。但这是一个真实的潜力