1.生存周期不同 全局变量:全局区(静态区)(static):全局变量和静态变量是存储在一起的,初始化过的全局变量和静态变量在同一块区域,未初始化的全局变量和静态变量存放在一块相邻的区域内。此区域由系统在程序结束后释放 局部变量: 放在堆栈中。由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈
2.作用范围不同 全局变量具有全局作用域。全局变量只需在一个源文件中定义,就可以作用于所有的源文件。当然,其他不包含全局变量定义的源文件需要用extern 关键字再次声明这个全局变量。 局部变量也只有局部作用域,它是自动对象(auto),它在程序运行期间不是一直存在,而是只在函数执行期间存在,函数的一次调用执行结束后,变量被撤销,其所占用的内存也被收回
3.静态变量分为 全局静态变量(常称为全局变量)和局部静态变量(static修饰的变量)
- using namespace std;
- static int var1 = 0;//局部静态变量,虽然位置在函数体外
- static int var2;//同上,局部静态变量
- int var3 = 0;//全局静态变量
- int main(int argc, char const *argv[])
- {
- int var4 = 3;//在text段
- static int var5 = 1;//局部静态变量
- return 0;
- }
///
(1)静态局部变量在函数内定义,但不像
自动变量那样,当调用时就存在,退出函数时就消失。静态局部变量始终存在着,也就是说它的生存期为整个源程序。
(2)静态局部变量的生存期虽然为整个源程序,但是其
作用域仍与自动变量相同,即只能在定义该变量的函数内使用该变量。退出该函数后, 尽管该变量还继续存在,但不能使用它。
(3)允许对构造类静态局部量赋初值。若未赋以初值,则由系统自动赋值。数值型变量自动赋初值0,字符型变量赋空字符。
(4)对基本类型的静态局部变量若在说明时未赋以初值,则系统自动赋予0值。而对
自动变量不赋初值,则其值是不定的。 根据静态
局部变量的特点, 可以看出它是一种生存期为整个
源文件的量。虽然离开定义它的函数后不能使用,但如再次调用定义它的函数时,它又可继续使用, 而且保存了前次被调用后留下的值。 因此,当多次调用一个函数且要求在调用之间保留某些变量的值时,可考虑采用静态局部变量。虽然用
全局变量也可以达到上述目的,但全局变量有时会造成意外的副作用,因此仍以采用局部静态变量为宜。
举例说明
给读者一个简单直白的例子(区别静态
局部变量和动态局部变量):
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#include<stdio.h>
int
fun(
int
n)
{
static
int
f=1;
f=f*n;
return
f;
}
void
main()
{
int
i;
for
(i=1;i<=5;i++)
printf
(
"fun(%d)=%d\n"
,i,fun(i));
}
|
这里的运行结果是:
1
2
3
4
5
|
fun(1)=1
fun(2)=2
fun(3)=6
fun(4)=24
fun(5)=120
|
说明f在加了static的类型限制之后,就相当于全局变量,函数调用完了之后,修改过的f的值仍然是有效的(即这个程序相当于求i的阶乘了)。而如果不加static的类型限制,那么,会是什么结果呢,我们看下面的代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#include<stdio.h>
int
fun(
int
n)
{
int
f=1;
f = f * n;
return
f;
}
void
main()
{
int
i;
for
(i=1;i<=5;i++)
printf
(
"fun(%d)=%d\n"
,i,fun(i));
}
|
程序的运行结果是:
1
2
3
4
5
|
fun(1)=1
fun(2)=2
fun(3)=3
fun(4)=4
fun(5)=5
|
也就是说,这时函数fun中的变量f的生命周期就仅限于fun函数的范围内了,在main中每次传入新的参数i,f就会计算1*i的值并返回,而不会像之前那样不断的累乘了。
———————————————————————————————————————————————
下面是java例子:
1
2
3
4
5
6
7
8
9
10
11
12
|
public
class
StaticTest{
static
int
f=
1
;
//java声明静态变量要放到函数外面,结果和c的结果一样
int
fun(
int
n){
f = f * n;
return
f;
}
public
static
void
main(String[] args){
StaticTest st =
new
StaticTest();
for
(
int
i =
1
; i <=
5
; i++)
System.out.println(st.fun(i));
}
}
|
---------------------------------------------------------------------------------------------------------------
Module Module1
Public a As Integer ‘未赋值的情况下a的值是0
End Module
Public Class Form1
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
a += 1
End Sub
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
a += 1
MsgBox(a) ’结果是2(0+1+1)因为是a是模块级静态
全局变量,所以按按钮3以后,直到关闭程序a的值都会是2
End Sub
End Class
///
全局变量与全局静态变量的区别:
(a)若程序由一个源文件构成时,全局变量与全局静态变量没有区别。
(b)若程序由多个源文件构成时,全局变量与全局静态变量不同:全局静态变量使得该变量成为定义该变量的源文件所独享,即:全局静态变量对组成该程序的其它源文件是无效的。
(c)具有外部链接的静态;可以在所有源文件里调用;除了本文件,其他文件可以通过extern的方式引用;
静态全局变量的作用:
(a)不必担心其它源文件使用相同变量名,彼此相互独立。
(b)在某源文件中定义的静态全局变量不能被其他源文件使用或修改。
(c) 只能在本文件中使用!具有内部链接的静态;不允许在其他文件里调用;
(b)若程序由多个源文件构成时,全局变量与全局静态变量不同:全局静态变量使得该变量成为定义该变量的源文件所独享,即:全局静态变量对组成该程序的其它源文件是无效的。
(c)具有外部链接的静态;可以在所有源文件里调用;除了本文件,其他文件可以通过extern的方式引用;
静态全局变量的作用:
(a)不必担心其它源文件使用相同变量名,彼此相互独立。
(b)在某源文件中定义的静态全局变量不能被其他源文件使用或修改。
(c) 只能在本文件中使用!具有内部链接的静态;不允许在其他文件里调用;
- using namespace std;
- static int var1 = 0;//局部静态变量,虽然位置在函数体外
- static int var2;//同上,局部静态变量
- int var3 = 0;//全局静态变量
- int main(int argc, char const *argv[])
- {
- int var4 = 3;//在text段
- static int var5 = 1;//局部静态变量
- return 0;
- }