static变量和函数(c/c++)
参考博文https://www.cnblogs.com/yujianfei/p/8974813.html
https://www.cnblogs.com/codingmengmeng/p/5906282.html
https://blog.csdn.net/guotianqing/article/details/79828100
c语言static关键字用法:
1. 局部变量
普通局部变量存储于进程栈空间,使用完毕会立即释放。
静态局部变量使用static修饰符定义,即使在声明时未赋初值,编译器也会把它初始化为0。且静态局部变量存储于进程的全局数据区,即使函数返回,它的值也会保持不变。变量在全局数据区分配内存空间;编译器自动对其初始化 ,其作用域为局部作用域,当定义它的函数结束时,其作用域随之结束。
int f(int n) { static int s=1; s=s*n; return s; }
main(){ int i; for(i=1;i<=5;i++) f(i); }
以上程序利用静态变量的性质,求出5!,然使用静态变量会消耗更多的内存,同时程序可读性降低,所以不多用;
2. 全局变量
全局变量定义在函数体外部,在全局数据区分配存储空间,且编译器会自动对其初始化。
普通全局变量对整个工程可见,其他文件可以使用extern外部声明后直接使用。也就是说其他文件不能再定义一个与其相同名字的变量了。
静态全局变量仅对当前文件可见,其他文件不可访问,其他文件可以定义与其同名的变量,两者互不影响。static关键字能够有效地降低程序模块之间的耦合,避免不同文件同名变量的冲突。
面向对象
1.静态数据成员
静态变量的定义:前面加关键字static
静态变量的初始化:<数据类型><类名>::<静态数据成员名>=<值> (需在类外进行)
必须对它进行初始化
引用静态数据成员时,采用如下格式:<类名>::<静态成员名>
2.静态成员函数
非静态成员函数对静态成员的调用不需要对象名
非静态成员函数不能直接引用静态成员,需通过对象引用
需要注意的几点:
1.静态成员变量在对象创建之前就已经被分配了内存空间
2.静态成员变量虽然在类中,但它并不是随对象的建立而分配空间的,也不是随对象的撤销而释放
3.但是静态成员函数没有this指针,不知道应该访问哪个对象中的数据,所以在程序中不可以用静态成员函数访问类中的普通变量
4.类的对象可以使用静态成员函数和非静态成员函数。
class StaticTest 2 { 3 public: 4 StaticTest(int a, int b, int c); 5 void GetNumber(); 6 void GetSum(); 7 static void f1(StaticTest &s); 8 private: 9 int A, B, C; 10 static int Sum; 11 }; 12 13 14 15 #include "StaticTest.h" 16 #include <iostream> 17 using namespace std; 18 19 int StaticTest::Sum = 0;//静态成员在此初始化 20 21 StaticTest::StaticTest(int a, int b, int c) 22 { 23 A = a; 24 B = b; 25 C = c; 26 Sum += A + B + C; 27 } 28 29 void StaticTest::GetNumber() 30 { 31 cout << "Number = " << endl; 32 } 33 34 void StaticTest::GetSum() 35 { 36 cout << "Sum = " << Sum <<endl; 37 } 38 39 void StaticTest::f1(StaticTest &s) 40 { 41 42 cout << s.A << endl;//静态方法不能直接调用一般成员,可以通过对象引用实现调用 43 cout << Sum <<endl; 44 } 45 46 #include "StaticTest.h" 47 #include <stdlib.h> 48 49 50 int main(void) 51 { 52 StaticTest M(3, 7, 10), N(14, 9, 11); 53 M.GetNumber(); 54 N.GetSum(); 55 M.GetNumber(); 56 N.GetSum(); 57 StaticTest::f1(M); 58 system("pause"); 59 return 0; 60 }
总结: static的优势:
1.不考虑类:不想破坏变量的访问范围(只收一个函数控制),将上次函数调用的值保存到下次函数的使用;
2.考虑类:节省内存,对多个对象静态数据成员只存储一处,供所有对象使用,及不破坏类的封装性,又可以让所有对象使用更新后的值,提高时间和空间效率。