Chinaunix首页 | 论坛 | 博客
  • 博客访问: 534995
  • 博文数量: 129
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1888
  • 用 户 组: 普通用户
  • 注册时间: 2013-06-20 11:09
文章分类

全部博文(129)

文章存档

2016年(1)

2015年(5)

2014年(64)

2013年(59)

我的朋友

分类: C/C++

2013-11-08 15:17:38

1、用static声明静态局部变量

    当有时候希望函数的局部变量的值在函数调用结束后不消失而保留原值,即其占用的存储单元不释放,在下一次该函数调用时,该变量保留上一次函数调用结束时的值。这时就应该指定该局部变量为静态局部变量。

对静态局部变量的说明:
  a.静态局部变量在静态存储区分配存储单元,在程序的整个运行期间都不释放。

  b.在编译期间为静态局部变量赋初值,且只赋初值一次。

  c.如果在定义静态局部变量时没有赋初值,那么在编译时自动赋初值0或null。

  d.静态局部变量的作用域为函数内。在其他函数中它是不可见的。

 那么在什么情况下需要用静态局部变量呢?

   1.需要保留函数上一次调用结束时的值。

   例如:用如下方式求n!时:

    
  1. #include<iostream>
  2. using namespace std;
  3. int fac(int);
  4. int main()
  5. {
  6.     int i;
  7.     for(i=1;i<=5;i++)
  8.          cout<<i<<"!"<<fac(i)<<endl;
  9.     return 0;

  10. }

  11. int fac(int n)
  12. {
  13.     static int f=1;    //一次也不会执行
  14.     f=f*n;
  15.     return f;

  16. }
   2.如果初始化后,变量只 被引用而不用改变其值,则用静态局部变量比较方便,以免每次都调用都要赋值。


2.用static声明静态全局变量
  如果在程序设计
中希望某些全局变量只限于本文件使用,而不能被其他文件引用,则可以在定义全局变量时加一个static声明。

注意:
 不要误以为用static修饰的全局变量才采用静态存储方式,而不加static的是动态存储。实际上,两种形式的全局变量都是静态存储方式。只是作用范围不同而已,都是在编译时分配内存。

3.用static修饰函数
  函数本质上是全局的,因为一个函数要被另外的函数调用,但是,也可以指定函数只能被本文件调用,而不能被其他文件调用。
  用static修饰的函数称为内部函数,它只能被本文件的其他函数调用。
  在定义函数时,如果函数首部冠以关键字extern,则表示此函数是外部函数,可供其他文件调用。

4.static的作用

C语言中,static的字面意思很容易把我们导入歧途,其实它的作用有三条。

1)先来介绍它的第一条也是最重要的一条:隐藏。

当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性。为理解这句话,我举例来说明。我们要同时编译两个源文件,一个是a.c,另一个是main.c

下面是a.c的内容:
 

  1. char a = 'A'; // global variable
  2. void msg()
  3. {
  4.     printf("Hello\n");
  5. }
下面是main.c的内容:
 
  1. int main(void)
  2. {
  3.     extern char a; // extern variable must be declared before use
  4.     printf("%c ", a);
  5.     (void)msg();
  6.     return 0;
  7. }

程序的运行结果是:

A Hello

你可能会问:为什么在a.c中定义的全局变量a和函数msg能在main.c中使用?前面说过,所有未加static前缀的全局变量和函数都具有全局可见性,其它的源文件也能访问。此例中,a是全局变量,msg是函数,并且都没有加static前缀,因此对于另外的源文件main.c是可见的。

如果加了static,就会对其它源文件隐藏。例如在amsg的定义前加上staticmain.c就看不到它们了。利用这一特性可以在不同的文件中定义同名函数和同名变量,而不必担心命名冲突。Static可以用作函数和变量的前缀,对于函数来讲,static的作用仅限于隐藏,而对于变量,static还有下面两个作用。

2static的第二个作用是保持变量内容的持久。
   
存储在静态数据区的变量会在编译阶段
就完成初始化,也是唯一的一次初始化。共有两种变量存储在静态存储区:全局变量和
static变量,只不过和全局变量比起来,static可以控制变量的可见范围,说到底static还是用来隐藏的。
     static修饰的变量总是在内存的静态区,所以即使这个函数运行结束,这个静态变量的值也不会销毁,函数下次使用时仍然能用到这个值。
例子:
  
  1. #include<iostream>
  2. using namespace std;

  3. static int j;
  4. int fun1()
  5. {
  6.     static int i=0;   //该句一次也不会执行,在编译阶段完成了变量i的初始化
  7.     i++;
  8.     return i;
  9. }

  10. int fun2()
  11. {
  12.     j=0;
  13.     j++;
  14.     return j;
  15. }

  16. int main()
  17. {
  18.     int k=0;
  19.     printf("global static\tlocalstatic\n");
  20.     for(k=0;k<10;k++)
  21.     {
  22.         
  23.         printf("%d\t\t%d\n",fun1(),fun2());
  24.     }
  25.     return 0;
  26. }

运行结果如下:
   

3static的第三个作用是默认初始化为0。其实全局变量也具备这一属性,因为全局变量也存储在静态数据区。在静态数据区,内存中所有的字节默认值都是0x00,某些时候这一特点可以减少程序员的工作量。比如初始化一个稀疏矩阵,我们可以一个一个地把所有元素都置0,然后把不是0的几个元素赋值。如果定义成静态的,就省去了一开始置0的操作。再比如要把一个字符数组当字符串来用,但又觉得每次在字符数组末尾加’\0’太麻烦。如果把字符串定义成静态的,就省去了这个麻烦,因为那里本来就是’\0’。不妨做个小实验验证一下。
  

  1. #include <stdio.h>

  2. int a;

  3. int main(void)
  4. {
  5.     int i;
  6.     static char str[10];

  7.     printf("integer: %d; string: (begin)%s(end)", a, str);

  8.     return 0;
  9. }
参考:
 http://www.cnblogs.com/dc10101/archive/2007/08/22/865556.html


 
阅读(993) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~