变量储存持续性、作用域和链接性

本文深入解析静态持续变量的三种链接性:外部、内部与无链接性。探讨了单定义规则,以及如何通过static限定符控制变量的访问范围,特别是在代码块内外的声明差异。并提供了一个静态局部变量的例子,展示其在函数调用间保持状态的特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

静态持续变量

  静态持续变量3种链接性:外部链接性(可在其他文件中访问)、内部链接性(只能在当前文件中访问)、无链接性(只能在当前函数或代码中访问)。
  要想创建链接性为外部或内部的静态持续变量,必须在代码块外面声明它,要创建没有链接性的静态持续变量,必须在代码块内声明它

外部链接性

1.单定义规则
  变量只能有一次定义,c++提供了两种变量声明,一种是定义声明(defining declaration)或简称为定义(definition),它会给变量分配储存空间;
  另一种是引用声明(referencing declaration)或简称为声明(declaration),它不给变量分配储存空间,因为它引用已有的变量。
引用声明使用关键字extern

// file01.cpp
extern int cats = 20;
int dogs = 22;
int fleas;

//flie02.cpp
extern int cats;
extern int dogs;

内部链接性

  将static 限定符用于作用域为整个文件的变量时,该变量的链接性将为内部的。 链接性为内部的变量只能在其所属的文件中使用;但常规外部变量都具有外部链接性,即可以在其他文件中使用。

//file01
int errors = 20;

//file02
int errors = 5;
void froo()
{

这种情况会失败



但是下面这种情况就可以
//file01
int errors = 20;

//file02
int errors = 5;
std::cout << errors;
//输出为5

无链接性

  将static限定符用于在代码块中定义的变量。
  这意味着虽然该变量只在该代码块中可用,但它在该代码块不处于活动状态时仍然存在,因此在两次函数调用之间,静态局部变量的值将保持不变。
  例子:

#include<iostream>
const int ArSize = 10;
void strcout(const char* str);
int main()
{
        using namespace std;
        char input[ArSize];
        cout << "Enter a line:";
        while (cin.getline(input, ArSize))
        {
               strcout(input);
               cout << "again:";
        }
        cout << "end";
        return 0;
}
void strcout(const char* str)
{
        using namespace std;
        static int total = 0;
        int count = 0;
        cout << str;
        while (*str++)
               count++;
        total += count;
        cout  <<  "    contain: "<< count << "       characters     "
               <<total << "   total char     " << endl;
}
### 变量作用域与生命周期的概念 #### 定义 变量作用域定义了该变量可以在哪些部分的代码中访问。不同的编程语言有不同的机制来决定变量作用域,但在大多数情况下,可以分为全局作用域、局部作用域以及块级作用域。 - **全局作用域**:在整个程序范围内都可以访问这些变量[^1]。 - **局部作用域**:仅限于特定函数内部使用的变量,在此函数外部无法直接访问它们。 - **块级作用域**:当涉及到更细粒度控制时,某些语言允许通过大括号 `{}` 或者其他方式定义一个新层次的作用域;这种情况下创建出来的就是所谓的“块级”作用域内的变量。 对于 Python 来说,还存在一种特殊的查找顺序用于解析未限定名称的空间,即按照 LEGB 规则(Local, Enclosing, Global Built-in),依次检查本地命名空间、封闭函数中的任何嵌套作用域、文件级别的全局命名空间最后才是内置命名空间[^3]。 #### 生命周期 另一方面,“生命周期”指的是对象自诞生至消亡所经历的过程。具体来说: - 对于 C++声明为 `static` 的静态局部变量而言,虽然其可见仍然局限于单个函数体内,但是它的生存期却贯穿整个应用程序运行期间,并且只会在第一次调用相应位置处执行初始化操作[^4]。 - 非静态类型的局部实体通常是在每次进入对应过程体之后才建立起来并分配内存资源给它自己使用直到退出为止才会释放掉这部分存储单元。 因此可以看出,两者之间存在着紧密联系却又互不相同之处——前者决定了某个名字能在多大的范围内有效识别出来而后者则是关于实际数据结构存在于计算机系统里的持续时间长短问题。 ```cpp // 示例展示C++中不同类型的变量及其生命周期差异 #include <iostream> using namespace std; void func() { int local_var = 0; // 局部自动变量,每次调用func都会重新创建销毁 static int stat_local = 0;// 静态局部变量,首次调用func时创建,后续保持不变直至程序结束 cout << "local_var: " << ++local_var << endl; cout << "stat_local: " << ++stat_local << endl; } int main(){ for(int i=0;i<5;++i){ func(); } } ``` ```python # Python例子说明普通局部变量vs带有闭包特的自由变量之间的区别 def outer(): x = 'outer_x' # 外层函数中的局部变量 def inner(): nonlocal x # 使用nonlocal关键字改变外层变量x的行为模式 y = 'inner_y' print(x,y) return inner # 返回内层函数作为结果的一部分返回出去形成闭包环境 closure_example = outer() closure_example() # 调用闭包实例会打印出两个字符串值表示内外两重作用域下的同名标识符状态 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值