c和c ++上下文中static,auto,global和local变量之间的区别

时间:2012-11-16 11:05:15

标签: c++ c variables

我对staticautogloballocal变量感到有些困惑。

在某处我读到static变量只能在函数内访问,但在函数返回后它们仍然存在(保留在内存中)。

但是,我也知道local变量也是一样的,那有什么不同呢?

6 个答案:

答案 0 :(得分:88)

这里有两个不同的概念:

  • 范围,用于确定可以访问名称的位置,以及
  • 存储持续时间,用于确定何时创建和销毁变量。

本地变量(迂腐地,带有块范围的变量)只能在声明它们的代码块中访问:

void f() {
    int i;
    i = 1; // OK: in scope
}
void g() {
    i = 2; // Error: not in scope
}

全局变量(迂腐地,具有文件范围的变量(在C中)或命名空间范围(在C ++中))可随时访问声明后:

int i;
void f() {
    i = 1; // OK: in scope
}
void g() {
    i = 2; // OK: still in scope
}

(在C ++中,情况更复杂,因为命名空间可以被关闭并重新打开,并且可以访问除当前范围之外的范围,并且名称也可以具有类范围。但这非常偏离主题。)

自动变量(迂腐地,自动存储持续时间的变量)是局部变量,其生命周期在执行离开其范围时结束,并在重新输入范围时重新创建。 / p>

for (int i = 0; i < 5; ++i) {
    int n = 0;
    printf("%d ", ++n);  // prints 1 1 1 1 1  - the previous value is lost
}

静态变量(迂腐地,静态存储持续时间的变量)的生命周期一直持续到程序结束。如果它们是局部变量,则当执行离开其范围时,它们的值仍然存在。

for (int i = 0; i < 5; ++i) {
    static int n = 0;
    printf("%d ", ++n);  // prints 1 2 3 4 5  - the value persists
}

请注意,static关键字除了静态存储持续时间外,还有各种含义。在全局变量或函数上,它为其提供内部链接,以便无法从其他翻译单元访问它;在C ++类成员上,这意味着每个类有一个实例,而不是每个对象一个实例。此外,在C ++中,auto关键字不再意味着自动存储持续时间;它现在意味着自动类型,从变量的初始化推断出来。

答案 1 :(得分:11)

首先我要说你应该谷歌这个,因为它在很多地方都有详细定义

本地
这些变量仅存在于创建它们的特定函数内。它们不为其他功能和主程序所知。因此,它们通常使用堆栈来实现。一旦创建它们的函数完成,局部变量就不再存在。每次执行或调用函数时都会重新创建它们。

全球
这些变量可以由包括程序的任何功能访问(即已知)。它们通过将内存位置与变量名称相关联来实现。如果调用该函数,则不会重新创建它们。

/* Demonstrating Global variables  */
    #include <stdio.h>
    int add_numbers( void );                /* ANSI function prototype */

    /* These are global variables and can be accessed by functions from this point on */
    int  value1, value2, value3;

    int add_numbers( void )
    {
        auto int result;
        result = value1 + value2 + value3;
        return result;
    }

    main()
    {
        auto int result;
        value1 = 10;
        value2 = 20;
        value3 = 30;        
        result = add_numbers();
        printf("The sum of %d + %d + %d is %d\n",
            value1, value2, value3, final_result);
    }


    Sample Program Output
    The sum of 10 + 20 + 30 is 60

可以通过仔细放置声明来限制全局变量的范围。它们从声明中可见,直到当前源文件结束。

#include <stdio.h>
void no_access( void ); /* ANSI function prototype */
void all_access( void );

static int n2;      /* n2 is known from this point onwards */

void no_access( void )
{
    n1 = 10;        /* illegal, n1 not yet known */
    n2 = 5;         /* valid */
}

static int n1;      /* n1 is known from this point onwards */

void all_access( void )
{
    n1 = 10;        /* valid */
    n2 = 3;         /* valid */
}

静态:
静态对象是一个从构造到程序结束时持续存在的对象。因此,排除了堆栈和堆对象。但是全局对象,命名空间范围内的对象,在类/函数内声明为静态的对象以及在文件范围内声明的对象都包含在静态对象中。程序停止运行时会破坏静态对象。
我建议您see this tutorial list

AUTO:
C,C ++

(称为自动变量。)

默认情况下,代码块中声明的所有变量都是自动的,但这可以使用auto关键字显式。[注1]未初始化的自动变量具有未定义的值,直到为其分配了有效的类型值。 [1]

使用存储类寄存器而不是auto是编译器将变量缓存在处理器寄存器中的提示。除了不允许在变量或其任何子组件上使用引用运算符(&amp;)之外,编译器可以自由地忽略该提示。

在C ++中,当执行到达声明位置时,将调用自动变量的构造函数。析构函数在到达给定程序块的末尾时被调用(程序块被大括号括起来)。此功能通常用于管理资源分配和解除分配,例如打开然后自动关闭文件或释放内存。SEE WIKIPEDIA

答案 2 :(得分:4)

差异是静态变量是那些变量:它允许从函数的一次调用到另一次调用保留一个值。 但是在局部变量的情况下,范围是块/函数寿命。

例如:

#include <stdio.h>

void func() {
    static int x = 0; // x is initialized only once across three calls of func()
    printf("%d\n", x); // outputs the value of x
    x = x + 1;
}

int main(int argc, char * const argv[]) {
    func(); // prints 0
    func(); // prints 1
    func(); // prints 2
    return 0;
}

答案 3 :(得分:3)

函数终止后,内存中的局部变量不存在 但是,无论函数是什么,static个变量在程序的整个生命周期内都会被分配

除了您的问题,static变量可以在class或函数范围内本地声明,在namespace或文件范围内全局声明。它们从头到尾分配了内存,它只是迟早会发生的初始化。

答案 4 :(得分:3)

static是C和C ++中严重超载的单词。函数上下文中的static变量是在调用之间保持其值的变量。它们在程序期间存在。

局部变量仅在函数的生命周期或其封闭范围内持续存在。例如:

void foo()
{
    int i, j, k;
    //initialize, do stuff
} //i, j, k fall out of scope, no longer exist

有时,这个范围用于{ }块:

{ 
   int i, j, k;
   //...
} //i, j, k now out of scope

在程序期间存在全局变量。

auto现在在C和C ++中有所不同。 C中的auto是一种指定局部变量的(多余的)方式。在C ++ 11中,auto现在用于自动派生值/表达式的类型。

答案 5 :(得分:2)

当变量在类中声明为static时,它将成为该类的所有对象的共享变量,这意味着该变量对于任何对象都更长。 例如: -

#include<iostream.h>
#include<conio.h>
class test
{
    void fun()
    {
        static int a=0;
        a++;
        cout<<"Value of a = "<<a<<"\n";
    }
};
void main()
{
    clrscr();
    test obj1;
    test obj2;
    test obj3;
    obj1.fun();
    obj2.fun();
    obj3.fun();
    getch();
}

该程序将生成以下输出: -

Value of a = 1
Value of a = 2
Value of a = 3

全局声明的静态变量也是如此。如果我们将变量声明为外部函数void fun()

,上面的代码将生成相同的输出

如果你删除关键字static并将a声明为非静态本地/全局变量,那么输出将如下: -

Value of a = 1
Value of a = 1
Value of a = 1