C++ 语法篇之 static 用法

这周的大部分时间都花了debug上,,在费了一番周折才debug成功之后发现原来是static局部变量搞得鬼。我意识到原来我对于static的用法理解地还不够透彻,所以想结合这个例子再总结一下。希望在今后的coding中,不在同一个地方跌倒。

下边是错误代码的示例:

Class A{
    int foo1(int a);
};
int A::foo1(int a){
    static int i = A_ARRAY[a]; // int i = A_ARRAY[a];
    // 业务代码若干
    return i;
}
const int A_ARRAY[8]={1,2,3,4,5,6,7,8}; 

在 A::foo1(int a)中,我本意是想通过参数 a 来更新变量 i 的值,但是由于忽视了static在修饰静态局部变量时只能初始化一次,便出现 i 的值在初始化后无法更新的情况。正确的代码应该去掉static修饰符。

但是在软件实际运行过程中,在绝大多数情况下,变量 i 的值在初始化之后便无需更新了。而在某一项极端的测试用例下,出现死机的现象,而在这一用例下发现初始化后的 i 是需要再次更新的。

上边便是我debug的血泪史。其实总结下来,static主要有以下用法:

  1. 在修饰变量的时候,static 修饰的静态局部变量只执行初始化一次,而且延长了局部变量的生命周期,直到程序运行结束以后才释放。
  2. static 修饰全局变量的时候,这个全局变量只能在本文件中访问,不能在其它文件中访问,即便是 extern 外部声明也不可以。
  3. static 修饰一个函数,则这个函数的只能在本文件中调用,不能被其他文件调用。static 修饰的变量存放在全局数据区的静态变量区,包括全局静态变量和局部静态变量,都在全局数据区分配内存。初始化的时候自动初始化为 0。
  4. 不想被释放的时候,可以使用static修饰。比如修饰函数中存放在栈空间的数组。如果不想让这个数组在函数调用结束释放可以使用 static 修饰。
  5. 考虑到数据安全性(当程序想要使用全局变量的时候应该先考虑使用 static)。

脑海中的理解并不算真正的理解,只有实现出来才是真的。 

Talking is cheap  Show me the code

假如我们有A.cpp, A.h。

A.cpp

#include "A.h"

static int b = 666; //静态全局变量 
static int foo1(void); //静态全局函数

int foo1(void){
    b++;
    return 0;
}

 A.h

#ifndef A_H_
#define A_H_

extern int b; 

#endif

针对上边提到的 static 的5个用法,我逐一举例说明。

第一条便是我的例子。

第二条可以拿 A.cpp 中的 static int b 举例。假如 B.cpp 引用了 A.h,  b 虽然在 A.h 中有 b 的声明,但在B.cpp也是无法使用 b。因为 b 是全局静态变量,作用域只在 A.cpp 中。

#include "A.h"

int foo2(void){
    b++;
    return 0;
}

第三条 A.cpp 中的 foo1(void) 只能在 A.cpp 中使用,而不能在 B.cpp中引用。

第四条 由于static变量存储在静态存储区,所以在函数调用完成后不会释放变量。而如果没有static修饰符,在函数重新被调用的时候变量会被再次初始化。下边是一个简单的例子: 

#include <iostream>
using namespace std;

int foo1(void){
    static int i = 10;
    return i++;
}

int foo2(void){
    int j = 10;
    return j++;
}

int main(void){
    cout << "第一次 foo1()=" << foo1() <<endl;
    cout << "第一次 foo2()=" << foo2() <<endl;
    cout << "第二次 foo1()=" << foo1() <<endl;
    cout << "第二次 foo2()=" << foo2() <<endl;
    return 0;
}

输出结果:

第一次 foo1()=10
第一次 foo2()=10
第二次 foo1()=11
第二次 foo2()=10

 第五条 static能够保证全局变量的作用域只在当前的文件中,能够提高数据的安全性。比如 A.cpp 中的变量 b 是受到保护的,不会因为在A.h或者其他头文件中的声明而改变作用域。 

参考:C/C++中static的用法全局变量与局部变量 - 滴巴戈 - 博客园

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值