C语言:全局变量、静态变量static、外部变量extern的区别

全局变量int i是在整个工程可见的,但是在另外文件是不能用(假设工程是由两个源文件1.cpp、2.cpp链接而成,全局变量定义在1.cpp,而2.cpp不能用,虽然可见),要想在2.cpp用,必须在2.cpp加上extern int i;

静态局部变量特点

  静态局部变量属于静态存储方式,它具有以下特点:
  (1)静态局部变量在函数内定义,但不象自动变量那样,当调用时就存在,退出函数时就消失。静态局部变量始终存在着,也就是说它的生存期为整个源程序。
  (2)静态局部变量的生存期虽然为整个源程序,但是其作用域仍与自动变量相同,即只能在定义该变量的函数内使用该变量。退出该函数后, 尽管该变量还继续存在,但不能使用它。
  (3)允许对构造类静态局部量赋初值。若未赋以初值,则由系统自动赋以0值。
  (4)对基本类型的静态局部变量若在说明时未赋以初值,则系统自动赋予0值。而对自动变量不赋初值,则其值是不定的。 根据静态局部变量的特点, 可以看出它是一种生存期为整个源程序的量。虽然离开定义它的函数后不能使用,但如再次调用定义它的函数时,它又可继续使用, 而且保存了前次被调用后留下的值。 因此,当多次调用一个函数且要求在调用之间保留某些变量的值时,可考虑采用静态局部变量。虽然用全局变量也可以达到上述目的,但全局变量有时会造成意外的副作用,因此仍以采用局部静态变量为宜。
`````````````````````````
静态全局变量定义

  全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用, 因此可以避免在其它源文件中引起错误。从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域, 限制了它的使用范围。因此static 这个说明符在不同的地方所起的作用是不同的。应予以注意。

C++中的静态对象需要注意的几个问题

1.无论何时设计一个包含静态变量的函数,都需要注意多线程问题


2.静态对象(包括局部静态对象和全局静态对象)的析构函数在程序从main中退出,或者是标准的C库函数exit被调用时才调用。多数情况下main函数的结尾也是调用exit来结束程序的,这就意味着在析构函数内部使用exit函数是很危险的,因为这样会导致无穷的的递归调用。但如果用标准的C库函数abort来退出程序,静态对象的析构函数并不会调用


3.可以用标准C库函数atexit来指定当程序跳出mian,或调用exit时应执行的操作。在这种情况下,在跳出main或者调用exit之前,用atexi()t注册的函数可以在所有的对象的析构函数调用之前被调用


4.和普通对象的销毁一样,静态对象的销毁也是按照与初始化相反的顺序进行的


5.静态全局变量是内部链接的,内部链接的好处是可以将这个东西放在一个头文件中而不用担心链接时发生冲突。一般来说,放在头文件中的名字,如常量、内联函数、在默认情况下都是内部链接的

注:常量在C中默认是外部链接的,在C++中默认是内部链接,如果想让const量变成外部链接,需要加extern,并且在定义时如果没有赋初值,则这个“定义”实际上是一个申明


6.所有的全局对象都是隐含为静态存储的(存放在静态存储区),如果不使用static关键字,则这个全局对象对所有的翻译单元都是可见的

文件作用域的int a=0等同于extern int a=0,都是定义一个外部连接性的静态数据区成员

文件作用域的static int a=0,是定义一个内部连接性的静态数据区成员

extern void f()等同于void f()

所以需要注意“static”与“静态”多种映射,对于在文件作用域的全局变量以及函数,static是改变其可见性,而对于局部变量,static改变的是存储类型


7.与static既能应用于全局变量也能应用于局部变量不同,关键字auto和register都只能应用于局部变量,不过这两个关键字都有点多余,因为编译器总是能从变量定义时的上下文判断出这是一个局部变量,并且编译器在优化代码方面也做得很好

你可能感兴趣的:(c++软件开发)