变量的作用域,生存周期:自动变量,静态变量,外部变量,寄存器变量

变量的作用域和生存期
1、变量的作用域
程序中被花括号括起来的区域,叫做语句块(Block)。函数体是语句块,分支语句和循环体也是语句块。
变量的作用域(Scope)规则是:每个变量仅在定义它的语句块(包含下级语句块)内有效,并且拥有自己的存储空间。
不在任何语句块内定义的变量,称为全局变量(Global Variable)全局变量的作用域为整个程序,即全局变量在程序的所有位置均有效。这是因为假如把整个程序看作一个大语句块,按照变量的作用域规则,在与main()平行的位置即不在任何语句块内定义的变量,就应该在程序的所有位置均有效。
相反,在除整个程序以外的其他语句块内定义的变量,称为局部变量(Local Variable)
全局变量从程序运行开始起就占据内存,仅在程序结束时才将其释放,所谓释放内存,其实就是将内存中的值恢复为随机值(即乱码)。由于全局变量的作用域是整个程序,在程序运行期间始终占据着内存,因此在程序运行期间的任何时候,在程序的任何地方,都可以访问(读或者写)全局变量的值。

例题:用递归方法编程输出Fibonacci数列的基础上,同时打印出计算Fibonacci数列每一项时所需的递归调用次数。

#include <stdio.h>

int count;
long fib(int n);


int main()
{
	int n,i,x;
	printf("Input n:");
	scanf("%d",&n);
	for(i=1;i<=n;i++)
	{
		count = 0;
		x = fib(i);
		printf("fib(%d)=%d,count = %d\n",i,x,count);
	}
	return 0;
 } 
 
long fib(int n)
{
	count++;
	if(n==0)
	return 0;
	else if(n==1)
	return 1;
	else return(fib(n-1)+fib(n-2));
} 

在这里插入图片描述
程序定义了全局变量count,用于累计递归函数调用次数,这里虽未对count初始化,但全局变量不指定初值时会自动初始化为0,因此此时count的值仍为0。
使用太多的全局变量,和使用太多的goto语句标号一样,都会导致程序混乱不堪,很难保证哪个变量不会被意外修改,也很难推断变量的值究竟是在哪个地方被修改的,而任何一个函数对它的修改都会作用到全局,同样,依赖全局变量的函数也会受此影响。

变量占用着不同的内存单元,有着不同的作用域,因此不会互相干扰。

2、变量的生存周期:
变量的生存周期是指变量从生成到被撤销的时间段,即从分配内存到释放内存的时间段,实际上就是变量占用内存的时间。在C语言中,变量的生存期是由变量的存储类型说明的,变量的存储类型决定了变量的生存期,即决定变量何时“生”,何时“灭”。变量的存储类型的一般声明方式如下:
存储类型 数据类型 变量名表;

变量只能在其生存期间内被访问,而变量的作用域也会影响变量的生存期。因此,C语言中提供的存储类型主要有以下几种:
(1)自动变量 (Automatic Variable)
(2)静态变量 (Static variable)
(3)外部变量 (Extern Variable)
(4)存储器变量 (Register Variable)

2.1自动变量(Automatic Variable)
自动变量的标准定义格式:
auto 类型名 变量名:
例如:
auto int temp;
由于自动变量极为常用,所以C语言把它设计成缺省的存储类型,即auto可以省略不写。反之,如果没有指定变量的存储类型,那么变量的存储类型就是缺省为auto。
自动变量的“自动”体现在进入语句块时自动申请内存,退出语句块时自动释放内存。它仅能被语句块内的语句访问,再退出语句块以后不能在访问。因此,自动变量也称为动态局部变量。
2.2静态变量(Static Variable)
静态变量的定义格式为:
static 类型名 变量名;
一个自动变量(即动态局部变量)再退出定义后它的函数后,因系统给他分配的内存已经被释放,下次再进入该函数时,系统会给它重新分配内存,因此它的值是不会被保留的。如果希望系统为其保留这个值,除非系统分配给它的内存在退出函数调用时不释放。这时就要用到静态变量。

例题:计算n!。

#include <stdio.h>

long func(int n);

int main()
{
	int i,n;
	while(1)
	{ 
	printf("Input n:");
	scanf("%d",&n);
	for(i=1;i<=n;i++)
	{
		printf("%d!=%ld\n",i,func(i));
	}
	} 
	return 0;
	
}

long func(int n)
{
	static long p=1;
	p=p*n;
	return p;
}

在这里插入图片描述
由此可以看出static会“记住“定义变量的值,使其不会被释放;发生了改变会记住改变的值。

2.3外部变量
格式:
extern 类型名 变量名;
如果在所有函数之外定义的变量没有指定其存储类别,那么他就是一个外部变量。外部变量是全局变量,它的作用域是从它的定义到本文件的末尾。但是如果要在定义 点之前或者在其他文件中使用它,那么就需要定义为外部变量。
和静态变量一样,外部变量也是在静态存储区内分配内存的,其生存周期是整个程序的运行期。没有显示初始化的外部变量由编译程序自动初始化为0。
区别在于他们的作用域有可能是不同的,这取决于静态变量是在哪里被访问,而在所有函数外定义的静态变量,称为全局静态变量,但是只能在本文件中调用,其他文件,无法调用。

2.4寄存器变量
寄存器变量就是用寄存器存储的变量。
其格式定义为:
register 类型名 变量名
寄存器(Register)是CPU内部的一种容量有限但速度极快的存储器。由于cpu进行访问时内存的操作很耗时,是的有时对内存的访问无法于指令的执行保持同步。因此,将需要频繁访问的数据存放在CPU内部的存储器里,即使使用频率较高的变量声明为register,可以避免cpu对存储器的频繁数据访问,是程序更小,执行速度更快。

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值