在 C 语言中,static 关键字不仅可以用来修饰变量,还可以用来修饰函数。在使用 static 关键字修饰变量时,我们称此变量为静态变量。
静态变量的存储方式与全局变量一样,都是静态存储方式。但这里需要特别说明的是,静态变量属于静态存储方式,属于静态存储方式的变量却不一定就是静态变量。例如,全局变量虽然属于静态存储方式,但并不是静态变量,它必须由 static 加以定义后才能成为静态全局变量。
它的第一条也是最重要的一条:隐藏
当我们同时编译多个文件时,所有未加 static 前缀的全局变量和函数都具有全局可见性。为理解这句话,我举例来说明。我们要同时编译两个源文件,一个是 a.c,另一个是 main.c。
下面是 a.c 的内容:
a.c 文件代码
chara=;//globalvariablevoid(){();}
下面是 main.c 的内容:
main.c 文件代码
intmain(void){externchara;//externvariablemustbedeclaredbeFOReuse(,a);(void)msg();0;}

程序的运行结果是:
你可能会问:为什么在 a.c 中定义的全局变量 a 和函数 msg 能在 main.c 中使用?前面说过,所有未加 static 前缀的全局变量和函数都具有全局可见性,其它的源文件也能访问。此例中,a 是全局变量,msg 是函数,并且都没有加 static 前缀,因此对于另外的源文件 main.c 是可见的。
如果加了 static,就会对其它源文件隐藏。例如在 a 和 msg 的定义前加上 static,main.c 就看不到它们了。利用这一特性可以在不同的文件中定义同名函数和同名变量,而不必担心命名冲突。static 可以用作函数和变量的前缀,对于函数来讲,static 的作用仅限于隐藏,而对于变量,static 还有下面两个作用。
static 的第二个作用是保持变量内容的持久
存储在静态数据区的变量会在程序刚开始运行时就完成初始化,也是唯一的一次初始化。共有两种变量存储在静态存储区:全局变量和 static 变量,只不过和全局变量比起来,static 可以控制变量的可见范围,说到底 static 还是用来隐藏的。虽然这种用法不常见,但我还是举一个例子。
实例
intfun(void){staticintcount=10;//事实上此赋值语句从来没有执行过count--;}intcount=1;intmain(void){();(;countprintf(,count,fun());0;}
程序的运行结果是:
globalstatic1102938475665748392101
static 的第三个作用是默认初始化为 0
其实全局变量也具备这一属性,因为全局变量也存储在静态数据区。在静态数据区,内存中所有的字节默认值都是 0x00,某些时候这一特点可以减少程序员的工作量。比如初始化一个稀疏矩阵,我们可以一个一个地把所有元素都置 0,然后把不是 0 的几个元素赋值。如果定义成静态的,就省去了一开始置 0 的操作。再比如要把一个字符数组当字符串来用,但又觉得每次在字符数组末尾加 \0 太麻烦。如果把字符串定义成静态的,就省去了这个麻烦,因为那里本来就是 \0 。
不妨做个小实验验证一下。
实例
inta;intmain(void){inti;staticcharstr[10];(,a,str);0;}
程序的运行结果如下:
:0;string:(begin)(end)
最后对 static 的三条作用做一句话总结。首先 static 的最主要功能是隐藏,其次因为 static 变量存放在静态存储区,所以它具备持久性和默认值0。
一个C语言程序其中static的作用是什么?
在这个程序中 static 没有什么用处。 对于被调用的函数来说 加上static 可以让变量值在被调用的时候,还是上次函数退出时的值。 对于你的程序 main不会被重复调用所以这里加不加都一样。
在C语言中,存储类别包括
四种变量存储类型。 说明符如下: autostaticexternregister一、auto auto称为自动变量。 局部变量是指在函数内部说明的变量(有时也称为自动变量)。 用关键字auto进 行说明, 当auto省略时, 所有的非全程变量都被认为是局部变量, 所以auto实际上 从来不用。 二、static static称为静态变量。 根据变量的类型可以分为静态局部变量和静态全程变量。 1. 静态局部变量 它与局部变量的区别在于: 在函数退出时, 这个变量始终存在, 但不能被其它 函数使用, 当再次进入该函数时, 将保存上次的结果。 其它与局部变量一样。 2. 静态全程变量 Turbo C将大型程序分成若干独立模块文件分别编译, 然后将所有模块 的目标文件连接在一起, 从而提高编译速度, 同时也便于软件的管理和维护。 静态 全程变量就是指只在定义它的源文件中可见而在其它源文件中不可见的变量。 它与 全程变量的区别是: 全程变量可以再说明为外部变量(extern), 被其它源文件使用, 而静态全程变量却不能再被说明为外部的, 即只能被所在的源文件使用。 三、extern extern称为外部变量。 为了使变量除了在定义它的源文件中可以使用外, 还要 被其它文件使用。 因此, 必须将全程变量通知每一个程序模块文件, 此时可用 extern来说明。 四、register register称为寄存器变量。 打字不易,如满意,望采纳。
static这个函数
static 是C中很常用的修饰符,它被用来控制变量的存储方式和可见性static 声明的变量在C语言中有两方面的特征: 1)、变量会被放在程序的全局存储区中,这样可以在下一次调用的时候还可以保持原来的赋值。 这一点是它与堆栈变量和堆变量的区别。 2)、变量用static告知编译器,自己仅仅在变量的作用范围内可见。 这一点是它与全局变量的区别。 2、问题:Static的理解 关于static变量,请选择下面所有说法正确的内容: A、若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度; B、若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度; C、设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题; D、静态全局变量过大,可那会导致堆栈溢出。 答案与分析: 对于A,B:根据本篇概述部分的说明b),我们知道,A,B都是正确的。 对于C:根据本篇概述部分的说明a),我们知道,C是正确的(所谓的函数重入问题,下面会详细阐述)。 对于D:静态变量放在程序的全局数据区,而不是在堆栈中分配,所以不可能导致堆栈溢出,D是错误的。 因此,答案是A、B、C。 3、问题:不可重入函数 曾经设计过如下一个函数,在代码检视的时候被提醒有bug,因为这个函数是不可重入的,为什么?unsigned int sum_int( unsigned int base ){unsigned int index;static unsigned int sum = 0; // 注意,是static类型的。 for (index = 1; index <= base; index++){sum += index;}return sum;}答案与分析: 所谓的函数是可重入的(也可以说是可预测的),即:只要输入数据相同就应产生相同的输出。 这个函数之所以是不可预测的,就是因为函数中使用了static变量,因为static变量的特征,这样的函数被称为:带“内部存储器”功能的的函数。 因此如果我们需要一个可重入的函数,那么,我们一定要避免函数中使用static变量,这种函数中的static变量,使用原则是,能不用尽量不用。 将上面的函数修改为可重入的函数很简单,只要将声明sum变量中的static关键字去掉,变量sum即变为一个auto 类型的变量,函数即变为一个可重入的函数。 当然,有些时候,在函数中是必须要使用static变量的,比如当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类型,则返回为错指针。
发表评论