问题的提出
2022年10月11日,当我重温thread_local、局部静态变量的作用域和初始化情况时,突然冒出个想法,for循环{}内部定义的变量的作用域是多大呢?
跳过分析过程,直接看 答案
// for循环一般形式
for( ; ; ){
// do something
// 定义并初始化局部变量
int x = 1;
// ...
}
简单分析思考
拿上文for循环定义的局部变量x来说。
我想到了学校教的:一个{}就是一个块,在{}块内定义的变量,只能在{}块内访问。可惜,这句话最初没有帮我想明白。
首先, for循环{}外部肯定是访问不到for内部定义的x。
那么, for循环定义的这个x能不能被当前循环的下一个循环访问到呢?其实也就是for的n次循环是在同一个块{}内,还是每次都新的块{}呢?
想到这个问题,第一反应是有点难搞,不好测试验证。想了得5、6分钟也没得思路,我就放了放,却去写别的。我在编写类的时候,恍然大悟,怎么刚没想到c++重要特性–类。
类对象有个特点: 我们可以监视对象的整个声明周期,从创建 – 销毁。
那就简单了,问题就转换成for的每次循环,对象在当前循环创建,当前循环结束后,对象是否会被销毁呢?
测试验证
// 测试代码
# include <iostream>
using namespace std;
// 简单测试类
class Test
{
public:
Test(){
cout << "test" << endl; // 监测对象的创建
}
~Test() {
cout << "~test" << endl; // 监测对象的销毁
}
};
// 主函数
int main()
{
for(int i = 0; i < 3; ++i){
Test t; // 创建对象
}
return 0;
}
运行结果:
测试结果分析
for循环{}内部定义的变量的作用域是多大呢?
问题的答案呼之欲出了。简单分析一下,输出结果是三次循环,每次输出一对test ~test。也就是说,每次循环创建局部对象,在当前循环即将结束前,又会将对象给析构掉。再进一步就是,for循环每次循环创建的局部变量只在当前的这次循环有效,对下一次循环将不再有效。
小结
for循环{}内部定义的变量的作用域是多大呢?
答:for循环每次循环创建的局部变量只在当前的这次循环有效。一般变量在此次循环定义,离开此次循环前会被销毁。
注: 局部静态变量有些特别,局部变量的生存周期是整个程序运行期间,但作用域还是一个块{}内。
其实,最初想到的 :一个{}就是一个块,在{}块内定义的变量,只能在{}块内访问就可以解决问题了。for循环每次结束,都会运行关键字for和 “{”之间的++i和循环条件判定,可不就是每次循环都会出块{},每次循环的{}都不一样。
再换个思路:在for循环定义x, int x = 1; 每次循环都会运行这行代码,如果在每次循环都在同一作用域内,那就相当于出现了多行int x = 1吗,变量可不就是重复定义了,那么程序会编译出错,更别说运行了。所有,问题答案也就锁定了。
整个问题提出到解决、加上写这篇博客,足足花了我一个小时的时间,不知道这时间花间值不值的,毕竟这个知识点并不是重要,甚至可以说没啥用。原本的计划也没完成。不过也有好处,又写了篇博客。。。