Chinaunix首页 | 论坛 | 博客
  • 博客访问: 125757
  • 博文数量: 42
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 354
  • 用 户 组: 普通用户
  • 注册时间: 2014-07-01 15:34
个人简介

不晓得说啥子

文章分类

全部博文(42)

文章存档

2015年(41)

2014年(1)

我的朋友

分类: C/C++

2015-04-12 15:56:30

 一、static定义局部静态变量(staic放在函数体内部)

    
     1.1  存储空间分配不同
          与auto变量不同的是,static变量的内存分配在静态数据区(data segment),而不是在栈内分配。如果两者在相同的地方定义,那么auto变量与static的作用域相同,但是他们的生存期不同。如果都定义在函数内,那么在函数销毁时auto变量就销毁,但是static变量会一直持续到程序运行结束(全局性)。如果在一个函数内定义一个auto变量,在函数结束时是不能返回该变量的,但是如果在函数局部定义一个static变量,那么在函数结束时是可以返回该变量的,因为该变量在整个程序运行期间都存在.

          int func (){
               int a = 10;
               return a;   //错误,在函数func结束时变量a已经被销毁,不能返回
          }
          
          int func2( ){
               static int a=10;
               return a;  //正确,由于a是静态变量,整个程序运行都存在,并不会随着函数的调用结束而销毁,因此可以返回他的值
          }

     1.2  初始化不同
          static变量只进行一次初始化, 如果static变量定义时没有赋值,那么默认值是0。(由于static变量存储在静态数据区,该区域的内存都默认初始化为0,所以可以利用这个特性来对数据进行初始化)
          如果一个static变量定义并初始化在一个函数内,在第一次调用函数时该变量会进行定义并初始化,在以后的函数调用过程中,定义和初始化的过程将不在执行:
          
     int func ( ){
          static int a =10;
          printf("%d\n",a--);     //静态变量a只被初始化一次,每次函数调用a的值是上一次函数调用结束时的值
      }
          
     int main()
     {
          for(int i=0; i<10; i++){
               func( );
          }
     }
     最终函数的输出是 10, 9, 8,7,6,5,4,3,2,1。 变量a只被初始化一次,而不是每次调用函数都重新定义一个变量a再进行初始化,当下次调用函数时变量a保持上一次函数调用结束时的值(static变量的记忆性)。


二、外部静态变量、函数(static放在函数体内部)

     在C中static有了第二种含义:用来表示不能被其它文件访问的全局变量和函数。, 但为了限制全局变量/函数的作用域, 函数或变量前加static使得函数成为静态函数。此处“static”的含义不是指存储方式,而是指对函数的作用域仅局限于本文件(所以又称内部函数)。注意此时, 对于外部(全局)变量, 不论是否有static限制, 它的存储区域都是在静态存储区, 生存期都是全局的。 此时的static只是起作用域限制作用, 限定作用域在本模块(文件)内部.
使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名。
//file1.c
int a;
static int b;
int func1( ){ ...}
static int func2( ) {...}

//file2.c

extern int a;   //正确,使用file1.c中的全局变量
extern int b;  //错误,不能使用file.c中的全局静态变量
func1( );         
func2( );          

三、静态数据成员/成员函数(C++特有)
C++重用了这个关键字,并赋予它与前面不同的第三种含义:表示属于一个类而不是属于此类的任何特定对象的变量和函数. 这是与普通成员函数的最大区别, 也是其应用所在, 比如在对某一个类的对象进行计数时, 计数生成多少个类的实例, 就可以用到静态数据成员. 在这里面, static既不是限定作用域的, 也不是扩展生存期的作用, 而是指示变量/函数在此类中的唯一性. 这也是”属于一个类而不是属于此类的任何特定对象的变量和函数”的含义. 因为它是对整个类来说是唯一的, 因此不可能属于某一个实例对象的. (针对静态数据成员而言, 成员函数不管是否是static, 在内存中只有一个副本, 普通成员函数调用时, 需要传入this指针, static成员函数调用时, 没有this指针. )
请看示例程序四((影印版)第59页)
class EnemyTarget {
public:
  EnemyTarget() { ++numTargets; }
  EnemyTarget(const EnemyTarget&) { ++numTargets; }
  ~EnemyTarget() { --numTargets; }
  static size_t numberOfTargets() { return numTargets; }
  bool destroy();   // returns success of attempt to destroy EnemyTarget object
private:
  static size_t numTargets;               // object counter
};
// class statics must be defined outside the class;
// initialization is to 0 by default
size_t EnemyTarget::numTargets;

在这个例子中, 静态数据成员numTargets就是用来计数产生的对象个数的.
另外, 在设计类的多线程操作时, 由于POSIX库下的线程函数pthread_create()要求是全局的, 普通成员函数无法直接做为线程函数, 可以考虑用Static成员函数做线程函数.


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