C “与”的区别是什么;“文件范围”;及;计划范围“;
全局声明的变量称为具有程序作用域C “与”的区别是什么;“文件范围”;及;计划范围“;,c,scope,storage-class-specifier,C,Scope,Storage Class Specifier,全局声明的变量称为具有程序作用域 用static关键字全局声明的变量称为具有文件作用域 例如: int x = 0; // **program scope** static int y = 0; // **file scope** static float z = 0.0; // **file scope** int main() { int i; /* block scope */ /* . .
用static关键字全局声明的变量称为具有文件作用域 例如:
int x = 0; // **program scope**
static int y = 0; // **file scope**
static float z = 0.0; // **file scope**
int main()
{
int i; /* block scope */
/* .
.
.
*/
return 0;
}
这两个程序的区别是什么?C程序可以写在几个文件中,这些文件由链接器合并到最终执行中。如果整个程序都在一个文件中,那么就没有区别了。但在现实世界的复杂软件中,包括在不同文件中使用函数库,这种差异是显著的 声明为
静态的变量
不能从其他文件直接访问。相反,如果在其他文件中声明为extern
,则可以从其他文件中访问非静态的
文件
例如:
富科
福安
main.c
#include "foo.h"
#include <stdio.h>
int main()
{
extern int foodata; /* OK */
extern int foodata_private; /* error, won't compile */
foo();
printf("%d\n", foodata); /* OK */
return 0;
}
#包括“foo.h”
#包括
int main()
{
extern int foodata;/*正常*/
extern int foodata_private;/*错误,无法编译*/
foo();
printf(“%d\n”,foodata);/*确定*/
返回0;
}
一般来说,应该避免全局变量。然而,在实际应用中,这些通常是有用的。移动
extern int foo是很常见的代码>对共享头文件的声明(示例中为foo.h)。具有文件范围的变量仅从其声明点到文件末尾可见。文件是指包含源代码的程序文件。一个大型程序中可以有多个程序文件。
具有程序范围的变量在整个程序的所有文件(不仅在定义它的文件中)、函数和其他块中都可见。
更多信息。检查此项:。在C99中,没有所谓的“程序范围”。在您的示例中,变量x
的文件作用域终止于转换单元的末尾。声明为静态的变量y
和z
也具有文件范围,但具有内部链接
C99(6.2.2/3)如果对象的文件范围标识符的声明
或者函数包含存储类说明符static
标识符具有内部链接
此外,变量x
具有外部链接,这意味着名称x
可以被其他翻译单元或整个程序访问
C99(6.2.2/5),如果对象标识符的声明
文件范围,没有存储类说明符,其链接是外部的
只是一个注释,说x有一个文件作用域,它终止于翻译单元的末尾
(这意味着它只在本单元中可见),并且x可以被其他翻译单元访问
,这在技术上是正确的,但可能有点混淆。(尽管如此,我还是发现维基页面同样令人困惑。问题是“可访问”和“可见”并不相同。(评论太长)在阅读了C99标准之后,我想我有点明白了:假设x有文件范围和外部链接。如果你想在另一个翻译单元中访问x,你也必须在那里声明x。然后因为两个x是链接的,它们指的是同一件事。extern int foodata\u private
将编译,但它不会链接。为什么ot将变量放入头文件中,并在需要时使用它们,而不诉诸任何外部
?@AlexanderCska这通常不是一个好主意。如果该变量不是静态
,它将在包含头文件的每个源代码文件中定义。然后程序可能链接,也可能不链接,这取决于变量是否ble已初始化(有关详细信息,请参阅)。这两种结果几乎都不是您想要的。如果变量是静态的
,它会在每个翻译单元中被定义为一个私有符号。同样,它通常不是您想要的。在模块之间在C中共享全局变量的正确方法是在源代码文件中定义一次变量,并将其声明为外部
然后,包含此头文件的所有源代码文件将正确共享该变量。
void foo();
#include "foo.h"
#include <stdio.h>
int main()
{
extern int foodata; /* OK */
extern int foodata_private; /* error, won't compile */
foo();
printf("%d\n", foodata); /* OK */
return 0;
}