C语言变量的存储方式和生存期

人之所以痛苦,那是因为你在成长。--------magic_guo

变量可以分为全局变量局部变量,那变量的存储方式可以分为静态存储方式动态存储方式

静态存储方式:指在程序运行期间由系统分配固定的存储空间的方式
动态存储方式:指在程序运行期间根据需要进行动态的分配存储空间的方式

定义一个变量和函数都有两个属性:数据类型(浮点型、整形等)和存储类别(数据在内存中的存储方式)

在动态存储区存放以下数据:
1.形参(在函数调用期间给形参分配存储空间)
2.函数中定义的没有用关键字static声明的变量,即自动变量(auto)
3.函数调用时的现场保护和返回地址等

在C中存储类别分为4中:自动的(auto)、静态的(statis)、寄存器的(register)、外部的(extern)

下面我们来讨论局部变量和群聚变量的存储类别有什么不同:

局部变量的存储类别
1.自动的(auto)
即函数中没有用关键字static声明的变量,函数的形参,函数中的局部变量都属于此类,动态的分配存储空间,数据存储在动态存储区中。
自动变量属于动态存储类别,函数调用完后即释放内存单元,自动变量赋值不是在编译时进行赋值的,而是在进行函数调用时进行赋值,每调用一次函数重新给一次初值。
代码如下:

int f1(int a)			//形参,a为动态存储类别
{
	auto int b = 3;		//自动变量,b为动态存储类别
	int c = 4;			//不带static关键字,与b同类别,也是动态存储类别
	static e = 5;		//使用static关键字声明,所以e为静态存储类别
}

2.静态存储类别(static局部变量)
如上图的e变量
静态局部变量属于静态存储类别,在静态存储区域内分配存储单元。在整个程序运行期间都不释放,静态局部变量是在编译时赋初值的,在程序运行时它已有初值,以后每次调用不需在重新赋值而只是保留上次函数调用结束时的值。
虽然静态局部变量的值在函数调用结束后仍然存在,但其他函数是不能引用它的,因为它是局部变量,只能被本函数引用。

代码如下:
自动变量和静态变量赋值的区别:

# include<stdio.h>


int main(void)
{
	int f1(int a);				//f1函数的前置声明
	int f2(int a);				//f2函数的前置声明
	int i, a = 1;
	for (i=0; i<3; i++)
	{
		printf("%d\n", f1(a));  //调用f1函数
	}

	return 0;
}

int f1(int a)		
{
	auto int b = 0;				//定义自动变量
	b = b + 1;
	return (a+b);		 
}

int f2(int a)		
{
		
	static c = 0;				//定义静态变量
	c = c + 1;
	
	return (a+c);		 
}

调用f1函数的结果:
在这里插入图片描述
调用f2函数的结果:
在这里插入图片描述
显然两种变量的存储方式不一样,导致的结果也不一样。

3.寄存器变量
使用关键字register作声明
一般情况下变量的值是存在内存中的,当程序需要用到那个变量时,由控制器发送指令将内存中变量的值送到运算器中。经过运算,如果需要存起来,再从运算器将数据传送到内存中存放。
如果有些使用频繁的变量,则存取变量的值会浪费很多时间,为提高执行效率,则将局部变量的值放在CPU中的寄存器中,不必再到内存中去取。这种变量叫做寄存器变量
声明如下:

register int a;

三种变量的存储位置是不同的:
自动变量存储在动态存储区、静态变量存储在静态存储区、寄存器变量存储在CPU的寄存器中

全局变量的存储类别
全局变量又称为外部变量,存储在静态区域内,存在于程序的着呢个运行过程
从作用域的角度来看,分为三种情况:
1.在一位文件内扩展外部变量的作用域
如下,函数后面定义的外部变量,想要使用,则需要使用关键字“extern“对该变量进行外部声明,表示将该变量的作用域扩展到此位置。

# include<stdio.h>

int main(void)
{
	int max();
	extern A, B, C;				// 如果不在这里使用extern声明A,B,C,则无法使用A,B,C三个变量
	printf("请输入三个整数以求出起最大值:");
	scanf("%d %d %d", &A, &B, &C);
	printf("最大值是:%d\n", max());

	
	return 0;
}

int A, B, C;

int max()
{
	int m;
	m = A>B? A:B;
	if (C>m)
		m=C;
	
	return m;
}

在这里插入图片描述
2.将外部变量的作用域扩展到其他文件
方法同上,也是使用extern关键字进行作用域声明,区别是在另一个文件内进行声明。

3.将外部变量的作用域限制在本文件内
在本外部变量前面加上static关键字即可,如下:

static int A;

则此全局变量(外部变量)只能在定义它的文件内使用。

扩展:
将函数的作用域限制在所定义它的文件中,也是使用static关键字作声明:

static int max()
{
	int m;
	m = A>B? A:B;
	if (C>m)
		m=C;
	
	return m;
}

则此函数只能在本文件内使用,其他文件则不能引用,称为内部函数。
外部函数:在函数首部的左端加关键字extern,则此函数是外部函数:

extern int max()
{
	int m;
	m = A>B? A:B;
	if (C>m)
		m=C;
	
	return m;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值