2.6.2 static 变量
static变量是函数或文件中的永久变量。和全局变量不同,函数外或文件外看不到静态(static)变量;和全局量相同,函数调用之间,静态量保持其值。编写其它程序使用的通用函数或库函数时,这一特性是有用的。static对周部变量和全局变量的作用不一样。
2.6.3 static 局部变量
把 static作用于局部变量时,编译程序为之生成永久存储单元,很象全局变量。静态(static)局部变量和全局变量的主要区别在于可见性,静态局部量只在其被声明的代码块中是可见的。简言之,静态局部变量是多次函数调用之间保持其值的局部变量。
对某些必须在调用之间保持局部变量值的子程序而言,static局部变量特别重要。如果不允许使用static,则必须在这类函数中使用全局变量,由此开放引入副作用的门户。基于前次值生成下一个值的数列产生器要求使用static局部变量。否则,我们只好使用全局变量,每个程序中使用该函数时都要声明所用的全局变量,同时要确保与已声明的其它全局变量没有冲突。使用全局量的函数也难于放到库中。数列产生器函数的较好写法是使用static,如下所示:
点击(此处)折叠或打开
-
series( void )
-
{
-
static int series_num;
-
-
series.num=series_num+23:
-
return(series_num);
- }
首次进入代码块时给局部静态量赋初值,以后进入同一代码块时不再赋初值,具体实现如下例所示。初次进入新版series()时,把series_num 初始化成 100,以后进入时不再赋初值了。
点击(此处)折叠或打开
-
series(void )
-
static int series_num=100:
-
-
series_num=series_num+23:
-
return(series_num):
- }
2.6.4 static 全局变量
施加于全局变量的 static 令编译程序生成静态(static)全局变量,使之仅在定义该变量的文件中是可见的。因此,虽然变量是全局的,但其它文件中的子程序无法感知其存在,无法修改之,有效地消除了副作用。在局部静态变量不能满足要求的罕见情况下,我们可以建立…个小文件,其中只放需要的静态全局变量的函数和所需的静态全局量,然后独立编译该文件,以后使用时不必担心副作用。
我们重写上节的序列产生器函数,由此允许通过称为series_start()的第二个函数置i mam个种子值,由该种子值初始化序列的产生。放函数series(),series_start()和变量 series_num的全文件如下:
点击(此处)折叠或打开
-
/* this must all be in one file -preferably by itself */
-
static int series_num:
-
void series_start(int seed);
-
int series(void );
-
-
series(void)
-
{
-
series_num=series_num-23;
-
return(series_num):
-
}
-
-
/*initialize series_num */
-
-
void series_start(int seed )
-
{
-
series_num=seed:
- }
由此产生序列中的值。我们再次重复:局部静态量只在其被定义的函数或代码块中是可见的;全局静态量只在其被定义的文件中是可见的。如果把函数series()和series_start()放到库中,程序可以调用这两个函数,但不能直接引用静态全局变量series-num,因为series_num()对程序的其它代码是隐蔽的。实际上,在其它文件中可以用series-num为名字,声明并使用另--个全局变量。本质上,static修饰符允许声明仅由一个函数了解并使用的变量,在函数调用之间保持变
量值的同时又不影响其它函数。static 变量允许程序的一部分对其它部分充分隐蔽,管理大型复杂程序时的优点十分突出。
存储修饰符static使我们方便地构造通用函数,使函数便于放到库中。
=========================================
以上内容,摘抄自 《C语言大全第二版》
由此,我们得出如下结论:
1、使用 static 修饰的局部变量,会在内存中开辟一个永久的静态存储区域,当下次调用该函数时,该区域被再次重载,其值为上一次该函数运行后结果值。且不受该函数再次调用时在该函数内定义的影响。这句话可以理解为:
假设我们在某个函数中定义了一个静态的整型变量 i,并赋予了初始值 10 ,当再次调用该函数时,在定义这个静态整型变量 i 的地方的赋值语句将不会被执行,i 的值保持为上一次调用该函数后的 i 值,我们用如下的程序代码片段加以解释:
点击(此处)折叠或打开
-
int func()
-
{
-
static int i=10;
-
-
i = i + 5 ;
-
return(i);
- }
static int i = 10 ;
将对 i赋予初始值 10 ;
第二次调用这个函数,虽然会执行 static int i ; 但不会对 i 赋予初始值 10 ,反而是将首次调用结束后的 i 值 15 赋予了 i , 然后再次执行 i = i+5 。
也就是说,第二次调用结束后, i 的值变成了 20 。
2、使用 static 修饰的局部变量,如果没有显式进行赋值,则对于整型变量而言,其值为 0 , 对于指针或字符型而言,其值为 NULL。
我们可以用如下代码进行验证:
点击(此处)折叠或打开
-
#include <stdio.h>
-
#include <string.h>
-
#include <stdlib.h>
-
-
-
int func()
-
{
-
static int i;
-
++i;
-
return(i);
-
}
-
-
-
int main ( void )
-
{
-
printf("%d\n",func());
-
printf("%d\n",func());
-
printf("%d\n",func());
-
printf("%d\n",func());
-
return 0;
- }
1
2
3
4