静态局部变量和后增操作符

     下面的程序的输出结果你能准确地写出来嘛?

1 /***********************************************
2 * 测试问题: *
3 * 下面的程序输出结果是什么? *
4 * *
5 * 注意: 下面的程序用于测试静态变量和局部变量的区别
6 * 以及后增操作符的运算机制。 *
7**********************************************
*/

8 #include <stdio.h>
9 /***********************************************
10 * first -- Demonstration of automatic *
11 * variables. *
12 **********************************************
*/

13 int first(void)
14 {
15 int i = 0// Demonstration variable
16
17 return (i++);
18 }

19 /***********************************************
20 * second -- Demonstration of a static *
21 * variable. *
22 *********************************************
*/

23 int second(void)
24 {
25 static int i = 0// Demonstration variable
26
27 return (i++);
28 }

29
30 int main()
31 {
32 int counter; // Call counter
33
34 for (counter = 0; counter < 3; counter++)
35 printf("First %d\n", first());
36
37 for (counter = 0; counter < 3; counter++)
38 printf("Second %d\n", second());
39
40 return (o);
41 }

     不知你能否,至少我第一次是没有准确的写出来。要写出这段程序的输出结果,其实也不是难事,只需要了解了静态变量和局部变量的区别,了解了后增和先增操作符的机制就可以了。
     局部变量的生命周期局限于一个区域之内,离开了它的生命周期,它就不复存在。函数first()中定义的i就是这样一个变量,所以每次程序进入first函数时,i都会被初始化为0,因而,无论调用该函数多少次,函数的输出结果都是相同的。而静态变量能够保证在每次调用时变量的值能保存下来,因而如果函数中改变了该变量的值,则如果多次调用该函数,静态变量的值会不同,所以调用second函数时,输出结果每次都不相同。second函数中的i既是静态变量,又是局部变量,为什么它还是能保存变量的值呢?这就要从函数调用说起。函数每次调用时,系统都会在栈上为局部变量分配空间,而函数调用结束后,系统为函数在栈上分配的空间也就随之释放掉,局部变量的值也就无法保存下来。而当系统遇到static时,它会为该静态变量在程序的静态存储区分配空间,因而即使函数退出,函数所使用的栈空间都被释放掉了,静态变量的值仍能保存下来。
     说完了静态变量,我们再来说说后增操作符operator ++。后增操作符的运算机制(以i++为例)是:1.保存i的值;2.i加一;3.返回保存的值。我们可以看到,在对变量进行后增操作时,会引入一个临时空间存储i的值,而这通常会影响程序执行效率。所以如果不需要保存i的值而只是对i进行累加操作,我们应该使用++i,而不应该使用i++,关于这一点,可以参看《exceptional c++》item6。
     分析了两个关键点后,我们可以给出程序的运行结果了:

First 0
First 
0
First 
0
Second 
0
Second 
1
Second 
2

     我想对于这个程序结果你应该不会感到意外了吧,不过你是否真的明白这些机制了呢?如果明白了,那就说说下面代码的输出结果吧:

 1 int first(void)
 2 {
 3 static int i = 0// Demonstration variable
 4 int j=i++;
 5 return j;
 6 }

 7 
 8 int second(void)
 9 {
10 static int i = 0// Demonstration variable
11 i++;
12 return i;
13 }

14
15 int main()
16 {
17 int counter; // Call counter
18
19 for (counter = 0; counter < 3; counter++)
20 printf("First %d\n", first());
21
22 for (counter = 0; counter < 3; counter++)
23 printf("Second %d\n", second());
24
25 return (0);
26 }
posted @ 2005-09-08 10:00  Articles about .NET  阅读(470)  评论(2)    收藏  举报