C 如何从另一个文件访问静态变量?

C 如何从另一个文件访问静态变量?,c,static-variables,C,Static Variables,如何从另一个文件访问静态变量?静态变量没有文件作用域吗 bash-3.2$ ls a.c b.c bash-3.2$ cat a.c #include <stdio.h> static int s = 100; int fn() { /* some code */ } bash-3.2$ cat b.c #include <stdio.h> #include "a.c" extern int s; int main() { printf("s = %d \n",s

如何从另一个文件访问静态变量?静态变量没有文件作用域吗

bash-3.2$ ls
a.c  b.c

bash-3.2$ cat a.c
#include <stdio.h>
static int s = 100;
int fn()
{
/*  some code */
}

bash-3.2$ cat b.c
#include <stdio.h>
#include "a.c"
extern int s;
int main()
{
printf("s = %d \n",s);
return 0;
}

bash-3.2$ gcc b.c   

bash-3.2$ a.exe
s = 100 
bash-3.2$ls
a、 卑诗省
bash-3.2美元cat空调
#包括
静态int s=100;
int fn()
{
/*一些代码*/
}
bash-3.2美元b.c类
#包括
#包括“交流”
外部内部;
int main()
{
printf(“s=%d\n”,s);
返回0;
}
bash-3.2$gcc不列颠哥伦比亚省
bash-3.2$a.exe
s=100

它来自一个单独的文件,但您打印的内容不是来自一个单独的翻译单元,因为您从
b.c
中包含了整个
a.c


静态
对象是翻译单元的本地对象,翻译单元由所有包含的文件组成,而不是单个源文件。

您将一个文件包含到另一个文件中-非常糟糕的做法。从C编译器的角度来看,这两个文件构成一个翻译单元,因为C预处理器将
a.C
的内容插入
b.C

如果有两个独立的翻译单元,一个单元无法访问另一个单元的
static
s,但这不是您的情况


如果您删除
#include“a.c”
行并按原样编译:
gcc a.c b.c
,您将得到
未解决的外部
错误,因为
s

静态变量是否有文件作用域?@aks:不,如果您指的是源文件。#include与某些其他语言支持的“导入”或类似。这更像是通过剪切和粘贴附加的“头”文件来组装单个源文件。这与将多个编译单元链接在一起不同——为此,您可以使用链接器来组合编译器从源文件生成的目标文件。单源文件的情况通常会变得简单-两个+文件并不难,但您确实需要知道编译器选项等,或者找到一个IDE为您做到这一点。@aks:忘记“文件范围”,从翻译单元(TU)的角度考虑,这种静态用法意味着“内部链接”,您可能会认为是“TU范围”。@Steve314:gcc(以及我使用过的大多数C编译器)让它变得非常简单,不管有多少个文件:
gcc a.C b.C
。一个15分钟的make教程涵盖了隐式规则和CFLAGS,其余的都涵盖了。(
echo a.exe:a.o b.o>>Makefile&&make a.exe
)静态变量只有文件作用域,不能从另一个文件访问,这是否违反或绕过了静态变量的定义?静态作用域仅限于翻译单元。在您的情况下,两个文件都是一个翻译单元。作为一般规则,我绝对同意-避免包含源文件(而不是标题)但是,对于单元测试,源文件(包括源文件)的内部为测试代码提供了访问其他不可见代码(变量和函数)的权限-可能非常有用。但这是一个非常专业的上下文。@Jonathan:非常专业,不值得一提,因为对于尚未掌握TUs概念的初学者来说很困惑。也包括在一般规则“永远不要将实现(*.c)文件作为头”中因为您没有将它们视为标题。它是否违反或绕过了静态变量的定义,即它只有文件作用域,不能从另一个文件访问?永远不要将#包括*.c、*.cpp等文件作为标题。