Skip to content

简单变量的生命周期与作用域


静态内存分配声明关键字所创建的简单变量的生命周期,及其与作用域的关系。

前言:

  • 变量的生命周期是指变量拥有有效内存的时间段(而作用域是指程序中变量名可见的部分)。变量的值在其生命周期内可以改变,但始终保持某个一致的值。
  • 本文所讨论的简单变量包括:预定义变量、原始指针、固定长度字符串/数组,但不包括可变长度字符串/数组。不含任何动态分配数据的简单 UDT 实例也在讨论范围之内。
  • 用于静态内存分配的声明关键字有:DimStaticVar

对于以上述方式静态分配的变量,其生命周期通常与其所在作用域一致,但也可以大于该作用域。

生命周期与所在作用域一致的声明语法

对于在任何位置按如下语法(或类似语法)声明的变量:

(1)Dim Shared As datatype [Ptr] variablename ...

or

(2)Var Shared variablename = expression

(等价于: 'Dim Shared As Typeof((expression)) = expression')

or

(3){Dim|Static} Shared As datatype [Ptr] variablename ...

or

(4)[Static] Var Shared variablename = expression

(等价于: '{Dim|Static} Shared As Typeof((expression)) = expression')

or

(5)Common [Shared] As datatype [Ptr] variablename

这些变量的生命周期始终与其所在作用域一致(全局作用域、作用域块、复合语句块或过程作用域)。

使用语法 (1)(2) 时,局部变量在声明时始终被分配在程序栈上,并在离开其作用域时自动释放。

使用语法 (3)(4)(5) 时,全局变量始终被分配在可执行文件的 .BSS.DATA 段中(其作用域和生命周期从程序创建时开始,直到程序终止结束)。

生命周期可能大于所在作用域的声明语法

对于在任何位置按如下语法(或类似语法)声明的变量:

Static Shared As datatype [Ptr] variablename ...

Static Var Shared variablename = expression

这些变量的生命周期始终等于程序运行时长。若在任何局部作用域块中声明,其生命周期将大于其所在作用域;若在全局作用域中声明,则与其所在作用域一致。

静态变量始终被分配在可执行文件的 .BSS.DATA 段中(其生命周期从程序创建时开始,直到程序终止结束)。

在复合指令块或过程作用域中声明此类静态变量的意义:

  • Dim 相同,Static 关键字用于在复合语句块或过程作用域中声明变量,这些变量的作用域在复合语句块或过程结束时终止。

  • 然而,与 Dim 不同的是,其生命周期有所不同——用 Static 关键字声明的变量在复合指令块的连续循环或对过程的连续调用之间保留其值

  • 总结来说,声明为 Static 的变量具有局部作用域,但其生命周期与全局作用域变量相当。

  • 因此,可以在多个不同的复合语句块和不同的过程作用域中声明同名的静态变量,每个变量保持独立,并在各自的局部作用域中保留自己的值。

示例

在局部作用域中声明的不同变量之间的生命周期比较:

在过程作用域中声明的局部变量 vs. 静态变量

vb
Dim Shared As ZString Ptr pzl ' 全局变量,用于记录局部 Zstring 的地址
Dim Shared As ZString Ptr pzs ' 全局变量,用于记录静态 Zstring 的地址

Declare Sub prntSubString (ByVal p As ZString Ptr, ByVal size As Integer)

Sub s ()                                          ' 过程作用域开始
    Dim As ZString * 15 zl = "local variable"     ' 声明/初始化一个局部 Zstring
    pzl = @zl                                     ' 记录局部 Zstring 的地址
     
    Static As ZString * 16 zs = "static variable" ' 声明/初始化一个静态 Zstring
    pzs = @zs                                     ' 记录静态 Zstring 的地址
     
    Print "     From inside the procedure scope:"
    prntSubString(pzl, 14)                        ' 显示局部 zstring 的地址/内容
    prntSubString(pzs, 15)                        ' 显示静态 zstring 的地址/内容
End Sub                                           ' 过程作用域结束

Print "Lifetimes comparison between local/static variables declared in a local scope:"
s() ' 调用过程

Print "     From outside the procedure scope:"
prntSubString(pzl, 14) ' 离开局部作用域后显示局部 zstring 的地址/内容
prntSubString(pzs, 15) ' 离开局部作用域后显示静态 zstring 的地址/内容

Sleep

Sub prntSubString (ByVal p As ZString Ptr, ByVal size As Integer)
    Print , "&h" & Hex(p, SizeOf(Any Ptr) * 2),
    Print """";
    For I As Integer = 0 To size - 1
        Dim As UByte u = (*p)[I]
        If u < Asc(" ") Then
            Print " ";
        Else
            Print Chr(u);
        End If
    Next I
    Print """"
End Sub

输出示例:

Lifetimes comparison between local/static variables declared in a local scope:
 From inside the procedure scope:
  &h0019FE74    "local variable"
  &h00407004    "static variable"
 From outside the procedure scope:
  &h0019FE74    " p@ Çp@ ¿■  Y "
  &h00407004    "static variable"

参见

返回 目录

基于 FreeBASIC 官方文档翻译 如有侵权请联系我们删除
FreeBASIC 是开源项目,与微软公司无隶属关系