C语言理论知识-生存期

各种基本类型的字节数

void main()
{
	cout << sizeof(char) << endl;
	cout << sizeof(short) << endl;
	cout << sizeof(int) << endl;
	cout << sizeof(long int) << endl;
	cout << sizeof(long long) << endl;
	cout << sizeof(float) << endl;
	cout << sizeof(double) << endl;
	cout << sizeof(long double) << endl;
	cout<<endl;///////////////////////////////
	cout << sizeof(char*) << endl;
	cout << sizeof(short*) << endl;
	cout << sizeof(int*) << endl;
	cout << sizeof(long int*) << endl;
	cout << sizeof(long long*) << endl;
	cout << sizeof(float*) << endl;
	cout << sizeof(double*) << endl;
	cout << sizeof(long double*) << endl;//在当前系统之下 指针为4字节;
}

生存期:是指编译通过后的情况

int *fun()
{
	int x = 10;
	return &x;
}
void add()
{

}
void main()
{
	int *p = NULL;
	p = fun();
	//add();
	cout << *p << endl;

}

当加上调用add()时得出的结果是一个随机值
在这里插入图片描述
而不调用add()时则可以得到结果10
在这里插入图片描述
在不调用add时,虽然fun()函数在执行完之后空间会被释放,但是在这时候没有干扰到这一块的空间,所以p=fun()依旧指向了x的值。然而当调用add时,栈帧的调用时连续的,比如main时一楼的栈帧,fun时二楼的栈帧,当fun()执行完后释放,又把fun的栈帧空间给了add(),同时在给add()时会将fun释放后的空间打扫一边会用16进制数0xcccccccc来填充。所以同时p=fun()就失效了,这是p就变成了失效指针。只要fun()被释放不管p能不能得到x的值都是失效指针。但是当printf()输出一个数组时输出的数可能不是全0xcccccccc应为printf()这个函数也会侵占上一个函数的栈帧,但是他不一定会影响上一个函数的值。如果一直测试都是那个值只能说明是运气问题总之下面这样的程序是据不允许的
在这里插入图片描述
但是

int fun()
{
	int x = 100;
	return x;
}
void mian()
{
	int a = fun();
}

这样的程序是允许的应为return的x是一个临时量是放在cpu的寄存器中的
另外全局变量是存放在数据区的

char *str = "yhping"
void main()
{
	char *ch = "hellow";

}

在上面的的程序中str是全局变量在数据区ch是局部变量在栈区,而hellow和yhping是常量在数据区,全局变量还有静态变量也在数据区
静态变量在第一次调用时初始化被产生而且初始化一次,它的生存期是从产生开始一直到程序的结束

int *fun(int x)
{
	static int a = x;//静态变量只在执行时初始化一次,所以后来的x也没有是a再次初始化。存放于数据区,将a的空间分配于数据区
	                     之所以之初始化一次,是应为在第一次初始化其时,在他的空间处设计了一个标记域,在未初始化之前比如标记域的值为0;
						 而初始化之后把他改为1,这样在第二次初始化时检查到标记域的值为1,这样就进行第二次初始化

	static int b = 0;//b是一个常量在编译时就会完成,在数据区开辟空间存放数
	++a;
	cout << a;
	return &a;
}
void main()
{
	int *p = NULL;
	for (int i = 10; i > 0; --i)
	{
		p = fun(i);//之所以可以这样做是应为静态变量即使在fun()函数被释放后依然存在于数据区,所以可以执行
		*p += 100;//这样是会改变静态变量a的值的
	}

}

正是应为静态变量的这种特性,所以为了返回数组时,可以把数组定义为静态变量,就可已返回数组的值,但是这样的方式有局限性,所以当需要返回多个类型不同的值时建议使用结构体进行返回

struct student
{
	char id[10];
	char name[10];
	char sex;
	int age;
};
student *fun()
{
	student s = { "20180101", "yhping", 'm', 28 };
	return &s;
}
void main()
{
	student *sp = fun();
	cout <<sp->age;
}

这样虽然可能得到结果,这是应为没有被别的函数在获取内存空间是没有被替代,但是这样做是不合法的,可能会造成错误,这就是函数的生存期问题。所以最好把整个结构体返回

但是有一个例外就是malloc开辟的堆内存空间

int *getarray(int n)//不再生存期问题中,函数空间在栈中,malloc在堆中,虽然函数死亡,但是堆空间开辟的内存空间依旧存在
{
	int *s = (int *)malloc(sizeof(int)*n);
	return s;     //所以s在main中依旧能够在主函数中调用
}

void main()
{
	int n;
	cin >> n;
	int *p = getarray(n);
	for (int i = 0; i < n; i++)
		p[i] = i;
	for (int i = 0; i < n; i++)
		cout << p[i] << endl;
	free(p);
	p = NULL;
}

猜你喜欢

转载自blog.csdn.net/qq_40738945/article/details/85216532
今日推荐