c和c++上下文中静态、自动、全局和局部变量之间的差异

Difference between static, auto, global and local variable in the context of c and c++

本文关键字:之间 局部变量 全局 自动 上下文 静态 c++      更新时间:2023-10-16

我对staticautogloballocal变量有点困惑。

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

然而,我也知道local变量也有同样的作用,那么有什么区别呢?

这里有两个独立的概念:

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

本地变量(实际上,具有块范围的变量)只能在声明它们的代码块中访问:

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

首先我要说的是,你应该用谷歌搜索它,因为它在很多地方都有详细的定义
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 %dn",
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 */
}

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

自动:
C,C++

(称为自动变量。)

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

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

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

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

例如:

函数终止后,
#include <stdio.h>
void func() {
static int x = 0; // x is initialized only once across three calls of func()
printf("%dn", 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;
}

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

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

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

程序期间存在全局变量。

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

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

#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