C语言中变量的作用域与生命周期

7

请问有人能准确地解释C语言中变量的作用域和生命周期概念吗?在C++中是否不同?我对作用域和生命周期之间的区别感到困惑。

4个回答

22

"作用域"指的是变量可以被引用的源代码区域。

"生命周期"指的是变量在程序执行期间存在的时间长短。

默认情况下,局部变量的生命周期与其作用域相同:

void foo()
{
    int x = 123;
    cout << x << endl;
    x += 1;
}

int main(){ foo(); foo(); foo(); }

每次调用foo时,都会创建一个新的x(在栈上为其保留空间),当执行离开声明x的块时,x将被销毁(对于int来说,这意味着被保留的空间现在可以被重新使用)。

相比之下:

void foo()
{
    static int x = 123;
    cout << x << endl;
    x += 1;
}

int main(){ foo(); foo(); foo(); }

由于在声明 x 时使用了 static 关键字,所以在程序执行之前就为 x 分配了空间。 x 在内存中具有固定的位置,它是一个 静态变量。C++ 对这种变量的初始化有特殊的规定:初始化发生在第一次通过声明时执行。

因此,在第一次调用 foo 时,将初始化该 x,输出语句显示 123,并且增量将值增加 1。在下一次调用中,初始化将被跳过(已经执行过),输出值为 124,并且再次递增。如此往复。

x 的生命周期从执行开始到执行结束。


5

作用域是变量可访问的区域。
生命周期是对象保持有效的时间跨度。

一个简单的例子:

#include <iostream.h>

void doSomething()
{
    x = 5; //Error! Not Accessible
}

int main() 
{

      int x = 4;
      std::cout<< x << endl;
      {
            int x = 2;
            cout << x << endl;
      }
      doSomething(); 
      std::cout<< x << endl;
      return 0;
}

上述程序的输出结果为:
``` 4 2 4 ```
在以上程序中,变量`x=4`的生命周期始终是在`main`函数中,即它在整个`main`函数执行期间都是有效的,并且它在`main`函数内是可访问的,也就是说它的作用域是在`main`函数中。请注意,因为变量`x`的范围超出了变量`x`的范围,所以它不能在函数中访问。
而变量`x=2`的作用域和生命周期仅限于`main`函数中的大括号`{}`内部。

“Remains valid” 意味着 “仍在使用” 吗?这会对变量的作用域有何影响? - Sandip Agarwal
@R.MartinhoFernandes:嗯,谈论变量的生命周期并不是错误的,因为变量是一个对象。据我回忆,标准将变量定义为命名对象。然而,我现在可能讲得没有意义,可能是因为某些SO历史修订删除了您评论的原始上下文? - Cheers and hth. - Alf
1
继续Alf的评论:变量是符号(名称)和对象的关联。生命周期涉及对象(仅涉及对象);作用域涉及符号(仅涉及符号)。 - James Kanze

0

变量的作用域在编译时确定。它是程序中定义相同对象的区域,可以通过该标识符访问。

对象的生命周期是在运行时通过执行流定义的特性。即使定义它的变量不在作用域内,也可以通过指针访问对象。

void f(char *a) {
  *a = 'f';
}

void g(void) {
   char aChar = ' ';
   f(&aChar);
}

这里变量aChar(标识符)的作用域是g的主体。在执行g时,对象的生命周期扩展到执行f。在f中使用标识符aChar将是非法的,编译器会告诉您类似于“函数f中未知的标识符aChar”。像上面那样使用指向该对象的指针是完全合法的。


-1
变量的作用域是指程序的不同部分可以访问该变量的范围。变量可以声明为:
  • 在一个函数内部,这被称为局部变量或内部变量。

  • 在所有函数之外,这被称为全局变量或外部变量,其生命周期或“范围”跨越整个程序运行。

这里有关于变量的详细教程和示例:C语言中的变量是什么?


那么关于作用域和生命周期的问题呢? - J0e3gan
作用域 - 定义程序中哪些部分可以访问变量 生命周期 - 定义变量何时被创建和销毁 - Sandeep Saini

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接