当前课程知识点:C++语言程序设计基础 > 第5章 数据的共享与保护 > 对象的生存期 > 对象的生存期
对象的生存期
这种生存期与程序的运行期相同。
在文件作用域中声明的对象具有这种生存期。
在函数内部声明静态生存期对象,要冠以关键字static 。
块作用域中声明的,没有用static修饰的对象是动态生存期的对象(习惯称局部生存期对象)。
开始于程序执行到声明点时,结束于命名该标识符的作用域结束处。
#include<iostream>
using namespace std;
int i = 1; // i 为全局变量,具有静态生存期。
void other() {
static int a = 2;
static int b;
// a,b为静态局部变量,具有全局寿命,局部可见。
//只第一次进入函数时被初始化。
int c = 10; // C为局部变量,具有动态生存期,
//每次进入函数时都初始化。
a += 2; i += 32; c += 5;
cout<<"---OTHER---\n";
cout<<" i: "<<i<<" a: "<<a<<" b: "<<b<<" c: "<<c<<endl;
b = a;
}
int main() {
static int a;//静态局部变量,有全局寿命,局部可见。
int b = -10; // b, c为局部变量,具有动态生存期。
int c = 0;
cout << "---MAIN---\n";
cout<<" i: "<<i<<" a: "<<a<<" b: "<<b<<" c: "<<c<<endl;
c += 8; other();
cout<<"---MAIN---\n";
cout<<" i: "<<i<<" a: "<<a<<" b: "<<b<<" c: "<<c<<endl;
i += 10; other();
return 0;
}
例5-2(续)
运行结果:
---MAIN---
i: 1 a: 0 b: -10 c: 0
---OTHER---
i: 33 a: 4 b: 0 c: 15
---MAIN---
i: 33 a: 0 b: -10 c: 8
---OTHER---
i: 75 a: 6 b: 4 c: 15
大家好
欢迎回来继续学习
C++语言程序设计
这一节
我们来学习对象的生存期
对象的生存期
就是从对象的诞生开始
到它的寿命结束的这段时间
叫做对象的生存期
在C++程序中呢
对象和变量
它们的生存期都分成静态生存期
和动态生存期
所谓静态生存期呢
就是说它的生存期
跟程序的整个运行期间是一致的
比如说具有文件作用域的标识符
变量名 对象名
它都具有静态生存期
只有当你整个程序
运行结束的时候
它才消失
另外就是
如果在函数体内部定义一个变量
定义一个对象
那么在定义的时候
你前面加一个static修饰
它也就具有静态生存期了
它虽然是局部变量 局部对象
虽然它的作用域
在函数体这个局部范围之内
但是在整个程序的运行期间
它都是生存着的
具有静态生存期的对象变量
它会保有它的值
在整个程序运行期间
它的值都不会被破坏
除非你要重新赋给它新值
或者说你改变它的状态
那么它当然会改变
如果你不想做任何
主动的修改的话
在静态生存期的变量
和对象中的值
它都是一直存续着的
那另一种生存期就是动态生存期
动态生存期
开始于它声明的点 定义的点
结束于紧紧包围着它的
最内层的这个模块结束的地方
比如说我们在函数体里面
定义的非静态的对象和变量
都是具有这种动态生存期的
动态生存期的变量对象呢
它也是在
它的生存寿命的范围之内
会很好的保存着
你放到它里面的值
如果你不再写程序
去刻意改变这个值
曾经你存入的它就一直保存着
但是你一旦离开
它这个作用域
它的值就消亡了
这是静态生存期和动态生存期
它们的差别
静态生存期的变量
即使当程序的执行流程
离开了这个变量
这个对象的作用域
其中的值也还都保存着
下回有机会
再回到这个作用域来的时候
又能找得回上次离开之前
它最后存的是什么
能找得到
而动态生存期的变量和对象呢
当执行流程
离开它的作用域范围的时候
它的生存期也就结束了
内存单元释放了
下一回如果执行流程
又再次进入这个范围的话
那么这些动态生存期的对象
会再一次被重新分配内存空间
需要的话它会重新进行初始化
接下来呢
我们通过一个例子
大家来体会一下静态生存期
和动态生存期它们的不同
这个例题呢
我们用它来演示变量的生存期
与可见性
我们看到在所有函数之外呢
定义了一个全局变量i
然后接下来我们看到
这是一个函数other
在这个函数中
定义了两个局部变量a和b
不过这两个局部变量
它都是静态变量
我们知道静态局部变量
它是具有全局的寿命
局部的可见性
什么意思呢
也就是说这两个局部变量
它一直生存着
你即使离开这个other函数
它所占用的存储空间
也不会被释放
它里面的值也不会被破坏
等下一次
重新进入other函数的时候
它原来存在里面的值
依然是有效的
所以像我们这里写的这个初始化
把a初始化成2
这种初始化只在第一次
进入函数的时候执行
等第二次再调用这个函数的时候
就不会再会对它进行初始化了
接下来看这个other函数里面
还有个局部变量c
这是非静态的局部变量
这种局部变量呢
每次当你离开它的作用域
也就是离开这个other函数的时候
它本身就消亡了
它所占用的内存空间就都释放了
里面的值也就无效了
所以等下一次
再进入other函数的时候
这种初始化还会被执行一次
好 那在这个other函数里面
做了一些什么操作呢
我们分别对a c和i
进行了一个加法运算
把2加到变量a里面
将32加到全局变量i里面
将5加到变量c里面
接下来呢
在这儿输出一下各个变量的值
也就是给我们看一下
验证一下
最后在马上就要结束这个函数
要离开这个函数的时候呢
将a的值赋给变量b
好 就用这种状态
离开这个函数了
那我们刚才讲了
即使离开了这个other函数
a和b并不消失
在函数之外我们看不见它了
但是它里面的值应该都
好好地保存着呢
再看主函数
在主函数中呢
也定义了变量名a b c
当然这个例题就是为了演示
大家如果写程序的话
虽然在不同函数中
定义的局部变量
它的作用域是不一样的
互相不会干扰
但是尽量不要用重名的变量
自己看的时候会觉得混乱
那么这个例子
故意定义成这种重名的
给大家演示一下
各自的作用域是什么
好 那这个主函数中的变量a呢
也是个静态变量
它也是具有全局的寿命
局部的作用域
当然主函数中的变量
它是不是全局的寿命
大家仅仅从程序运行状态来说
运行的输出结果来说
也不太看得出来
因为毕竟主函数一结束了
整个程序都结束了
所有变量的空间都是要释放的
那么主函数没有结束呢
它自己的局部变量
非静态局部变量空间
也不会释放
所以仅仅从运行结果呢
不太区分得出来
这里的a和b和c
它们有什么不同
实际上它们存储的区域的位置
是不一样的
好 那再看b和c
这是两个非静态的局部变量
动态的变量
它是局部寿命
也是局部的生存期
也叫动态生存期
好 这些变量定义了
a没有初始化
静态变量不初始化
它的值默认是什么
应该默认是0
然后b和c都有初始化
接下来呢
我们在这里输出一下
变量i和a b c的值
那么这个i是什么呢
是哪里的变量呢
i就是在这儿定义的这个全局变量
它的初始状态值是1
所以这个输出i的值 a的值
b的值
还有c的值
我们看输出呢
i是1 a默认的值是0
b被初始化为-10
c被初始化为0 是这种状态
接下来我把8加到c里面去
c等于c+8
好 加完了以后
这些主函数的局部变量的状态
就是暂时就这个样
马上进入到子函数other里面去
进入到other里面以后
大家看 第一次进入other
要给other它的局部变量a
初始化为2
它的局部变量b没有初始化
那静态的局部变量没有初始化呢
默认的初始值是0
而c初始化为10
接下来将2加到a里面去
a变成a+2
32加到i里面 i等于i加32
5加到c里面
然后再输出验证一下
目前在other函数里面
i a b c
它们的值分别都是几
我们看到在other函数里面
i的值现在是33
然后other的局部变量
a b c的值
分别是4 0 15
注意它不是当初主函数里面
那个a b c
是other函数自己的局部变量
a b c
好 输出完了以后呢
我们来看继续将a的值赋给b
a的值这时候是4
所以把4这个值赋到b里面了
所以这一次离开这个函数之前
最后的状态是
a里面是4 b里面也是4
离开这个函数以后
就回到了主函数中
回到了主函数中
我们再输出一下
i a b c
验证一下
看看当初我们进入other函数之前
主函数里面的a b c
还有全局变量i的值
目前怎么样了
是不是还是在原来的状态
看看输出结果
主函数里面的局部变量
a b c的值都没有变化
c在这个地方给它加了一个8
原来是0 加了个8
也是进入other以前的状态
保持着
a b c状态都保持着 没有变
那就说明我们进到other函数以后
对变量a b c
做了那些操作呢
都是other的局部变量
跟主函数里面的变量
真的完全不相干
但是i呢我们就看到
不管在主函数中访问的i
还是在other函数中访问i
访问的都是这个全局变量i
所以在other函数中
对i进行了操作
回到主函数中
依然看得见这个效果
它现在是33
接下来
我们再进行一次验证
在主函数中
给i再加10
然后再次进到other函数中
这一次进到other函数中
静态变量a
就不会再被初始化了
而且呢
虽然刚才离开other函数以后
在主函数中
你再也看不见
other函数的局部变量a b c了
只能看见主函数的局部变量
a b c
但是other函数里面
定义的局部变量a b c
丢没丢呢
a和b都没有丢
因为它是静态的
静态是具有全局寿命的
只要整个程序没有运行完
a和b这两个静态变量
它们里面的值
就始终是安全存放在那儿的
不会破坏掉
所以上一回离开other的时候
a是4 b也是4
那现在应该还是这种状态
c它是动态生存期的变量
局部变量
所以离开other的时候
c本身就消亡了
它曾经占用的空间就释放了
这一次
第二次进到other里面
会给c重新分配内存空间
重新初始化为10
接下来我们来看看
验证一下这个效果
那么这时候把2再加到a上面去
然后i呢
刚才离开的时候是33
回到主函数里面又给它加了10
现在再给它加32上去
c是在这一次
新的初始化为10的基础上
再加5
然后我们输出验证一下
结果是什么
我们看一下输出结果
你看 i的值现在变成75了
也就是说
不管在主函数中
还是other函数中
每一次对i的操作
一直都积累在这儿
因为它是全局变量
它一直是持续有效的
other里面这个a呢
在上一次离开的时候是4
现在又加了2 它变成6了
b在上一次离开的时候是4
这一回没有对它进行
更多的赋值和操作
这个4还保留在这儿
而c重新变成了15
初始化成10 又加了5
重新变成了15
那么通过这个例子呢
我们就看到
全局变量 局部变量
静态变量 动态变量
它们的生存期
与可见性的这种特点
-导学
--第1章导学
-计算机系统简介
--计算机系统简介
--计算机系统简介 测试题
-计算机语言和程序设计方法的发展
--计算机语言和程序设计方法的发展 测试题
-面向对象的基本概念
--面向对象的基本概念 测试题
-程序的开发过程
--程序的开发过程
--程序的开发过程 测试题
-信息的表示和储存
--计算机的数字系统
--数据的编码表示
--信息的表示和储存 测试题
-实验指导
-导学
--第二章导学
-C++语言概述
--C++语言概述 测试题
-基本数据类型、常量、变量
--程序举例
--基本数据类型、常量、变量 测试题
-运算与表达式
--运算与表达式 测试题
-实验二:简单程序设计(上)
-数据的输入和输出
--数据的输入和输出
--数据的输入和输出 测试题
-选择结构
--if语句
--switch语句
--选择结构 测试题
-循环结构
--for语句
--循环结构 测试题
-自定义类型
--自定义类型
--自定义类型
-第2章小结
--第二章小结
-实验二:C++简单程序设计(下)
-导学
--导学
-函数定义
--函数定义
--函数定义 测试题
-函数调用
--例3-2
--例3-3
--例3-4
--例3-5
--例3-6
--函数调用 测试题
-嵌套与递归
--例3-9
--例3-10
--嵌套与递归 测试题
-函数的参数传递
--函数的参数传递
--函数的参数传递 测试题
-引用类型
--引用类型 测试题
-含有可变参数的函数
--含有可变参数的函数 测试题
-内联函数
--内联函数 测试题
-constexpr函数
--CONSTEXPR函数课后习题
-带默认参数值的函数
--带默认参数值的函数 测试题
-函数重载
--函数重载 测试题
-C++系统函数
--C++系统函数习题
-第3章小结
--第三章小结
-实验三(上)函数的应用
-实验三(下)函数的应用
-导学
--导学
-面向对象程序的基本特点
--面向对象程序的基本特点 测试题
-类和对象
--类和对象的定义
--类和对象 测试题
-构造函数
--构造函数基本概念
--委托构造函数
--复制构造函数
--构造函数 测试题
-析构函数
--析构函数
--析构函数 测试题
-类的组合
--类的组合
--类的组合程序举例
--前向引用声明
--类的组合 测试题
-UML简介
--UML简介
--UML简介课后习题
-结构体与联合体
--结构体与联合体 测试题
-枚举类
--枚举类
--枚举类 测试题
-第4章小结
--第四章小结
-实验四(上)
--实验四(上)
-实验四(下)
--实验四(下)
-导学
--导学
-标识符的作用域与可见性
--标识符的作用域与可见性 测试题
-对象的生存期
--对象的生存期
--对象的生存期 测试题
-类的静态成员
--类的静态成员 测试题
-类的友元
--类的友元 测试题
-共享数据的保护
--共享数据的保护 测试题
-多文件结构和预编译命令
--多文件结构和预编译命令 测试题
-第5章小结
--小结
-实验五
--实验五
-导学
--导学
-数组的定义与初始化
--数组的定义与使用
--一维数组应用举例
--数组的定义与初始化 测试题
-数组作为函数的参数
--数组作为函数的参数 测试题
-对象数组
--对象数组
--对象数组 测试题
-基于范围的for循环
-指针的定义和运算
--指针的定义和运算 测试题
-综合实例
--综合实例
-实验六(上)
--实验六上
-指针与数组
--指针数组
--指针与数组 测试题
-指针与函数
--指针类型的函数
--指向函数的指针
--指针与函数 测试题
-对象指针
--对象指针
--对象指针 测试题
-动态内存分配
--动态内存分配 测试题
-智能指针
--智能指针
-vector对象
--vector对象
--vector对象 测试题
-对象复制与移动
--移动构造
--对象复制与移动 测试题
-字符串
--C风格字符串
--string类
--字符串 测试题
-第6章小结
--第六章小结
-综合实例
--综合实例
-实验六(下)
--实验六(下)