要面试了, 复习一下 c++ 的语言细节, 才发现自己差的还很多.
- static int i1=1;
- static int i2=1;
- int i3;
- static int i4;
- int main()
- {
- static int i5=1;
- int i6=1;
- int i7;
- cout<<&i1<<" "<<i1<<endl;
- cout<<&i2<<" "<<i2<<endl;
- cout<<&i3<<" "<<i3<<endl;
- cout<<&i4<<" "<<i4<<endl;
- cout<<&i5<<" "<<i5<<endl;
- cout<<&i6<<" "<<i6<<endl;
- cout<<&i7<<" "<<i7<<endl;
- getchar();
- }
输出:
首先说值:
普通 / static 全局变量 (i3) 默认初始化为 0, 普通局部变量初始值未定义(i7)
static 局部变量即静态局部变量, 也会初始化为 0
再说内存存储位置:
先放个进程的内存图:
其中未初始化 + 初始化区域就是静态区. 注意静态区和常量区还不一样, 常量比如: int a=1; 的 1. 或者 char* x="123"; 的 "123".
对应这两张图来看就很清晰了
好, 下面进入主题:
全局变量都在静态变量区, 不管是不是 static
普通局部变量在栈区 / 堆区, static 局部变量在静态变量区.
static 的不同用法:
1.static 全局变量 / 函数, 因为函数肯定是全局的了, 所以这俩捏一起说.
只有一个用途: 不让其他 cpp 使用自己, 即限制作用域为所在的 cpp. 如果不带 static, 其他 cpp 可以 extern 修饰进而引用.
所以假设 a.cpp 里有一个函数 f.
如果我们想让其他 cpp 引用这个 f 函数. 那么我们应该把 f 的声明加入到 a.cpp 的头文件并且声明时不要加 static, 这样会导致每个包含 a.h 的 cpp 都有一份该函数 f 的副本, 大大增加编译效率! 当然这个问题回头另外写一篇博客, 就先点到为止. 另外永远不要在头文件中定义变量!
如果我们不想让其他 cpp 引用 f 函数, 则我们直接在 f 的定义前加上 static 修饰, 这样其他 cpp 就看不到 f 函数了(即使包含 a 头文件的情况下也是看不到的).
2.static 局部变量, 如:
- void f(){
- static int cnt=0;cnt++;
- }
这个函数调用几次, cnt 就等于几.
static 局部变量和全局变量一起存在静态变量区, 二者唯一的区别就是: static 局部变量作用域只限于所在的函数, 但到达函数以外时并不会释放, 而是会保持已有的值继续等待下次调用.
static 局部变量只会初始化一次! 直到 cpp 退出才会释放.
3. 类中的 static 成员变量(类的静态成员变量):
在所有该类的实例 (对象) 中只存在一个副本, 所有对象共享一个该静态变量.
类的静态成员变量需要在类中声明, 类外定义, 例子如下:
- class A{
- static int x;
- };
- int A::x=1;
4. 类中的 static 成员函数:
只能调用静态成员变量, 别的和普通成员函数区别不大.
概括来说: 类的静态成员函数, 变量的存储位置不在类里, 所以也就理所当然的没有 this 指针. 所以静态成员函数无法调用普通成员变量也就合理了(因为没有 this 指针, 根本找不到相应的变量位置!).
由于二者都与类绑定, 而不与特定对象绑定, 所以二者可以除了可以通过对象访问外, 还可以通过类名访问(A:: f();).
来源: http://www.bubuko.com/infodetail-3449151.html