static关键字与内存

为什么要引入static

      函数内部定义的变量,在程序执行到它的定义处时,编译器为它在栈上分配空间,大家知道,函数在栈上分配的空间在此函数执行结束时会释放掉,这样就产生了一个问题: 如果想将函数中此变量的值保存至下一次调用时,如何实现? 最容易想到的方法是定义一个全局的变量,但定义为一个全局变量有许多缺点,最明显的缺点是破坏了此变量的访问范围(使得在此函数中定义的变量,不仅仅受此函数控制)。 伴随着不同源文件变量和函数之间的相互引用以及相互独立的关系,产生了extern和static关键字。

     static不同类型的用法
 
一, static全局变量
       必备基础:

          
                                          cpu与内存和存储设备关系图

            

                      

                                                         内存结构图

     当一个进程的全局变量被声明为static之后,它的中文名叫 静态全局变量 。静态全局变量和其他的全局变量的存储地点并没有区别,都是在data区(已初始化段)或者(未初始化段)内,但是 它只在定义它的源文件内有效,其他源文件无法访问它


二, static局部变量

 static局部变量中文名叫静态局部变量。它与普通的局部变量比起来有如下几个区别:

           1)位置:静态局部变量被编译器放在全局存储区.data(注意:不在.bss段内,原因见3)),所以它虽然是局部的,但是在程序的整个生命周期中存在。

           2)访问权限:静态局部变量只能被其作用域内的变量或函数访问。也就是说虽然它会在程序的整个生命周期中存在,由于它是static的,它不能被其他的函数和源文件访问。

           3) :静态局部变量如果没有被用户初始化,则会被编译器自动赋值为0,以后每次调用静态局部变量的时候都用上次调用后的值。这个比较好理解,每次函数调用静态局部变量的时候都修改它然后离开,下次读的时候从全局存储区读出的静态局部变量就是上次修改后的值。

       三 , static函数

    函数前加static使得函数称为静态函数,但是此处"static"的含义不是指存储方式,而是指对函数的作用域局限于本文件(所以又称内部函数).使用内部函数的好处是:不同的人编写函数时,不用担心自己定义的函数,是否会与其他文件中函数同名.

代码:
int a = 0;// 全局初始化区
char *p1; //全局未初始化区
int main()
{	
       int b; //栈
	char s[] = "abc";// 栈
	char *p2;// 栈
	char p3[]= "123456"; //123456//0在常量区,p3在栈上。
	static int c = 0;   // 全局(静态)初始化区
       p1 = (char *)malloc(10);//分配得来得10和20字节的区域就在堆区。
       strcpy(p1, "123456");// 123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。
	return 	0;

}

扫描二维码关注公众号,回复: 1742547 查看本文章
     static与普通类型对比
1. static全局变量与普通的全局变量有什么区别 ?

       全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。
       全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。
      这两者的区别在于非静态全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。 static全局变量只初使化一次,防止在其他文件单元中被引用;   

2.  static局部变量和普通局部变量有什么区别 ?

   把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。  
  static局部变量只被初始化一次,下一次依据上一次结果值;   

3.  static函数与普通函数有什么区别?

   static函数与普通函数作用域不同,仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static修饰的函数),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件.
       static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝.

猜你喜欢

转载自blog.csdn.net/ox0080/article/details/80781813