static(c中定义的关键字1、被其修饰者 外部无法使用(相反的都可以使用extern在外部使用) 2、函数局部变量使用成为静态的放入静态池-生存期改变。c++进行了扩充,使它在类中有了特殊作用)
 1、 static局部变量的”记忆性”与生存期的”全局性”
 所谓”记忆性”是指在两次函数调用时, 在第二次调用进入时, 能保持第一次调用退出时的值. 
 示例程序一
 #include <iostream>
using namespace std;
 void staticLocalVar()
 {
  static int a = 0; // 运行期时初始化一次, 下次再调用时, 不进行初始化工作
  cout<<"a="<<a<<endl;
  ++a;
 }
 int main()
 {
  staticLocalVar(); // 第一次调用, 输出a=0
  staticLocalVar(); // 第二次调用, 记忆了第一次退出时的值, 输出a=1
  return 0;
 }
 应用:
  利用”记忆性”, 记录函数调用的次数(示例程序一)
    利用生存期的”全局性”, 改善”return a pointer / reference to a local object”的问题. Local object的问题在于退出函数, 生存期即结束,. 利用static的作用, 延长变量的生存期.
 示例程序二:
 // IP address to string format
 // Used in Ethernet Frame and IP Header analysis
 const char * IpToStr(UINT32 IpAddr)
 {
  static char strBuff[16]; // static局部变量, 用于返回地址有效
  const unsigned char *pChIP = (const unsigned char *)&IpAddr;
  sprintf(strBuff, "%u.%u.%u.%u",  pChIP[0], pChIP[1], pChIP[2], pChIP[3]);
  return strBuff;
 }
 注意事项:
 1. “记忆性”, 程序运行很重要的一点就是可重复性, 而static变量的”记忆性”破坏了这种可重复性, 造成不同时刻至运行的结果可能不同.
 2. “生存期”全局性和唯一性. 普通的local变量的存储空间分配在stack上, 因此每次调用函数时, 分配的空间都可能不一样, 而static具有全局唯一性的特点, 每次调用时, 都指向同一块内存, 这就造成一个很重要的问题 ---- 不可重入性!!!
 这样在多线程程序设计或递归程序设计中, 要特别注意这个问题.
 (不可重入性的例子可以参见<effective C++ (2nd)>(影印版)第103-105页)
在C中static有了第二种含义:用来表示不能被其它文件访问的全局变量和函数。, 但为了限制全局变量/函数的作用域, 函数或变量前加static使得函数成为静态函数。但此处“static”的含义不是指存储方式,而是指对函数的作用域仅局限于本文件(所以又称内部函数)。注意此时, 对于外部(全局)变量, 不论是否有static限制, 它的存储区域都是在静态存储区, 生存期都是全局的. 此时的static只是起作用域限制作用, 限定作用域在本模块(文件)内部.
 使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名。
 示例程序三:
  
 //file1.cpp
 static int varA;
 int varB;
 extern void funA()
 {
 ……
 }
 static void funB()
 {
 ……
 }
//file2.cpp
 extern int varB; // 使用file1.cpp中定义的全局变量
 extern int varA; // 错误! varA是static类型, 无法在其他文件中使用
 extern vod funA(); // 使用file1.cpp中定义的函数
 extern void funB(); // 错误! 无法使用file1.cpp文件中static函数
C++重用了这个关键字,并赋予它与前面不同的第三种含义:表示属于一个类而不是属于此类的任何特定对象的变量和函数.
namepace nnn
{
auto void func();//错误
auto int i;//错误
static int j;//正确,此时static的文件可见性消失,被限制为namespace可见性
}
class C
{
public:
auto int i;//错误
};
类的可见性,比namespace特殊一点,需要对象绑定,如果显示声明static可以消除对象绑定。
详见百度百科。
6. 对于类的作用域和namespace的作用域
类内定义具有文件作用域和namespace作用域,类外定义,具有全局作用域和namespace作用域,注意namespace作用域是可以跨文件的。(全局作用域的一个名字,两种类型在不同文件是不冲突的,而一个文件中一个名字只能出现一次,即使不同类型)。class比namespace域表示更复杂一点。类名和ns名是文件作用域的,但其有定义了一个作用域,这个作用域却又是跨文件的。
类的复杂的一点是:两个文件中同名类中可以有同名变量,而ns中却不可以。因为ns作用域是跨文件的。而在类内部的话,类的作用域是不跨文件的。
 
 
 
 
 
                   
                   
                   
                   
                             本文介绍了C和C++中static关键字的作用。在C++里,static局部变量有“记忆性”和生存期“全局性”,可记录函数调用次数、改善返回局部对象指针问题,但有不可重入性。在C中,static可限制全局变量和函数作用域在本文件内,使用内部函数可避免函数重名。
本文介绍了C和C++中static关键字的作用。在C++里,static局部变量有“记忆性”和生存期“全局性”,可记录函数调用次数、改善返回局部对象指针问题,但有不可重入性。在C中,static可限制全局变量和函数作用域在本文件内,使用内部函数可避免函数重名。
           
       
           
                 
                 
                 
                 
                 
                
               
                 
                 
                 
                 
                
               
                 
                 扫一扫
扫一扫
                     
              
             
                   396
					396
					
 被折叠的  条评论
		 为什么被折叠?
被折叠的  条评论
		 为什么被折叠?
		 
		  到【灌水乐园】发言
到【灌水乐园】发言                                
		 
		 
    
   
    
   
             
            


 
            