1、main中有{},{}结束时变量的生命期结束
生命周期与析构函数的关系:当一个对象/变量的生命周期结束时,析构函数会自动被调用
#include <stdio.h>
class Object
{
public:
~Object()
{
prinf("销毁");
}
int value;
};
int main
{
{
Object obj;
obj.value=1;//成员变量初始化
printf("....a....");
}//局部变量obj生命周期在此处结束,此时会自动调用析构函数打印“销毁”
printf("....b....");
return 0;
}
全局变量和局部变量
全局变量的生命期是永恒的,如果返回一个局部变量的地址会出现问题(变量在子函数中或者在if语句后出现都会随着程序的运行时变量失效)
#include <stdio.h>
int* get()
{
int num=1;
return #
}
int main()
{
int* p=get();
*p=12; //p指向的变量已经失效,不能用星号操作
return 0;
}
用法错误 ,因为get()函数返回的是一个局部变量的地址,当get()获取局部变量的地址返回后,局部变量num的生命周期结束,从而使指针p指向了一个无效的变量。正确程序如下,应该把num定义为全局变量
#include <stdio.h>
int num=1;
int* get()
{
return #
}
int main()
{
int* p=get();
*p=12;
return 0;
}
再如
int main()
{
int* p=0;
if(1)
{
int a=123; //a生命期开始
int* p=&a;
} //a生命期结束
printf("%d\n",*p);
return 0;
}
2、数组释放
打印内容不确定
返回“字符串常量的指针”和“返回数组名”的区别:
返回静态数据区的地址,函数调用完成内部p数组被释放了,所以返回的地址指向的内容不确定
返回栈内存(动态数据区)的地址
特殊说明:如果定义成char* p =”hello world”;返回常量区地址是可以得到正常打印的
3、static修饰函数和变变量
static修饰一个全局变量事时,该变量的名字被限制在本cpp内,即不能用extern来声明访问
全局变量生命周期永恒
static可以看成全局变量
输出结果为6
函数incre内部定义了一静态局部变量x,尽管与全局变量x同名,但
它们占用各自不同的内存单元,对于静态变量x来说,因为它的生存期与程序相同,所以
每次调用后其值将长期保留(不会被内存释放),其初始值是当程序运行时赋值一次,以后调用不再赋初始值(再次进入incre函数时,第一句赋值语句不执行)。
所以第一次调用输出2,第二次调用就输出6(2*3)
#include <stdio.h>
void Test()
{
static int number=0;
number++;
printf("%d",number);
}
int main()
{
Test();
Test();
Test();
return 0;
}
全局变量,调用完后,再次调用时number在上一次基础上+1
4、局部对象的声明周期
Object& Test()
{
Object the_object={123}; //局部对象
return the_object; //返回对象的引用
}
int main()
{
Object& r=Test();
r.value=456; //被引用的对象有效
return 0;
}
Test函数返回值引用了一个局部对象
当Test函数返回后,对象已经失效,因此返回的引用r/the_object不能被访问
static变量不属于这个类
class Object
{
public:
int a;
public:
static int b;
static int c;
};
int Object::b=0;
int Object::c=0;
则sizeof(Object)的值为4