C++(一)——存储持续性、作用域、链接性

存储持续性、作用域、链接性

  • 自动存储持续性:在函数定义中声明的变量(包括函数参数)的存储持续性为自动的。它们在程序开始执行其所属的函数或代码块时被创建,在执行完函数或代码块时,它们使用的内存被释放。C++有两种存储持续性为自动的变量。
  • 静态存储持续性:在函数定义外定义的变量使用关键字static定义的变量的存储持续性都为静态。它们在程序整个运行过程中都存在。C+ +有3种存储持续性为静态的变量。线程存储持续(C++11) :当前,多核处理器很常见,这些CPU可同时处理多个执行任务。这让程序能够将计算放在可并行处理的不同线程中。如果变量是使用关键字thread_ local声明的 ,则其生命周期与所属的线程一样长。
  • 动态存储持续性:用new运算符分配的内存将一直存在, 直 到使用delete运算符将其释放或程序结束为止。这种内存的存储持续性为动态,有时被称为自由存储( free store )或堆( heap )

1.自动存储持续性

1.1.自动变量的初始化

1.2.自动变量和栈

        了解典型的C+ +编译器如何实现自动变量有助于更深入地了解自动变量。由于自动变量的数目随函数的开始和结束而增减,因此程序必须在运行时对自动变量进行管理。常用的方法是留出一段内存,并将其视为栈,以管理变量的增减。之所以被称为栈,是由于新数据被象征性地放在原有数据的上面(也就是说,在相邻的内存单元中,而不是在同一个内存单元中) ,当程序使用完后,将其从栈中删除。栈的默认长度取决于实现,但编译器通常提供改变栈长度的选项。程序使用两个指针来跟踪栈,一个指针指向栈底一栈的开始位置,另一个指针指向堆项 下一 个可用内存单元。当函数被调用时,其自动变量将被加入到栈中,栈顶指针指向变量后面的下一个可用的内存单元。函数结束时,栈顶指针被重置为函数被调用前的值,从而释放新变量使用的内存。

        栈是LIFO (后进先出)的,即最后加入到栈中的变量首先被弹出。这种设计简化了参数传递。函数调用将其参数的值放在栈顶,然后重新设置栈顶指针。被调用的函数根据其形参描述来确定每个参数的地址。

1.3.寄存器变量

2.静态持续变量

        和C语言一样,C++也为静态存储持续性变量提供了3种链接性:外部链接性(可在其他文件中访问)、内部链接性(只能在当前文件中访问)和无链接性(只能在当前函数或代码块中访问)。这3种链接性都在整个程序执行期间存在,与自动变量相比,它们的寿命更长。由于静态变量的数目在程序运行期间是不变的,因此程序不需要使用特殊的装置(如栈)来管理它们。编译器将分配固定的内存块来存储所有的静态变量,这些变量在整个程序执行期间一直存在。另外,如果没有显式地初始化静态变量,编译器将把它设置为0。在默认情况下,静态数组和结构将每个元素或成员的所有位都设置为0。

例子 

        正如前面指出的,所有静态持续变量(上述示例中的global、one_ file和count )在整个程序执行期间都存在。在funct1()中声 明的变量count的作用域为局部,没有链接性,这意味着只能在funct1()函数中使用它,就像自动变量lam一样。然而,与llama不同的是,即使在funct1()函数没有被执行时,count也留在内存中global和one_ file的作用 域都为整个文件,即在从声明位置到文件结尾的范围内都可以被使用。具体地说,可以在main(、funct1()和funct2()中使用它们。 由于one_ file的链接性为内部,因此只能在包含上述代码的文件中使用它;由于global的链接性为外部,因此可以在程序的其他文件中使用它。

5种变量存储方式 

3.静态持续性,外部链接性

        链接性为外部的变量通常简称为外部变量,它们的存储持续性为静态,作用域为整个文件。外部变量是在函数外部定义的,因此对所有函数而言都是外部的。例如,可以在main()前面或头文件中定义它们。可以在文件中位于外部变量定义后面的任何函数中使用它,因此外部变量也称全局变量( 相对于局部的自动变量)。

3.1单定义规则

3.2 全局变量和局部变量

        既然可以选择使用全局变量或局部变量,那么到底应使用哪种呢?首先,全局变量很有吸引力,因为所有的函数能访问全局变量,因此不用传递参数。但易于访问的代价很大——程序不可靠。 计算经验表明,程序越能避免对数据进行不必要的访问,就越能保持数据的完整性。通常情况下,应使用局部变量,应在需要知晓时才传递数据,而不应不加区分地使用全局变量来使数据可用。读者将会看到,OOP在数据隔离方面又向前迈进了一步。然而,全局变量也有它们的用处。例如,可以让多个函数可以使用同一一个数据块(如月份名数组或原子量数组)。外部存储尤其适于表示常量数据,因为这样可以使用关键字const来防止数据被修改。

4.静态持续性,内部链接性

        将static限定符用于作用域为整个文件的变量时,该变量的链接性将为内部的。在多文件程序中,内部链接性和外部链接性之间的差别很有意义。链接性为内部的变量只能在其所属的文件中使用;但常规外部变量都具有外部链接性,即可以在其他文件中使用如前面的示例所示。

注意:在多文件程序中,可以在一个文件(且只能在一一个文件)中定义一个外部变量。使用该变量的其他文件必须使用关键字extern声明它。 

正确示例

 两个程序的输出

 5.静态存储持续性,无链接性

        至此,介绍了链接性分别为内部和外部、作用域为整个文件的变量。接下来介绍静态持续家族中的第三个成员——无链接性的局部变量。 这种变量是这样创建的,将static限定符用于在代码块中定义的变量。在代码块中使用static时,将导致局部变量的存储持续性为静态的。这意味着虽然该变量只在该代码块中可用,但它在该代码块不处于活动状态时仍然存在。因此在两次函数调用之间,静态局部变量的值将保持不变。另外,如果初始化了静态局部变量,则程序只在启动时进行一次初始化。以后再调用函数时,将不会像自动变量那样再次被初始化。

 6.函数和链接性

        和变量一样,函数也有链接性,虽然可选择的范围比变量小。和C语言一样,C++不允许在个函数中定义另外一一个函数因此所有函数的存储持续性都自动为静态的,即在整个程序执行期间都一直存在。默认情况下,函数的链接性为外部的,即可以在文件间共享。实际上,可以在函数原型中使用关键字extern来指出函数是在另一个文件中定义的,不过这是可选的(要让程序在另一个文件中查找函数,该文件必须作为程序的组成部分被编译,或者是由链接程序搜索的库文件)。还可以使用关键字static将函数的链接性设置为内部的,使之只能在一个文件中使用。必须同时在原型和函数定义中使用该关键字:

         这意味着该函数只在这个文件中可见,还意味着可以在其他文件中定义同名的的函数。和变量一样,在定义静态函数的文件中,静态函数将覆盖外部定义,因此即使在外部定义了同名的函数,该文件仍将使用静态函数。

        单定义规则也适用于非内联函数,因此对于每个非内联函数,程序只能包含一一个定义。对于链接性为外部的函数来说,这意味着在多文件程序中,只能有一个文件 (该文件可能是库文件 ,而不是您提供的 )包含该函数的定义,但使用该函数的每个文件都应包含其函数原型。


        内联函数不受这项规则的约束,这允许程序员能够将内联函数的定义放在头文件中。这样,包含了头文件的每个文件都有内联函数的定义。然而,C++要求同一个函数的所有内联定义都必须相同。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值