48

我对, 和static变量auto有点困惑。globallocal

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

但是,我也知道一个local变量也一样,那有什么区别呢?

4

6 回答 6

91

这里有两个独立的概念:

  • scope,它确定可以访问名称的位置,以及
  • storage duration,它决定了变量的创建和销毁时间。

局部变量(学究式地,具有块作用域的变量)只能在声明它们的代码块内访问:

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++ 中,情况更加复杂,因为命名空间可以关闭和重新打开,并且可以访问当前范围以外的范围,并且名称也可以具有类范围。但这变得非常离题。)

自动变量(学究式地,具有自动存储持续时间的变量)是局部变量,其生命周期在执行离开其范围时结束,并在重新进入范围时重新创建。

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关键字不再意味着自动存储持续时间;它现在意味着自动类型,从变量的初始化程序推导出来。

于 2012-11-16T11:26:35.477 回答
12

首先我说你应该用谷歌搜索它,因为它在很多地方都有详细定义。

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

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

/* 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 */
}

静态:
静态对象是从构造到程序结束一直存在的对象。因此,堆栈和堆对象被排除在外。但是全局对象、命名空间范围内的对象、在类/函数中声明为静态的对象以及在文件范围内声明的对象都包含在静态对象中。当程序停止运行时,静态对象被销毁。
我建议你看看这个教程列表

AUTO:
C, C++

(称为自动变量。)

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

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

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

于 2012-11-16T11:11:23.753 回答
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;
}
于 2012-11-16T11:18:33.803 回答
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++ 中有所不同。auto在 C 中是一种(多余的)指定局部变量的方法。在 C++11 中,auto现在用于自动派生值/表达式的类型。

于 2012-11-16T11:14:29.273 回答
3

函数终止后,内存中不存在局部变量。
然而,static变量在程序的整个生命周期中仍然分配在内存中,而与任何功能无关。

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

于 2012-11-16T11:09:21.780 回答
2

当一个变量在类中声明为静态时,它将成为该类的所有对象的共享变量,这意味着该变量不再特定于任何对象。例如: -

#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
于 2016-11-25T15:10:34.970 回答