当前位置: 首页 > news >正文

【C语言】static关键字用法

目录

一、static修饰局部变量

二、static修饰全局变量

三、static修饰函数


一、static修饰局部变量

首先我们来看两段代码:

  • 代码1(不加static)
#include <stdio.h>
void test()
{int i = 0;i++;printf("%d ", i);
}
int main()
{int i = 0;for (i = 0; i < 5; i++){test();}return 0;
}

运行结果如下:

  • 代码2(加static)
#include <stdio.h>
void test()
{static int i = 0;i++;printf("%d ", i);
}
int main()
{int i = 0;for (i = 0; i < 5; i++){test();}return 0;
}

运行结果如下:

对比以上两段代码,我们发现:

  • 代码1:运行结果分析可知,test函数的局部变量i在每次进入test函数的时候都会重新创建并赋值为0,出函数的时候销毁。
  • 代码2:运行结果可知,被static修饰过后的i,它的值是有累加效果的,在头一次进入test函数后,创建了i后,出函数是不会被销毁的。再次进入函数也不会重新创建变量,而是累积上次的数值继续计算。

出现结果2的原因:

  1. static修饰局部变量的时候,局部变量出了作用域是不会被销毁的。
  2. 不被销毁的原因是:static修饰的局部变量,本质上是改变了变量的存储位置。
  3. 存储位置的改变,实质上影响了变量的生命周期,生命周期变得跟程序的生命周期一样了,只有程序结束,变量才销毁,内存才回收。
  4. 但是变量i的作用域是不变的

由上图可知:

  • 栈区的数据特点是:进作用域创建,出作用域销毁。
  • static修饰之后叫静态变量,静态变量是存放在静态区的,放在静态区的数据出了它的作用域不销毁,只有在整个程序结束的时候跟着一起销毁。
  • 一旦变量创建之后,在整个程序执行过程中,它是不会换位置的,不会重新开辟空间。只不过本来在栈区,static修饰就在静态区。

使用建议:未来一个变量出了函数后,我们还想保留值,等下次进入函数继续使用,就可以使用static。

二、static修饰全局变量

全局变量的作用域是整个工程,它可以在另外源文件内部使用。

如下:

当用static修饰全局变量时,则会报错。如下:

出现错误的原因:

  1. 一个全局变量被static修饰,使得这个全局变量只能在本源文件内使用,不能在其他源文件内使用。
  2. 本质原因是全局变量默认是具有外部链接属性的,在外部的文件中想使用,只要适当的声明就可以。
  3. 当static修饰全局变量时,外部链接属性就变成了内部链接属性,其他源文件(.c)即使声明了,也不能使用这个全局变量。
  4. 但是这个全局变量可以在自己的源文件中正常使用,比如在它自己的add.c文件就可正常使用。

使用建议:如果一个全局变量,只想在所在的源文件内部使用,不想被其他文件发现,就可以使用static修饰。

三、static修饰函数

我们先看一下下面两段代码

代码1(不加static)

该位置能够调用函数是因为:函数也默认具有外部链接属性,只要适当声明,就可以在整个工程都使用

代码2(加static)

可以发现,当函数被static修饰之后,就发生了链接错误。

原因:

如果一个函数被static修饰,外部链接属性就变成了内部链接属性,其它源文件(.c)就不能再使用该函数,只能在自己所在的源文件内部使用。

使用建议:一个函数只想在所在的源文件内部使用,不想被其他源文件使用,就可以使用static来修饰。

相关文章:

  • 【每日刷题】Day61
  • bigtop-3.4.0-SNAPSHOT ubuntu22.04打包
  • [2024-06]-[大模型]-[Ollama] 0-相关命令
  • 系统架构设计师重难点知识脑图
  • 启明智显工业级HMI芯片Model3功耗特性分享
  • LabVIEW2017破解安装教程
  • vue2前置路由守卫中使用this.$store.state报错解决
  • Django前端页面-模板继承
  • opencv 在飞行堡垒8中调用camera导致设备消失
  • 纹理贴图必须要输入顶点坐标或纹理坐标吗
  • 如何免费获取云服务器
  • Vue09-事件处理
  • 【鸿蒙开发】HarmonyOS开发 URL动态路由设计
  • Mac环境下,简单反编译APK
  • 探索未来制造,BFT Robotics引领潮流
  • android百种动画侧滑库、步骤视图、TextView效果、社交、搜房、K线图等源码
  • Centos6.8 使用rpm安装mysql5.7
  • CSS实用技巧干货
  • ES6, React, Redux, Webpack写的一个爬 GitHub 的网页
  • JS 面试题总结
  • Js实现点击查看全文(类似今日头条、知乎日报效果)
  • Redux 中间件分析
  • 从setTimeout-setInterval看JS线程
  • 对JS继承的一点思考
  • 对话 CTO〡听神策数据 CTO 曹犟描绘数据分析行业的无限可能
  • 猫头鹰的深夜翻译:Java 2D Graphics, 简单的仿射变换
  • 面试遇到的一些题
  • 名企6年Java程序员的工作总结,写给在迷茫中的你!
  • 通过获取异步加载JS文件进度实现一个canvas环形loading图
  • 为视图添加丝滑的水波纹
  • 协程
  • 掌握面试——弹出框的实现(一道题中包含布局/js设计模式)
  • Python 之网络式编程
  • Unity3D - 异步加载游戏场景与异步加载游戏资源进度条 ...
  • 积累各种好的链接
  • ​猴子吃桃问题:每天都吃了前一天剩下的一半多一个。
  • #APPINVENTOR学习记录
  • #QT(TCP网络编程-服务端)
  • #stm32整理(一)flash读写
  • #我与Java虚拟机的故事#连载01:人在JVM,身不由己
  • #我与Java虚拟机的故事#连载07:我放弃了对JVM的进一步学习
  • (02)Cartographer源码无死角解析-(03) 新数据运行与地图保存、加载地图启动仅定位模式
  • (Mac上)使用Python进行matplotlib 画图时,中文显示不出来
  • (Note)C++中的继承方式
  • (补充)IDEA项目结构
  • (附源码)springboot车辆管理系统 毕业设计 031034
  • (附源码)springboot工单管理系统 毕业设计 964158
  • (接口封装)
  • (力扣)1314.矩阵区域和
  • (没学懂,待填坑)【动态规划】数位动态规划
  • (三)centos7案例实战—vmware虚拟机硬盘挂载与卸载
  • (十二)springboot实战——SSE服务推送事件案例实现
  • (一)VirtualBox安装增强功能
  • (转)nsfocus-绿盟科技笔试题目
  • (转载)OpenStack Hacker养成指南