写在前面(领会下面五句话即可):
C:
1. static修饰函数中的变量(栈变量):改变变量的生存期,作用域不变仍为所在函数。 只被初始化一次。
2. static修饰全局变量:限制全局变量只能被模块内访问,不可以在别的模块中用extern声明调用。
3. static修饰函数:作用与修饰全局变量类似,也是限制该函数只能在模块内访问,不能再别的模块中用extern声明调用
C++:
1. static静态数据成员属于整个类所有,类的所有对象共同维护。
2. static静态函数成员也属于整个类,一般用于调用静态数据成员,不能直接访问非static成员(要指定类才行)。
一、C中的static关键字
- #include<iostream.h>
- void fn();
- extern int n;
- void main()
- {
- n=20;
- cout << n << endl;
- fn();
- }
-
- //file2.cpp
- #include<iostream.h>
-
- static int n; //定义静态全局变量,初始化为0;
- void fn()
- {
- n++;
- cout << n << endl;
- }
- void fn();
- void staticFn()
-
- void main()
- {
-
- fn();
- staticFn();
- }
-
- //file2.cpp
- #include<iostream.h>
-
- static void staticFn();
- void fn();
-
- void fn()
- {
- staticFn();
- cout << "this is fn() \n";
- }
-
- void staticFn()
- {
- cout << "this is staticFn() \n";
- }
二、C++中的static关键字
- class base{
- public :
- static int _num;//声明
- };
- int base::_num=0;//静态数据成员的真正定义
-
- class derived:public base{
- };
-
- main()
- {
- base a;
- derived b;
- a._num++;
- cout<<"base class static data number _num is"<<a._num<<endl;
- b._num++;
- cout<<"derived class static data number _num is"<<b._num<<endl;
- }
- class base{
- public :
- static int _num;//声明
- };
- int base::_num=0;//静态数据成员的真正定义
-
- class derived:public base{
- };
-
- main()
- {
- base a;
- derived b;
- a._num++;
- cout<<"base class static data number _num is"<<a._num<<endl;
- b._num++;
- cout<<"derived class static data number _num is"<<b._num<<endl;
- }
- class base{
- public :
- static base _object1;//正确,静态数据成员
- base _object2;//错误
- base *pObject;//正确,指针
- base &mObject;//正确,引用
- };
- class base{
- public:
- base(){_i=0;_val=0;}
-
- mutable int _i;
- static int _staticVal;
- int _val;
- void test() const{//const 成员函数
-
- _i++;//正确,mutable数据成员
- _staticVal++;//正确,static数据成员
- _val++;//错误
-
- }
- };
- int base::_staticVal=0;
A、静态成员函数与类相联系,不与类的对象相联系。
B、静态成员函数不能访问非静态数据成员。原因很简单,非静态数据成员属于特定的类实例。
作用:
主要用于对静态数据成员的操作。
调用形式:
A、类对象名.静态成员函数名()
B、类类型名:: 静态成员函数名()
- class base{
- static int func1();
- int func2();
- };
-
- int (*pf1)()=&base::func1;//普通的函数指针
- int (base::*pf2)()=&base::func2;//成员函数指针
- class base{
- virtual static void func1();//错误
- static void func2() const;//错误
- static void func3() volatile;//错误
- };
扩展分析:
术语static有着不寻常的历史.起初,在C中引入关键字static是为了表示退出一个块后仍然存在的局部变量。随后,static在C中有了第二种含义:用来表示不能被其它文件访问的全局变量和函数。为了避免引入新的关键字,所以仍使用static关键字来表示这第二种含义。最后,C++重用了这个关键字,并赋予它与前面不同的第三种含义:表示属于一个类而不是属于此类的任何特定对象的变量和函数(与Java中此关键字的含义相同)。
全局变量、静态全局变量、静态局部变量和局部变量的区别
变量可以分为:全局变量、静态全局变量、静态局部变量和局部变量。
(1) 按存储区域分,全局变量、静态全局变量和静态局部变量都存放在内存的静态存储区域,局部变量存放在内存的栈区。
(2) 按作用域分, 全局变量在整个工程文件内都有效;静态全局变量只在定义它的文件内有效;静态局部变量只在定义它的函数内有效,只是程序仅分配一次内存,函数返回后,该变量不会消失;局部变量在定义它的函数内有效,但是函数返回后失效。
全局变量(外部变量)的说明之前再冠以static就构成了静态的全局变量。全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式。这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。
从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域, 限制了它的使用范围。
(1) static 函数与普通函数作用域不同。仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件
(2) static全局变量与普通的全局变量有什么区别:static全局变量只初始化一次,防止在其他文件单元中被引用;
(3) static局部变量和普通局部变量有什么区别:static局部变量只被初始化一次,下一次依据上一次结果值;
(4) static函数与普通函数有什么区别:static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝.
(5) 全局变量和静态变量如果没有手工初始化,则由编译器初始化为0。局部变量的值不可知。