变量类型
变量地址
变量寿命
作用域
static类型的局部变量
全局区
全部程序运行结束
局部
static类型的全局变量
全局区
全部程序运行结束
全局(项目文件中变量声明的文件中)
① 变量会被放在程序的全局存储区中,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是它与堆栈变量和堆变量的区别;
② 变量用static告知编译器,自己仅仅在变量的作用范围内可见。这一点是它与全局变量的区别;
③ static全局变量与普通的全局变量的区别:static全局变量只初使化一次,防止在其他文件单元中被引用;
④ 全局变量和静态变量如果没有手工初始化,则由编译器初始化为0,而局部变量的值不可知。
A. 若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度;
B. 若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;
C. 设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题(重新调用该函数里面的参数与上一次调用该函数生成的数据有无关系);
D. 如果我们需要一个可重入的函数,那么,我们一定要避免函数中使用static变量(这样的函数被称为:带“内部存储器”功能的的函数)
E. 函数中必须要使用static变量情况:比如当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类型,则返回为错指针(返回指针后,指针指向的变量必须存在不可以随着函数调用完成而结束自己的生命)。
按作用域划分,全局变量在整个工程文件内都有效;静态全局变量只在定义它的文件内有效;静态局部变量只在定义它的函数内有效,只是程序仅分配一次内存,函数返回后,该变量不会消失;局部变量在定义它的函数内有效,但是函数返回后失效。全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式。这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。
从以上分析可以看出,把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。
函数前加static使得函数成为静态函数。但此处“static”的含义不是指存储方式,而是指对函数的作用域仅局限于本文件(所以又称内部函数)。
不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名。由于该函数被声明为static类型,因此它的作用域被限定在该函数声明所在的文件,不会出现在其他源文件中。
例如:我在fun.h头文件中声明了一个静态函数“static void ShowInfor()”,那么我只能在头文件所对应的同名源文件fun.c中实现并使用该函数,若在”addition_fun.c”中声明“#include”fun.h”后去调用静态函数“static void ShowInfor()”是不可行的”。
static函数在内存中只有一份,因此我们只能在其函数声明所在的源文件所调用,而普通函数没有作用于限制,因此可以在每个被调用中维持一份拷贝。
术语static有着不寻常的历史.起初,在C中引入关键字static是为了表示退出一个块后仍然存在的局部变量。随后,static在C中有了第二种含义:用来表示不能被其它文件访问的全局变量和函数。为了避免引入新的关键字,所以仍使用static关键字来表示这第二种含义。最后,C++重用了这个关键字,并赋予它与前面不同的第三种含义:表示属于一个类而不是属于此类的任何特定对象的变量和函数(与Java中此关键字的含义相同)。