引言
C/C++面试常见问题,关键字static的用法,在这里稍作整理和温习。
C——静态局部变量
用于函数体内部修饰变量,这种变量的生存期长于该函数。这与变量所在的内存区域有很大的关系。我们知道编译器自动分配的内存区域,如局部变量、函数参数,都在栈区,会随着作用域退出而释放空间。用户分配的区域在堆空间。全局数据区(静态区),全局变量和静态变量就存在一起,初始化的全局变量和静态变量在一个区域,未初始化的全局变量和未初始化的静态变量在另一块区域,程序结束时自己释放。
函数结束后,静态局部变量的内存空间不会被销毁,仍然保留原值,下一次调用仍然是上一次的值。如下测试用例:
#include <iostream>
using namespace std;
void show_average(double x){
static double num=0;
static double sum=0;
num+=1;
sum+=x;
cout<<"num="<<num<<", sum="<<sum<<", avg="<<sum/num<<endl;
}
int main() {
double entry=0;
for(;;){
cout<<"Enter a number: ";
cin>>entry;
if(entry<0) break;
show_average(entry);
}
return 0;
}
如图所示,不断调用函数,num和sum的值会在第一次调用时被初始化为0,之后不再进行初始化,而是保留原始,所以结果会进行不断的叠加。
小结:
1、静态局部变量存储在静态存储区
2、静态局部变量在函数结束后内存空间不会被回收,下次使用时可以保留上一次的计算结果,这与全局变量很相似,但是作用范围不同
3、静态局部变量如果没有初始化,编译器默认为0或NULL
C——静态全局变量
静态全局变量只能在它所声明的源文件中使用,不能被extern引用
静态全局变量与全局变量的区别:生命周期不变,作用域缩小
C——静态函数
在C语言中,第一个函数声明为static,主要目的也是为了进行文件隔离,即其只在本文件内是可用的,设想一个大型项目多是有很多人一起完成,使用static声明就不用担心别人定义的函数与自己的重名,因为,只在本文件可用。静态函数位于一块存储区长期存在,知道应用程序结束,在调用时直接读取相应的内存,不需要进行出栈、压栈操作,效率较高。而C++中由于类的引入,类的静态成员函数与此不同,稍后请看。
C++类静态成员
访问方式:
1、类名::静态成员名(建议此种,因为静态成员属于整个类,而不是某个特定的对象)
2、对象名.静态成员名
类的静态成员必须在类外进行初始化,否则会出现链接错误。
#include <iostream>
#include <string.h>
using namespace std;
class Employee{
public:
Employee(char* n);
void print() const;
private:
char name[50];//姓名
static int id_Num;//员工序号
};
int Employee:: id_Num=0;//类外初始化static变量
Employee::Employee(char *n) {
id_Num++;
strcpy(name,n);
}
void Employee::print() const {
cout<<name<<" "<<id_Num<<endl;
}
int main() {
//
Employee p1("lily");
p1.print();
Employee p2("bob");
p2.print();
return 0;
}
C++静态成员函数
静态成员函数只能用于操作静态成员变量。(静态成员函数是类公用的,没有对象也可以使用,不能用于访问某个特定对象的非静态成员)
普通成员函数即可以访问静态成员,也可以访问非静态成员。
总结
类的静态成员变量和非静态成员变量的区别:
每一个对象的非静态成员变量在内存中保留一个空间来存储各自的值,即每一个对象的非静态成员都有自己的空间,而类的静态成员,整个类只有一份,所有对象共享此空间。
类的静态成员函数只能访问静态成员。