【编程语言】变量的存储时期/作用域以及static/extern的用法

存储类:

              存储时期       链接         内存管理

 

对于一个变量(不同的存储类型)可以通过存储时期,链接属性,以及相应的作用域来描述它。

存储时期就是变量在内存中的保留时间,变量的作用域和链接在一起表明程序的哪些部分可以通过变量名来使用该变量。于是就有了不通过的存储时期,链接属性,以及作用域的组合

 

【1】存储时期(变量的生命期,表示存取一个变量在内存空间的存放以及释放时间)

                          局部变量                寄存器变量               全局变量

 

1局部变量(自动变量)的生命周期是在代码块内如果变量被调用才会分配内存空间;直到退出这个代码块的时候,分配的内存被释放。该思想把自动变量使用的内存视为一个可以重复使用的工作区或者暂存内存。

2寄存器变量 一般变量存储在内存中,但是也有变量被存储在CPU的寄存器中或者存储在高速缓存中,尽可能块的被访问和操作,由于一个寄存器变量存在寄存器而非内存中,所有无法获得寄存器变量的地址,但是在其他方面,寄存器变量和自动变量时一样的,也就是说,他们都具有代码块作用域,空连接以及自动存储时期,可以通过register来表示寄存器变量。

3全局变量(静态外部变量)它具有文件作用域,外部链接和静态存储时期,把变量定义在所有函数之外,即创建了一个外部全局变量,它具有外部链接的静态变量,即从声明的位置开始一直到文件尾部都是可见的。如果要是程序更加清晰的看懂,可以在外部变量前面加上extern 来声明此变量具有,但我们现在一般都不会加上extern 来声明在本文件已定义的外部链接的静态变量(全局变量),但是当你要引用其他文件的外部链接的静态变量时,此时必须要加extern 来声明。

 

作用域/链接属性

                外部链接             内部链接             空链接

1)具有代码块作用域或者函数原型作用域的变量有空连接,意味这它们是由其定义所在代码块或者函数原型所私有的

2)extern 声明的变量具有外部链接属性,表示此变量可以在一个文件或者多个文件的任何地方使用

3)static 声明的变量具有内部链接属性,表示此变量只可以在本文件任何地方使用,在这里要注意的是用static声明的变量可以是文件作用域的变量(内部链接的全局变量)也可以是具有代码块的局部静态变量,它们的共同特点就是具有静态的存储时期,从一次的函数直到下次的调用,内存中都记录着它们的值,这些变量再完成工作时,并没有消失。但是被声明成具有代码块作用域的静态变量它却是空连接属性

 

内存管理(变量存储在内存中的位置)(重点)

         变量可以存储在内存中的不同地方,依赖于他们的生存周期,在函数外部定义的变量(全局变量或静态外部变量)和在函数内部定义的static变量,其生存期就是程序运行的全过程,这些数据被存储在数据段(.DATA)数据段是在内存中为这些变量留出的一段大小固定的空间,它分为两部分用来存放初始化的全局变量以及静态全局变量,另一部分用来存放为初始化的全局变量,由于在有操作系统的情况下,未初始化的静态全局变量(static修饰的变量)会被编译器初始化为零,它们的生存期从程序开始执行到其所在的代码块所在位置开始,直到程序离开该程序代码块时为止,而作为函数参数的变量(形参)的调用只在调用函数周期间存在,被存储在栈空间,但是要注意的是被static修饰的静态局部变量虽然只有代码块作用域但它却一直存在内存中,直到下次被刷新。

 

特别注意

内存空间实际上并不存储变量,但是可以用来存储变量所指向的数据,这里也有点指针的含义,如果把malloc()函数的结果赋给一种指针变量类型,那么指针变量将包含一块动态分配的内存地址,这块内存位于一段名为“堆(HEAP)”的内存空间中,堆一开始也很小,但当程序员调用malloc或者calloc等分配函数时,它就会增大,由于堆可以和数据段或者栈公用一个内存段,当大于一定限度会出现堆栈重叠的情况。


示例代码:

#include 
   
   
    
    

int  func1();
int  func2();

static int j = 1;		//初始化的静态全局变量(文件作用域,内部链接)
//static int a;			//未初始化的静态变量(作用域是本文件可见,编译器会默认赋值为零)

//(extern)int k = 2;	/*全局变量(如果用extern修饰则表示该变量可被其他文件使用
							//(具有外部链接属性,可被其他文件使用))*/

int main(int argc,char *argv[])
{

	int i;					//局部变量
	int m,n;
	static int j = 0;		//静态局部变量(空链接,代码作用域)
	
	for(i = 0; i < 10; i++){
		m = func1();
		n = func2();

//		printf("m = %d, n = %d, j = %d\n",m,n,j);
		
		printf("m = %d, n = %d, \n",m,n);
	}

	return 0;
}

int func1()
{
	static int i;
	i++;

	return i;
}

int func2()
{	
//	i++;
//	j = 0;
//	int j =0;
	j++;			//系统只初始化一次,
					//数据生命期直到程序结束,一直存在内存中,直到被其他数据刷新
	return j;
}

   
   


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值