static 这个关键字,我感觉对很多初级程序源和刚接触程序的同学来说,可能都没有完全理解它的含义。至少对我来说对它的认识不是很清楚。因此对它在次总结一下。主要作为自己的备忘录。
1.static关键字的第一特性:隐藏
static 在修饰变量时分为全局变量和局部变量,都存在静态存储区域。
static全局变量:作用域是从定义的位置开始到整个所在cpp文件结束,其他cpp文件都不能使用static定义的变量,在同一个cpp文件中,在定义前使用要用extern关键字。因此static修饰变量会被隐藏在一个cpp文件里。
static 局部变量:作用域只在一个函数的内部使用,static局部变量是静态存储,因此在函数退出后,仍然保存值,再次进入函数时,static局部变量使用上次的值。
在局部变量前,加上关键字static,该变量就被定义成为一个静态局部变量。 我们先举一个静态局部变量的例子,如下:
//Example 3 #include <iostream.h> void fn(); void main() { fn(); fn(); fn(); } void fn() { static n=10; cout<<n<<endl; n++; }
通常,在函数体内定义了一个变量,每当程序运行到该语句时都会给该局部变量分配栈内存。但随着程序退出函数体,系统就会收回栈内存,局部变量也相应失效。但是有时候我们需要在两次调用之间对变量的值进行保存。通常的想法是定义一个全局变量来实现。但这样一来,变量已经不再属于函数本身了,不再仅受函数的控制,给程序的维护带来不便。 静态局部变量正好可以解决这个问题。静态局部变量保存在全局数据区,而不是保存在栈中,每次的值保持到下
static 修饰函数:函数前加 static 使得函数成为静态函数。但此处“static”的含义不是指存储方式,而是指对函数的作用域仅局限于本文件(所以又称内部函数)。使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名。
2.static的第二个作用是:保持变量内容的持久
存储在静态数据区的变量会在程序刚开始运行时就完成初始化,也是唯一的一次初始化。共有两种变量存储在静态存储区:全局变量和static变量,只不过和全局变量比起来,static可以控制变量的可见范围,说到底static还是用来隐藏的。虽然这种用法不常见,但我还是举一个例子。
#include <stdio.h>
int fun(void){
static int count = 10; // 事实上此赋值语句从来没有执行过,仅在程序初始化时,初始static局部变量count=10,以后就不再执行。
return count--;
}
int count = 1;
int main(void) {
printf("global\t\tlocal static\n");
for(; count <= 10; ++count)
printf("%d\t\t%d\n", count, fun());
return 0; }
3. static的第三个作用是默认初始化为0.
其实全局变量也具备这一属性,因为全局变量也存储在静态数据区
在静态数据区,内存中所有的字节默认值都是0x00,某些时候这一特点可以减少程序员的工作量。比如初始化一个稀疏矩阵,我们可以一个一个地把所有元素都置0,然后把不是0的几个元素赋值。如果定义成静态的,就省去了一开始置0的操作。再比如要把一个字符数组当字符串来用,但又觉得每次在字符数组末尾加‘\0’太麻烦。如果把字符串定义成静态的,就省去了这个麻烦,因为那里本来就是‘\0’。不妨做个小实验验证一下。
#include <stdio.h>
int a;
int main(void){
int i;
static char str[10];
printf("integer: %d; string: (begin)%s(end)", a, str);
return 0;
}
程序的运行结果如下integer: 0; string: (begin)(end)
最后对static的三条作用做一句话总结。首先static的最主要功能是隐藏,其次因为static变量存放在静态存储区,所以它具备持久性和默认值0.
4. 用static声明的函数和变量小结
static 声明的变量在C语言中有两方面的特征:
1)、变量会被放在程序的全局存储区中,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是它与堆栈变量和堆变量的区别。
2)、变量用static告知编译器,自己仅仅在变量的作用范围内可见。这一点是它与全局变量的区别。
Tips:
A.若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度;
B.若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;
C.设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题;
D.如果我们需要一个可重入的函数,那么,我们一定要避免函数中使用static变量(这样的函数被称为:带“内部存储器”功能的的函数)
E.函数中必须要使用static变量情况:比如当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类型,则返回为错指针。
函数前加static使得函数成为静态函数。但此处“static”的含义不是指存储方式,而是指对函数的作用域仅局限于本文件(所以又称内部函数)。使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名。
5.static 描述类的静态变量和函数:
C++重用了这个关键字,并赋予它与前面不同的第三种含义:表示属于一个类而不是属于此类的任何特定对象的变量和函数(与Java中此关键字的含义相同)。
版权声明:本文为博主原创文章,未经博主允许不得转载。
来源:oschina
链接:https://my.oschina.net/u/1399901/blog/492751