简介
==============================================================================================================
一、局部对象
在C++中,每个名字都有作用域,而每个对象都有生命期;
名字的作用域指的是知道该名字的程序文本区(哪些地方可以用);
对象的生命期则是在程序执行过程中对象存在的时间(什么时候可以用,什么时候不可以了);
在函数中定义的形参和变量的名字只位于函数的作用域中,这些名字只在函数体中可见,通常,变量名从声明或定义的地方开始到包围它的作用域结束处都是可用的。
1、自动对象
默认情况下,局部变量的生命期局限于所在的函数的每次执行期间。
只有当定义它的函数被调用时才存在的对象称为自动对象
自动对象在每次调用函数时创建和撤销。
局部变量所对应的自动对象在函数控制经过变量定义语句时创建。
如果在定义时提供了初始化式,那么每次创建对象时,对象都会被赋予指定的初值。
对于未初始化的内置类型局部变量(局部变量不会默认初始化的,全局变量就会),其初值不确定,函数调用结束时,自动对象就会被撤销。
形参也是自动对象,形参所占用的存储空间在调用函数时创建,在函数结束时撤销。当函数结束时,会释放它的局部存储空间,而且,在函数结束后,自动对象和形参的值都不能再访问 了;
- -
2、静态局部对象
一个变量如果位于函数的作用域内,但生命期却跨越了这个函数的多次调用,这种变量很有用 ,往往定义为static(静态的);
static局部对象确保不迟于在程序执行流程第一次经过该对象的定义语句时进行初始化,这种对象一旦被创建,在程序结束前都不会撤销。
当定义静态局部对象的函数结束时,静态局部对象不会撤销。在该函数被多次调用的过程中,静态局部对象会持续存在并保持它的值。
size_t count_calls(){
static size_t ctr=0;//定义一个静态的局部的变量,而且该变量已经被初始化
return ++ctr;
}
int main(){
for(size_t i=0;i!=10;i++)
cout<<count_calls()<<endl;//依次输出1--10
return 0;
}
//在第一次调用函数count_calls之前,ctr就已经创建并赋予初值0.每次函数调用都使ctr加1,并且返回其当前值。在执行函数count_calls时,变量ctr就已经存在并且保留上次调用该函数时的值,因此第二次调用时,ctr的值为1,第三次为2.。
//如果去掉static ,那么结果就是10个1.因为每次调用结束ctr就被撤销了,再次调用的时候又重新建立并初始化。
习题 7.27 (important)
解释形参、局部变量和静态局部变量的差别。并给出一个有效使用了这三种变量的程序例子。
从本质上讲,三者均属于局部作用域中的变量,其中,局部变量又分为普通(非静态)和静态局部变量。
1、 形参的作用域为整个函数体,而普通(非静态)局部变量和静态局部变量的作用域为:从定义处到包含该变量定义的块的结束处;
2、形参由调用函数时所传递的实参初始化;而普通(非静态)局部变量和静态局部变量通常用初始化式进行初始化,且均在程序执行流程第一次经过该对象的定义语句时进行初始化。静态局部变量的初始化在整个程序执行过程中只进行一次;
3、形参和普通(非静态)局部变量均属于自动变量,在每次调用函数时创建,并在函数结束时撤销:而静态局部变量的生命期却跨越了函数的多次调用,它在创建后直到程序结束时才撤销。(一个是函数结束时撤销,一个是程序结束时撤销)
int fac(int x){
static int result=1;
result*=x;
return result;
}
int main(){
int upmut;
cout<<"please input :"<<endl;
cin>>upmut;
for(int i=1;i<=upmut;i++){
cout<<fac(i)<<endl;//依次输出从1到upmut之间所有整数的阶乘
}
return 0;
}
int k;//全局变量,未初始化,默认初始化未0
int main(){
static int i; //静态局部变量i ,未初始化,默认初始化未0
int j; //局部变量,不会默认初始化
cout<<k<<endl; //输出 0
cout<<i<<endl; //输出 0
cout<<j<<endl; //未初始化
return 0;
}