K& R c第83页说明如下:
应用于外部变量或函数的静态声明将该对象的范围限制为正在编译的源文件的其余部分。因此,外部静态提供了隐藏
buf
-bufp
组合中getch
和ungetch
等名称的方法,这些名称必须是外部的,以便可以共享,但不应该getch
和ungetch
的用户可以看到。
如果新文件中的变量没有extern
修饰符,那么任何外部变量如何在另一个文件中可见?是否为静态存储类的变量添加了某种类型的保护?
在外部变量上使用static的目的是什么?有什么简单的例子吗?
编辑:
我认为我的问题令人困惑,所以我会把它写成代码。我正在扩展这个想法以包含功能:
文件1的内容
void somefunc(void);
int x;
int main()
{
....
}
void somefunc(void)
{
....
}
文件2
int x;
void somefunc(void);
void somefunc(void)
{
....
}
请注意,文件1中的int x
和somefunc()
在文件2中不可见,反之亦然。也就是说,除非我们在任一文件中的extern
和/或int x
上包含somefunc()
修饰符,否则文件中的匹配函数和变量名将彼此不可见。
为什么我们需要将static
放在其中一个变量或函数上,以防止变量或函数在另一个文件中可见,如果我们必须故意使用extern
来制作函数或变量在另一个文件中可见?
代码需要看起来像这样,文件2的内容在文件1中可见:
extern void somefunc(void);
extern int x;
int main()
{
....
}
void somefunc(void)
{
....
}
文件2
int x;
void somefunc(void);
void somefunc(void)
{
....
}
答案 0 :(得分:2)
K& R2与C标准之间存在术语差异。
K& R2使用措辞外部变量作为文件范围变量,并使用措辞 external static 指定使用静态存储声明的文件范围变量类说明符。在C标准中,单词 external 通常保留用于链接而不是词法范围。
答案 1 :(得分:1)
引用你引用的内容:
外部静态因此提供了隐藏
buf
-bufp
组合中的getch
和ungetch
等名称的方法,这些名称必须是外部的,以便可以共享它们getch
和ungetch
的用户不应该看到这些内容。
它只是意味着静态变量不是函数范围的静态变量。它们在函数外部,但在文件中是静态的。
在文件中将它们设为静态会使getch
和ungetch
看到它们,但不会显示给其他文件中的其他函数。
更新,以回应已修改的问题
你说,
请注意,文件1中的
int x
和somefunc()
在文件2中不可见,反之亦然。也就是说,除非我们在任一文件中的extern
和/或int x
都包含somefunc()
修饰符,否则文件中的匹配函数和变量名将彼此不可见。
这是一个错误的结论。
该行
int x;
相当于:
extern int x;
int x;
该行
void somefunc(void);
相当于:
extern void somefunc(void);
如果您编译"文件1"和"文件2"并链接生成的目标文件以创建可执行文件,您将获得链接器错误,以便int x
和void somefunc(void)
被多重定义。
为了使它们仅在相应的文件中可见,您必须在文件范围内创建static
。
static int x;
static void somefunc(void);
答案 2 :(得分:0)
这个简单的问题很少得到完全回答。 Static在C中有三种不同的用途:
(a)在函数体内声明为static的变量在函数调用之间保持其值。
(b)在模块1内声明为静态的变量(但在函数体外部)可由该模块中的所有函数访问。任何其他模块中的函数都无法访问它。也就是说,它是一个本地化的全球化。
(c)在模块中声明为static的函数只能由该模块中的其他函数调用。也就是说,函数的范围被本地化为声明它的模块。
大多数候选人都认为第一部分是正确的。一个合理的数字得到第二部分是正确的,而一个可怜的数字理解答案(c)。
来自A ‘C’ Test: The 0×10 Best Questions for Would-be Embedded Programmers
答案 3 :(得分:0)
考虑这种情况:
如果您有三个文件,则文件1和文件2都具有int x
,但是具有不同的值,那么在文件3中您具有extern int x
。编译器如何知道您想要哪个x?那就是您需要extern
的时候了。