一、共性:
静态变量(全局的或局部的)存放在内存的静态存储区,系统自动初始化为0,自动变量的值是任意的。
二、static的用法
1. 修饰全局变量------全局静态变量
在全局变量之前加上关键字static
与普通全局变量的比较:
共同点:都存放在内存的静态存储区
不同点:(1)全局静态变量会被程序自动初始化为0,而普通全局变量的值是任意的。除非被显示的初始化。(2)全局静态变量的作用域只在本文件中,不能在其他文件中通过extern声明来访问。
定义全局静态变量的好处:
(1)不会被其他文件所访问,修改
(2)其他文件中可以使用相同名字的变量,不会发生冲突。
示例:
//teststatic1.c
void display();
extern int n;
int main()
{
n = 20;
printf("%d\n",n);
display();
return 0;
}
//teststatic2.c
static int n; //定义全局静态变量,自动初始化为0,仅在本文件中可见
void display()
{
n++;
printf("%d\n",n);
}
文件分别编译通过,但link的时候teststatic1.c中的变量n找不到定义,产生错误。
2. 修饰局部变量----局部静态变量
在局部变量之前加上关键字static
与普通局部变量的区别:
(1) 局部静态变量会被程序自动初始化为0,而普通局部变量的值是任意的,除非它被显示的初始化
(2) 局部静态变量存放在静态存储区,作用域从其定义一直到程序结束。而普通局部变量存放在栈中,作用域从其定义到函数结束。
应用: 统计次数功能
声明函数的一个局部变量,并设为static类型,作为一个计数器,这样函数每次被调用的时候就可以进行计数。这是统计函数被调用次数的最好的办法,因为这个变量是和函数息息相关的,而函数可能在多个不同的地方被调用,所以从调用者的角度来统计比较困难。代码如下:
void count();
int main()
{
int i;
for (i = 1; i <= 3; i++)
count();
return 0;
}
void count()
{
static num = 0;
num++;
printf(" I have been called %d",num,"times\n");
}
输出结果为:
I have been called 1 times.
总结:当static用来修饰局部变量的时候,它就改变了局部变量的存储位置,从原来的栈中存放改为静态存储区。 当static用来修饰全局变量的时候,它就改变了全局变量的作用域(在声明他的文件之外是不可见的)
3. 修饰函数---静态函数
在函数的返回类型前加上关键字static,
函数的定义和声明默认情况下是extern的,但静态函数只是在声明他的文件当中可见,不能被其他文件所用。
定义静态函数的好处:
<1> 其他文件中可以定义相同名字的函数,不会发生冲突
<2> 静态函数不能被其他文件所用。
例如:
//teststatic1.c
void display();
static void staticdis();
int main()
{
display();
staticdis();
renturn 0;
}
//teststatic2.c
void display()
{
staticdis();
printf("display() has been called \n");
}
static void staticdis()
{
printf("staticDis() has been called\n");
}
文件分别编译通过,但是连接的时候找不到函数staticdis()的定义,产生错误。
总结:
在一个源程序所有源文件中,一个外部变量或函数只能在某个文件中定义一次,而其它文件可以通过extern声明来访问它(在其他文件中必须通过extern声明来访问外部变量,但是访问外部函数时可以不用extern只需声明函数原型就可以,因为函数的声明默认为),如果在外部变量或函数前加上static修饰,则该变量或函数就成为内部变量或内部函数,其作用域只在定义它的文件中。其他文件不能通过extern声明来访问它,此时在其他文件中可以定义与其重名的变量或函数。