【问题标题】:How am I able to access a static variable from another file? [duplicate]如何从另一个文件访问静态变量? [复制]
【发布时间】:2011-01-19 15:42:58
【问题描述】:

如何从另一个文件访问静态变量?静态变量没有文件范围吗?

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 

【问题讨论】:

  • 静态变量只有文件作用域,不能从其他文件访问,是不是违反或绕过了定义?
  • 从不 #include *.c, *.cpp, etc. files as headers.

标签: c static-variables


【解决方案1】:

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

如果有两个独立的翻译单元,一个单元不能访问另一个单元的statics,但不是你的情况。

如果你删除#include "a.c" 行并像它应该的那样编译:gcc a.c b.c,你将得到unresolved external 错误s

【讨论】:

  • 静态变量只有文件作用域,不能从其他文件访问,是不是违反或绕过了定义?
  • 静态范围仅限于翻译单元。在您的情况下,两个文件都是一个翻译单元。
  • 作为一般规则,我绝对同意 - 避免包含源文件(而不是标题)。但是,对于源文件内部的单元测试,包括源文件在内的源文件为测试代码提供了对其他不可见代码(变量和函数)的访问权限——并且非常有用。但这是一个非常专业的上下文。
  • @Jonathan:非常专业,不值得一提,因为对于尚未掌握 TU 概念的初学者感到困惑。也包含在一般规则“永远不要将实现 (*.c) 文件作为头文件”中,因为您没有将它们视为头文件。
【解决方案2】:

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

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

【讨论】:

  • 静态变量没有文件范围吗?
  • @aks:不,如果您指的是源文件,则不是。
  • #include 与一些其他语言支持的“import”或类似的不同。这更像是通过剪切和粘贴附加的“头”文件来组装单个源文件。它与将多个编译单元链接在一起不同 - 为此,您使用链接器来组合编译器从源文件生成的目标文件。单源文件的情况通常会变得容易 - 两个以上的文件并不难,但您确实需要知道编译器选项等,或者找到一个可以为您做这些的 IDE。
  • @aks:忘记“文件范围”并考虑翻译单元(TU),这种使用静态意味着“内部链接”,您可能会将其视为“TU 范围”。跨度>
  • @Steve314:gcc(以及我曾经使用过的大多数 C 编译器)让它变得非常容易,无论有多少文件:gcc a.c b.c。一个 15 分钟的制作教程,涵盖了隐式规则,CFLAGS 涵盖了其余部分。 (echo a.exe: a.o b.o &gt;&gt;Makefile &amp;&amp; make a.exe)
猜你喜欢
  • 2011-01-14
  • 2014-09-20
  • 1970-01-01
  • 2012-09-06
  • 2014-02-27
  • 2010-12-30
  • 2019-09-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多