每天进步一点点。
若萌新总结有误,望牛人不吝赐教。>_<
static在不同的环境具有不同的意思,这确实很不幸,因为这总是会给c程序员新手带来麻烦。它既是一个自私的关键字,又是一个大方的关键字,为什么这么说呢?如下文所示。
在c语言中当我们需要使用一个变量或者函数时,我们不得不考虑的两点就是它们的作用域(决定它可以被谁使用)和生命周期(决定它可以被使用到什么时候),static关键字用于改变这两种属性。
一、static改变作用域(自私)。
在某些c程序中你可能添加不止一个源文件,这个时候,每个源文件中的内容能否在其它的源文件中起作用,这就可能和static有关了。我们通过一个例子来看看:
这是test1.c:
#include <stdio.h>
#include <windows.h>
int main()
{
extern int n;
printf("%d\n", n);
system("pause");
return 0;
}
这是test2.c:
int n = 10;
下面是运行结果:
通过上面例子我们可以看到,我们在test2中定义并初始化了一个全局变量n(注意该变量在代码块外部,即对于test2.c来说它时全局变量,虽然test2中并没有代码块),在test1中声明并使用它(至于为什么用extern,我们暂时不管它),程序正常运行。由此我们可以得出test2中的变量具有全局作用域,即它可以在其它任何一个源文件中被使用。但是当我们把test2.c改为如下时:
static int n = 10;
除了修饰变量之外,static还可以修饰函数,如下:
test1.c:
#include <stdio.h>
#include <windows.h>
extern void fun1();
int main()
{
fun1();
system("pause");
return 0;
}
test2.c:
#include <stdio.h>
void fun1()
{
printf("Hello world!\n");
}
运行结果:
我们在test1.c中调用test2.c中的函数时,运行正常,但是,用static修饰test_2.c中的函数时,编译器就会报错说fun1是一个无法解析的外部符号,也就是说fun1没有被定义,原因和上面static修饰变量相同。虽然fun1用static修饰后只能在test2中使用,但是我们可以通过其它手段,让它在test1中使用,如下:
test1.c:
#include <stdio.h>
#include <windows.h>
extern void fun2();
int main()
{
fun2();
system("pause");
return 0;
}
test2.c:
#include <stdio.h>
static void fun1()
{
printf("Hello world!\n");
}
void fun2()
{
printf("I want to use fun1!\n");
fun1();
}
运行结果:
通过以上测试,我们搞清楚了static的第一个作用——改变修饰内容的作用域。即static只允许本源文件使用被它修饰的内容,是不是很自私。
!!这里要注意:
1、static修饰全局变量时才会改变其作用域(可以被其它源文件使用 ——> 只能自己使用)。
2、static修饰函数时,该函数并不是绝对的只能被该源文件使用,我们可以另辟蹊径使用它。
二、改变生命周期(大方)。
变量的储存类型(storage class)是指储存变量的内存类型。变量的储存类型决定它何时创建、何时销毁、以及它的值能保持多久。有一下几个地方可以储存变量:堆区,栈区,静态全局区,寄存器。。。
变量的储存类型取决于它的声明位置和修饰符。在任何代码块之外声明的变量储存于静态全局区,这类变量在程序运行之前创建,在程序的整个执行期间存在。它始终保持原先的值,除非你给他赋一个新值。
对于在代码内部的变量,它们默认的是自动变量,即执行到该代码块是被创建,执行完毕后该变量被释放,我们可以通过关键字static改变它的储存类型(自动变量——>静态变量),即改变它的生命周期,使它在整个程序运行期间一直存在。我们通过以下例子来详细了解它。
#include <stdio.h>
#include <windows.h>
int main()
{
int i = 0;
for(i = 0; i < 10; i++)
{
int n = 1;
printf("%d\n", n);
n++;
}
system("pause");
return 0;
}
运行结果:
在每趟循环开始的时候,我们定义n=1,然后打印,在循环结束时销毁,所以打印结果全是1。那么当使用static修饰n的时候,如下:
#include <stdio.h>
#include <windows.h>
int main()
{
int i = 0;
for(i = 0; i < 10; i++)
{
static int n = 1;
printf("%d\n", n);
n++;
}
system("pause");
return 0;
}
运行结果:
打印结果是从1到10,是不是有点出乎意料。原因是我们使用static修饰n时,n被存放在了静态区,它在程序的整个执行过程中都不会被销毁,所以,当第二趟循环开始的时候,static int n = 1并没有起作用,程序是在第一趟的基础上使用n的值。这样来看,1-10的结果也就理所应当了。
由此来看,static是不是也很大方啊,它允许你使用前面“旧”值。
总结:
static作用:
1、修饰函数,改变作用域(其它源文件——>仅本源文件)。
2、修饰全局变量,改变作用域(其它源文件——>仅本源文件)。
3、修饰局部变量,改变生命周期(储存类型)(自动——>静态)。
成于坚持,败于止步!
【作者:果冻 http://blog.csdn.net/jelly_9】