全局变量、局部变量、静态全局变量、静态局部变量

来源:互联网 发布:排课软件价格 编辑:程序博客网 时间:2024/06/06 09:25

原文:http://www.cnblogs.com/chenglei/archive/2009/09/06/1561367.html

从作用域看:

全局变量具有全局作用域。全局变量只需在一个源文件中定义,就可以作用于所有的源文件。当然,其他不包括全局变量定义的源文件需要用extern关键字再次声明这个全局变量。

静态局部变量具有局部作用域。它只被初始化一次,自从第一次初始化直到程序与你新内阁结束都一直存在,他和全局变量的区别在于全局变量对所有的函数都是可见的,而静态局部变量只对定义自己的函数体始终可见。

局部变量也只有局部作用域,他是自动对象,他在程序运行期间不是一直存在,而是只在函数执行期间存在,函数的一次调用结束后,变量就被撤销,其所占用的内存也被收回。

静态全局变量也具有全局作用域,他与全局变量的区别在于如果程序包含多个文件的话,他作用于定义它的文件里,不能作用到其他文件里,即被static关键字修饰过的变量具有文件作用域。这样即使两个不同的源文件都定义了相同的静态全局变量,他们也是不同的变量。

从分配内存空间看:

全局变量、静态局部变量、静态全局变量都在静态存储区分配空间,而局部变量在栈分配空间。

全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式。这两者在存储方式上没有什么不同。区别在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其他源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其他源文件中引起错误。

1、静态变量会被放在程序的静态数据存储区里,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是他与堆栈变量和堆变量的区别

2、变量用static告知编译器,自己仅仅在变量的作用域范围内可见。这一点是他与全局变量的区别。

从以上分析可以看出,把局部变量改变为静态变量后是改变了他的存储方式,即改变了他的生存期。把全局变量改变为静态变量后是改变了他的作用域,限制了他的使用范围,因此static这个说明符在不同的地方起的作用是不同的。

TIPS:

1、若全局变量仅在单个文件中访问,则可以讲这个变量修改为静态全局变量。

2、若全局变量仅在单个函数中使用,则可以将这个变量修改为该函数的静态局部变量。

3、全局变量、静态局部变量、静态全局变量都存放在静态数据存储区。

4、函数中必须要使用static变量的情况:当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类型,则返回为错指针。

(不能返回局部auto型的指针或引用

原文:http://blog.chinaunix.net/uid-27411029-id-3497902.html

存储在静态区域和存储在栈区域的对象在返回指针的函数中有什么本质区别,为什么存储在静态区域的静态变量就能够返回其地址,而存储在栈区域的自动变量不能返回其地址?

  

      主要在于他们的管理机制不同,存储在静态区域的对象的生存周期是主函数的生存周期,而存储在栈区域的对象生存周期为指针函数开始运行到指针函数结束,当指 针函数结束时存储在栈区域的对象生存周期也就结束,其地址也变成无效地址。栈空间由编译器自动分配和释放,函数结束时其栈空间释放内存。堆区域一般由程序 员来控制其生存周期。因此,指针函数返回的指针能够指向静态区域的变量而不能指向自动局部变量。

      当函数使用指针作为返回值时,它可以指向静态区域的地址,可以指向堆内存的地址,也可以指向函数调用者的栈空间,但是它不可以指向一个函数内部栈内存的地址。

      因此,能不能返回局部指针变量,不在于这个指针变量的类型和性质(不在于该指针是不是局部指针变量),而在于该指针指向的对象的类型和性质。如果该指针指向函数内部的栈空间,则程序非法,如果指向静态区域的地址,则合法。

   

     因此,判断指针函数返回值是否合法,应该首先看看该返回指针变量指向的对象的存储区域,即该指针指向的区域。透过现象看本质,不同区域的对象本质区别在于 其的生存周期的有效性不同,判断返回的指针值是否有效合法,最本质应该看看该指针指向的对象的生存周期在函数结束后是否有效。如果该对象的生存周期长于指 针函数的生存周期,则该指针返回值合法,否则,该指针的值为非法地址。即使该指针指向堆区域的地址但在指针函数结束时,堆已释放,则该函数的返回地址仍为 非法。


0 0