全局变量
定义:在函数外定义的变量是全局变量,全局变量可以为本文件中其它函数所共用,它的有效范围从定义变量的位置开始到本源文件结束。
- 设全局变量的作用:增加了函数间数据联系的渠道;
- 不必要时不要使用全局变量,因为:a) 全局变量在程序的全部执行过程中都占用存储单元; b) 使得函数的通用性降低;c) 全局变量使用过多,会降低程序的清晰性;
- 如果外部变量在文件开头定义,则在整个文件范围内都可以使用该外部变量,如果不在文件开头定义,按上面规定作用范围只限于定义点到文件终了,如果在定义点之前的函数想引用该外部变量,则应该在该函数中用关键字extern作外部变量说明;
- 如果在同一个源文件中,外部变量与局部变量同名,则在局部变量的作用范围内,外部变量不起作用。
局部变量
定义: 在一个函数内部定义的变量是局部变量,它只在本函数范围内有效。
- 主函数main定义的变量也只在主函数有效;
- 不同函数中可以使用名字相同的变量,它们代表不同的对象,互不干扰;
- 形式参数也是局部变量;
- 在一个函数内部,可以在复合语句中定义变量,这些变量只在本复合语句中有效。
静态变量
变量定义前加上 static
- 静态变量的作用范围要看静态变量的位置,如果在函数里,则就是静态局部变量,作用范围就是这个函数;
- 静态全局变量,只在本文件可以用,虽然整个程序包含多个文件, 但静态全局变量只能用在定义它的那个文件里,却不能用在程序中的其他文件里。它是定义存储因型为静态型的外部变量,其作用域是从定义点到程序结束,所不同的是存储类型决定了存储地点,静态型变量是存放在内存的数据区中的, 它们在程序开始运行前就分配了固定的字节, 在程序运行过程中被分配的字节大小是不改变的,只有程序运行结束后,才释放所占用的内存。
思考
1、static全局变量与普通的全局变量有什么区别?
- 全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。这两者在存储方式上并无不同。
- 这两者的区别虽在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。
- 从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域, 限制了它的使用范围。
2、static函数与普通函数有什么区别?
- static函数与普通函数作用域不同,仅在本文件。
- 只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义。
- 对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件。
3、static局部变量和普通局部变量有什么区别?
- static局部变量只被初始化一次,下一次依据上一次结果值。
总结
- 全局变量的作用域是整个项目,它只需要在一个源文件中定义就可以作用于所有的源文件,其它不包括全局变量定义的文件需要用extern关键字再次声明这个全局变量。
- 全局变量、静态全局变量、静态局部变量都是在静态存储区(全局数据区)中分配空间的,而局部变量是在栈上分配空间的。
- 全局变量、静态变量的生命期和程序生命期是一样的,在程序结束之后操作系统会回收空间。
- 全局变量和静态变量都是保存在静态存储区中,生命期和程序一样,但是不同的是全局变量的作用域是整个项目,而静态全局变量是当前程序文件,静态局部变量则是当前函数体内。全局变量和静态全局变量、静态局部变量默认值都是0,也就是在没有初始化变量值的时候默认为0。
- 静态变量包含静态局部变量和静态全局变量。静态局部变量具有局部作用域只对定义自己的函数可见,只被初始化一次,自从初始化一次之后直到程序运行期间一直都在。静态全局变量具有全局作用域作用于定义它的程序文件但是不能作用于项目里的其它文件,这一点和全局变量不同。静态全局变量可以被多次初始化。
- 把局部变量改变为静态变量之后是改变了它的存储方式和生命期。把全局变量改变为静态变量之后是改变了它的作用域,限制了使用范围。
C/C++语言经过编译之后将内存分为以下几个区域:
- 栈(stack)区:由编译器进行管理,自动分配和释放,存放函数调用过程中的各种参数、局部变量、局部常量、返回值以及函数返回地址。操作方式类似数据结构中的栈。
- 堆(heap)区:用于程序动态申请分配和释放空间。C语言中的malloc和free,C++中的new和delete均是在堆中进行的。正常情况下,程序员申请的空间在使用结束后应该释放,若程序员没有释放空间,则程序结束时系统自动回收。注意:这里的“堆”并不是数据结构中的“堆”。
普通变量和局部变量存放在栈里,指针变量存放在堆里。
- 全局(静态)存储区、全局区:分为DATA段和BSS段。DATA段(全局初始化区)存放初始化的全局变量和静态变量;BSS段(全局未初始化区)存放未初始化的全局变量和静态变量。还存放了常量(字符串常量、其他常量等)。程序运行结束时自动释放。其中BBS段在程序执行之前会被系统自动清0,所以未初始化的全局变量和静态变量在程序执行之前已经为0。
- 程序代码区、代码区:存放程序的二进制代码。
显然,C/C++语言中的全局变量和局部变量在内存中是有区别的。C/C++语言中的全局变量包括外部变量和静态变量,均是保存在全局存储区中,占用永久性的存储单元;局部变量,即自动变量,保存在栈中,只有在所在函数被调用时才由系统动态在栈中分配临时性的存储单元。