C/C++:static用法总结
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C/C++:static用法总结相关的知识,希望对你有一定的参考价值。
前言:static是C/C++中一个很重要的关键字,最近阅读了很多博客和资料,遂在此对自己的学习笔记进行简单的总结并发表在这里
一、C语言中的static
? 静态全局变量:在全局变量之前加上关键字static,该全局变量就被定义成了一个静态全局变量
特别注意:
1.静态全局变量在内存中的存储位置:静态区(全局区)。 [注]:静态区(全局区)在整个程序运行期间都存在
2.静态全局变量的初始化:未经初始化的静态全局变量会被程序自动初始化为0。 [注]:在C语言中,未经初始化的全局变量的值是任意的;而在C++中,未经初始化的全局变量也会被程序自动初始化为0
3.全局变量和静态全局变量的存储方式是一样的,但不同的是全局变量在整个源代码中都是可以使用的,而静态全局变量只能在当前文件中使用。比如一个程序有3个文件a.cpp、b.cpp和c.cpp,如果在文件a.cpp中定义了一个全局变量x,那么变量x在文件a.cpp、b.cpp和c.cpp中都可以使用;但如果在文件a.cpp中定义了一个静态全局变量y,那么变量y只能在文件a.cpp中使用文件b.cpp和文件c.cpp都不可以使用该静态全局变量y
源文件file1.cpp:
1 // 文件file1.cpp 2 int value1=10;//全局变量value1 3 static int value2;//静态全局变量value2,默认初始化为0 4 ......
源文件file2.cpp:
1 // 文件file2.cpp 2 extern int value1; //成功:期望使用文件file1中定义的全局变量value1 3 extern int value2; //错误:期望使用文件file1中定义的静态全局变量value2,但value2是static类型,只能在file1中使用,无法被其他文件使用 4 ......
4.使用静态全局变量的好处:
a.将一个全局变量定义为静态全局变量,相当于让该全局变量对该程序的其他源文件进行了“隐藏”,也就是说该静态全局变量只能在定义它的源文件中使用,而程序的其他源文件则无法访问该变量
b.程序中的其他源文件中可以使用与该静态全局变量同名的变量,而不会发生冲突
5.在C/C++程序中,如果一个全局变量仅仅在单个源文件中使用,则可以将该全局变量修改为静态全局变量,以降低模块间的耦合度
? 静态局部变量:在局部变量之前加上关键字static,该局部变量就被定义成了一个静态局部变量
特别注意:
1.静态局部变量在内存中的存储位置:静态区(全局区)。[注]:普通局部变量在内存中的存储位置为栈区
2.静态局部变量的初始化:未经初始化的静态局部变量会被程序自动初始化为0。[注]:在C/C++中,未经初始化的普通局部变量值是任意的
3.static并没有改变局部变量的作用域。换句话说就是静态局部变量的作用域仍是局部作用域,当定义它的函数或语句块结束的时候,其作用域也就随之结束。 [注]:与之相反,static改变了全局变量的作用域(在声明它的文件之外是不可见的)
4.static虽然没有改变局部变量的作用域,但它改变了局部变量在内存中的存储位置(而static修饰的全局变量在内存中的存储位置则没有被static改变),即从原来的栈区中存放改变为静态区(全局区)中存放。因此静态局部变量在离开其作用域时,并没有像一般局部变量那样被销毁,而是仍驻留在内存中的静态区(全局区)中,直到程序结束,只不过在其离开自己的作用域时,我们无法再对其进行访问。
1 #include<iostream> 2 using namespace std; 3 int count=1; 4 int fun(){ 5 static int count=10; 6 return count--; 7 } 8 int main(){ 9 cout<<"Global\\tLocal Static"<<endl; 10 for(int i=1;i<=10;i++){ 11 cout<<" "<<count++<<"\\t "<<fun()<<endl; 12 } 13 return 0; 14 }
5.在C/C++中,如果全局变量仅有单个函数访问,则可以将该全局变量改为该函数的静态局部变量,以降低模块间的耦合度
? 静态函数:在函数的返回值类型前加上关键字static,该函数就被定义成了一个静态函数
特别注意:
1.和静态全局变量相似,静态函数只能在声明它的源文件中可见,而不能被该程序的其他源文件所使用。
源文件file1.cpp:
1 //文件file1.cpp 2 ...... 3 extern void fun1(){......} //定义函数fun1 4 static void fun2(){......} //定义静态函数fun2 5 ......
源文件file2.cpp:
1 //文件file2.cpp 2 ...... 3 extern void fun1();//成功:期望使用文件file1.cpp中的函数fun1 4 extern void fun2();//错误:期望使用文件file1.cpp中的静态函数fun2,但fun2是static类型函数,只能在file1中使用,无法被其他文件使用
2.使用静态函数的好处:
a.在该程序的其他源文件中可以定义和使用与该静态函数同名的函数,而不会发生冲突
b.将一个普通函数定义为函数,相当于让该函数对该程序的其他源文件进行了“隐藏”,也就是说该静态函数只能在定义它的源文件中使用,而程序的其他源文件则无法调用该函数。
c.静态函数会被自动分配在一个一直使用的存储区域,直到程序结束。这样避免了普通函数在调用时的进栈出栈操作,从而提高程序的运行速度
? 总结:static在C语言中的作用:
——隐藏功能:static修饰的全局变量和普通函数只能在定义它们的源文件中使用,相当于对程序中的其他源文件进行了隐藏
——默认初始化功能:static修饰的变量,不管是全局变量还是局部变量,在用户没有显式初始化它们的条件下,系统都会将他们默认初始化为0
——延长“寿命”功能:static修饰的局部变量存储在内存的静态区(全局区)而非栈区,而静态区中存储的内容只会在程序结束时被OS释放,因此当static修饰的局部变量离开自己的作用域时,其不会像一般局部变量那样被系统销毁,而是一直驻留在系统的内存中,直到程序结束。
二、C++中的static
? 静态数据成员:自定义类中被static修饰的成员变量
特别注意:
1.静态数据成员在内存中的存储位置:静态区(全局区)
2.使用:
语法:类名::静态数据成员名
3.静态数据成员属于类。换句话说就是类的静态数据成员为其所有对象所共享,不管该类有多少对象,静态数据成员只有一份存储于公共的内存中
1 #include<iostream> 2 #include<string> 3 using namespace std; 4 class Student{ 5 public: 6 static int count;//记录该类的对象的个数 7 Student(){ 8 count++; 9 } 10 Student(string name,int age):Name(name),Age(age){ 11 count++; 12 } 13 ~Student(){ 14 count--; 15 } 16 private: 17 string Name; 18 int Age; 19 }; 20 int Student::count=0; //对count进行初始化 21 int main(){ 22 Student stu1("Tomwenxing",23); 23 Student stu2("Ellen",22); 24 Student stu3("Jack",24); 25 cout<<"Student类的对象的个数:"<<Student::count<<endl; 26 return 0; 27 }
? 静态成员函数:自定义类中被static修饰的成员函数
特别注意:
1.在C++的自定义类中,一个常规的成员函数声明往往意味着:
? 该成员函数能够访问其所在类的私有部分
? 该成员函数位于其所在类的作用域之中
? 该成员函数必须由一个对象去激活从而被调用(通过this指针来实现)
如果将该类的一个成员函数声明为static,则可以只让它拥有前两种性质
2.使用:
语法1:类名::静态成员函数名
语法2:对象名.静态成员函数名
3.和静态数据成员一样,静态成员函数也属于类,即类的静态成员函数为其所有对象所共享。
4.类中的普通成员函数既可以访问一般成员变量,也可以访问静态数据成员;而类中的静态成员函数只能访问类中的静态数据成员。
[解释]:编译器在编译程序中的自定义类时,会在类中的每个普通成员函数中插入this指针,而对static修饰的静态成员函数则不会插入this指针。由于静态成员函数中没有this指针,因此静态成员函数无法在其函数体内访问非静态数据成员;相反,由于静态数据成员属于类而非特定对象,故不需要this指针也可以在函数体内访问静态数据成员,因此不管是普通成员函数还是静态成员函数,都可以在其函数体内访问静态数据成员。
5.同理,普通成员函数中可以调用静态成员方法,而静态成员方法中不能调用普通成员函数
1 #include<iostream> 2 #include<string> 3 using namespace std; 4 class Student{ 5 public: 6 static int count; //静态数据成员 7 Student(){ 8 count++; 9 } 10 Student(string name,int age):Name(name),Age(age){ 11 count++; 12 } 13 ~Student(){ 14 count--; 15 } 16 void show1(); 17 static void show2(); 18 private: 19 string Name; 20 int Age; 21 22 }; 23 int Student::count=0; //对count进行初始化 24 /* 25 编译器对成员函数show1的改写: 26 void Student::show1(Student* const this){ 27 cout<<"Name:"<<this->Name<<endl; 28 cout<<"Age:"<<this->Age<<endl; 29 cout<<"Count:"<<count<<endl; 30 show2(); 31 */ 32 void Student::show1(){ 33 cout<<"调用了方法show1"<<endl; 34 cout<<"Name:"<<Name<<endl; 35 cout<<"Age:"<<Age<<endl; 36 cout<<"Count:"<<count<<endl; 37 show2();//在普通成员函数中调用静态成员函数 38 } 39 void Student::show2(){ //编译器不会为静态成员函数添加this指针 40 cout<<"调用了方法show2"<<endl; 41 //cout<<"Name:"<<Name<<endl; //错误:静态成员函数不能访问非静态数据成员 42 //cout<<"Age:"<<Age<<endl; //错误:静态成员函数不能访问非静态数据成员 43 //show1(); //错误:静态成员函数中不能调用普通成员函数 (只能以this->show1()的形式调用) 44 cout<<"Count:"<<count<<endl; 45 } 46 int main(){ 47 Student stu1("Tomwenxing",23); 48 Student stu2("Ellen",22); 49 Student stu3("Jack",24); 50 stu3.show1(); 51 cout<<"----------分界线----------------"<<endl; 52 stu2.show2();//可以通过对象来调用静态成员函数 53 cout<<"----------分界线----------------"<<endl; 54 Student::show2() ;//也可以通过类来调用静态成员函数 55 return 0; 56 }
以上是关于C/C++:static用法总结的主要内容,如果未能解决你的问题,请参考以下文章