static的作用有3个,分为函数层面和变量层面。
函数
当我们同时编译多个文件时,所有未加 static 前缀的全局变量和函数都具有全局可见性。函数的使用方式与全局变量类似,在函数的返回类型前加上static,就是静态函数。
其特性如下:
- 静态函数只能在声明它的文件中可见,其他文件不能引用该函数。相当于把函数隐藏了,其他文件不可见。
- 不同的文件可以使用相同名字的静态函数,互不影响
/* file1.c */
#include <stdio.h>
static void fun(void)
{
printf("hello from fun.\n");
}
int main(void)
{
fun();
fun1();
return 0;
}
/* file2.c */
#include <stdio.h>
static void fun1(void)
{
printf("hello from static fun1.\n");
}
这里fun1为静态函数,无法再main函数中调用。如果,file1和file2放在一起编译,就会报错。
变量
static对变量声明的时候,第一个作用和函数一样。
在变量前加上static的时候,此变量只对当前文件可见,其他源文件将不可使用。利用这一特性可以在不同的文件中定义同名函数和同名变量,而不必担心命名冲突。
/* a.c */
char a = 'A'; // global variable
void msg()
{
printf("Hello\n");
}
/* main.c */
int main(void)
{
extern char a; // extern variable must be declared before use
printf("%c ", a);
(void)msg();
return 0;
}
--------------------运行结果-----------------------------------------
A Hello
--------------------------------------------------------------------
如在 a 和 msg 的定义前加上 static,main.c 就看不到它们了
static 的第二个作用是保持变量内容的持久
存储在静态数据区的变量会在程序刚开始运行时就完成初始化,也是唯一的一次初始化。共有两种变量存储在静态存储区:全局变量和 static 变量
#include <stdio.h>
int fun(void){
static int 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;
}
---------------------运行结果-----------------------
global local static
1 10
2 9
3 8
4 7
5 6
6 5
7 4
8 3
9 2
10 1
----------------------------------------------------
static 的第三个作用是默认初始化为 0
静态局部变量使用static修饰符定义,即使在声明时未赋初值,编译器也会把它初始化为0。其实全局变量也具备这一属性,因为全局变量也存储在静态数据区。
#include <stdio.h>
#include <stdlib.h>
int a;
static int b;
int main()
{
printf("a=%d\n",a);
printf("b=%d\n",b);
return 0;
}
-------------------运行结果-----------------
a=0
b=0
-------------------------------------------
最后对 static 的三条作用做一句话总结。首先 static 的最主要功能是隐藏,其次因为 static 变量存放在静态存储区,所以它具备持久性和默认值0。