这周的大部分时间都花了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的用法全局变量与局部变量 - 滴巴戈 - 博客园

C++ 语法篇之 static 用法相关推荐

  1. 【教程】PHP快速学习教程(语法篇)

    [教程]PHP快速学习教程(语法篇) 备注 一.环境搭建 1.phpstudy一键搭建 2.apache+php+mysql手动配置 <1>apache加载php <2>php ...

  2. vue引用自定义.js文件 (常量抛出 + 地址三级联动为例)- 语法篇

    文章目录 vue如何引用`自定义封装的` `.js`文件? `如何操作,详细如下.`(注意代码注释部分:注意1/2/3/4/5) 一.效果图预览: 二.以自定义`area.min.js`文件为例: 三 ...

  3. vue引用自定义.css文件 - 语法篇

    vue如何引用外部自定义的.css文件 ? 一般都会因为存在权重或优先级设置的问题才会侧意引用: [详情进入查看:如何在scoped不污染组件样式的前提下,实现el-input组件样式覆盖?] 再者, ...

  4. mysql select high_priority_MySQL进阶SELECT语法篇

    MySQL进阶SELECT语法篇 2019-09-29 编程之家收集整理的这篇文章主要介绍了MySQL进阶SELECT语法篇,编程之家小编觉得挺不错的,现在分享给大家,也给大家做个参考. MysqL中 ...

  5. ①(语法篇)、《史上最全iOS八股文面试题》2022年,金三银四我为你准备了,iOS《1000条》笔试题以及面试题(包含答案)。带面试你过关斩将,(赶紧过来背iOS八股文)

    iOS面试题 一共分为笔试题和面试题两部分 笔试题 一共分为10个 总共613题 面试题 一共400题 笔试题 一个10个系列 分别为 ①(语法篇) 共147题 已更新 ②(常识篇) 共72题 已更新 ...

  6. Flex 布局教程:语法篇

    阮一峰的网络日志 » 首页 » 档案 上一篇:ES6 的功能侦测库 下一篇:Flex 布局教程:实 分类: 开发者手册 Flex 布局教程:语法篇 作者: 阮一峰 日期: 2015年7月10日 网页布 ...

  7. GoogleHacking 语法篇

    GoogleHacking 语法篇 欢迎使用Markdown编辑器 这个是我第一次开通,也是一位小白,我的博客只不过是保存自己的一些问题技术,想找的话就不会满世界找了哈哈哈哈 常用GoogleHack ...

  8. Vue——基础语法篇

    Vue--基础语法篇 author:木子六日 学习视频来源 coderwhy老师的vue教学 文章目录 Vue--基础语法篇 author:木子六日 学习视频来源 01.hello vue 02.vu ...

  9. Vue.js学习笔记 01、Vue基本语法篇

    文章目录 前言 1.基础学习 1.1.第一个vue:helloworld(template以及mount()使用) 1.2.编写计数器(mounted应用) 1.3.vue的绑定事件和事件方法(v-o ...

  10. Android实战开发-Kotlin教程(语法篇 1.2)

    上一篇我们介绍了Kotlin语法的一些基础用法,本章我们来学习一下Kotin的语法知识 if表达式 if表达式在开发过程中最常见的判断表达式 if后面的括号代表判断的条件表达式,如条件表达式的结果为t ...

最新文章

  1. dsp处理浮点数_关于IQMATH和浮点数在DSP的深入理解
  2. 将Iterable转换为Collection的简便方法
  3. Oracle优化01-引起数据库性能问题的因素
  4. export default 和 export 区别(ES6)
  5. JEP 181不兼容,嵌套类/ 2
  6. 关于单元测试脚手架的几点思考
  7. ???--???二进制变换
  8. 归并python_python基本算法之实现归并排序(Merge sort)
  9. mysql xml字段转json格式_mysql将xml数据或者json数据转换为表格。
  10. matlab 最优化编程,Matlab最优化编程例子
  11. Latex学习笔记 (5) 通用长度单位
  12. 硬件编码相关知识(H264,H265),IPB分别压缩率/H265/H264压缩率
  13. Android Studio实现百度地图定位(显示经纬度和地址)
  14. 9 客户端认证方式 之 PKCE
  15. 激活pytorch环境
  16. 启动VMware虚拟机显示:物理内存不足无法使用
  17. 利用微信公共号的带参数二维码做(扫码登录)
  18. 去耦电容:10uF电容与0.1uF问题
  19. android 旋转屏幕 不重走生命周期,屏幕旋转后Activity生命周期
  20. 微信小程序 用户登录界面,用户名无法切换输入法问题解决方法

热门文章

  1. java十大经典排序
  2. c# 贪婪匹配 html,C#正则表达式之贪婪模式
  3. 解析 URP 教务系统, 创建查成绩 APP !
  4. 16、TFT-LCD 1.8寸显示屏使用
  5. 我花三个月看了200G×××教程,领悟了你的×××为什么不赚钱!
  6. 被华策、欢瑞等甩下,唐人影视往日荣光已成回忆?
  7. 视频监控直播项目经验总结
  8. 百度地图定位不准的问题
  9. Hexo+腾讯云+Icarus主题 搭建自定义个人博客
  10. Javaweb生成族谱树形图