1

我是 C 的初学者,目前正在学习数据类型修订章节。我已经解决了很多静态存储类的程序。静态存储类具有本地范围。在下面的代码中,静态变量在 main 即全局变量之上声明。这可能吗 ?并且根据静态存储类的特点的o/p是正确的。

static int y ;
main( )
{
static int z ;
printf ("%d %d", y, z ) ;
}

任何人都可以让我知道 main 上面的静态变量声明是正确的吗?如果这是正确的,请尝试用外行语言解释。

4

2 回答 2

7

存储类和范围是不同的东西。static关键字不影响范围。

存储类与对象的生命周期或存储持续时间有关:创建时间和生命周期结束时间。不幸的是,由于历史原因,存储类和其他概念有些混合。存储类有一些关于存储位置的含义。C 已经发展,因此关于存储在哪里的决定很大程度上取决于实现。通常,程序员应该只关心什么时候存储。

存储类是对象的属性:被存储的实际事物(值)。范围是标识符的属性:用于引用对象(或类型或函数)的名称。

有四种存储持续时间:静态、线程、自动和分配。作用域有四种:函数、文件、块和函数原型。它们的规则有些复杂(并且还取决于链接,可以是外部的、内部的或无链接),所以我不会全部描述它们。

如果将对象定义为static,则其生命周期就是程序的整个执行过程。默认情况下,在函数体内声明的普通对象具有自动存储期限。它的生命周期是从程序执行进入它所在的块开始,直到程序执行退出它所在的块。每次执行进入块时,都会创建一个对象的新实例。如您所见,生命周期是在程序运行时应用的属性。

当您在函数体内声明对象时,声明中的标识符(名称)具有块范围。该名称仅在块内可见。范围是编译时属性;它会影响源代码的哪些部分可以看到名称。例如,如果您的函数 A 在运行时调用函数 B,则函数 B 看不到函数 A 中的名称。即使函数 A 中的对象在函数 B 执行时存在(运行时属性),它们的名称(编译-time 属性)在函数 B 中不可见。

函数体内的名称具有块作用域,但它可以引用具有自动(块)存储持续时间的对象或具有静态(整个程序)存储持续时间的对象。

当您在函数体之外声明对象时,其标识符具有文件范围。文件中的所有以下源代码都可以看到它。

还有一个属性叫做链接。链接是一种方法,通过该方法可以使不同范围内的相同标识符引用同一对象。(foo可以在一个源文件中引用与foo另一个源文件相同的对象。)

于 2013-06-23T15:48:09.580 回答
3

y是一个全局变量,但由于它是声明static的,它只在编译单元中可见,即同一个 C 文件。如果您正在编译多个对象并将它们链接在一起,它将无法从其他单元访问。在这个简单的示例中,全局变量是否声明为静态无关紧要。

于 2013-06-23T14:15:03.267 回答