C语言---关键字static的初步剖析

news2025/5/28 23:18:04

在这里插入图片描述

🚀write in front🚀
📝个人主页:认真写博客的夏目浅石.
🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝
📣系列专栏:凡人修C传
💬总结:希望你看完之后,能对你有所帮助,不足请指正!共同学习交流 🖊
✉️如果无聊的话,就来逛逛我的博客栈吧stack-frame.cn

文章目录

  • 前言
  • 一、变量
    • 1.局部变量
  • 2.全局变量
  • 总结


前言

在初识C语言的过程中,static由于使用的灵活性,使我在了解这个关键字的时候十分苦恼,因此我决定来写一篇博客来帮助自己和不懂的小伙伴能更好的理解static这个关键字。如有错误,请大家指正。


提示:以下是本篇文章正文内容,下面案例可供参考

一、变量

1.局部变量

平常的局部变量想必大家都非常熟悉,具有局域临时性。即在函数调用开辟空间时并初始化,函数结束释放空间并初始化。

而局部变量存储在栈区上,使用完毕后会立即释放。(为了让大家可以理解的轻松些,下面附上C程序地址空间的图。)
在这里插入图片描述

静态局部变量也就是由static修饰定义的变量,存储于进程的全局数据区,也就是图中的未初始化全局,已初始化全局和静态数据区域。

其特点有三:

1)静态局部变量在程序执行到该对象的声明处时被首次初始化,即以后的函数调用不再进行初始化。

2)静态局部变量一般在声明处初始化,如果没有显式初始化,会被程序自动初始化为0。

3)它始终驻留在全局数据区,直到程序运行结束。但作用域为局部作用域,当定义它的函数或语句块结束时,其作用域随之结束。

而其作用是更改局部变量的生命周期。因为静态局部变量存储在全局数据区,当静态局部变量离开作用域后,并没有被销毁。当该函数再次被调用的时候,该变量的值为上次函数调用结束时的值。

让我们用一段代码来理解它的作用:

#include<stdio.h>
void test1()
{
	int i = 0;
	i++;
	printf("i=%d\n", i);
}
void test2()
{
	static int i = 0;
	i++;
	printf("i=%d\n", i);
}
int main()
{
	for (int i = 0; i < 5; i++)
	{
		test1();
		test2();
	}
	return 0;
}

在vs2022中运行结果如下:

test1
i=1
i=1
i=1
i=1
i=1
------------
test2
i=1
i=2
i=3
i=4
i=5

在调用test1函数时 ,由于i为局部变量,在test1函数执行结束后,其生命周期也就结束了,在每次调用test1函数时,i都会被赋值为0,因此输出结果为5个1;而局部变量i经static修饰后其生命周期变长,在离开作用域时并不会被销毁,当test2函数调用时,变量i的值为上次函数结束调用结束时的值,因此输出结果为1-5。

可见静态局部变量i在运行的过程中并没有被释放!!!

这也恰巧说明了static修饰的局部变量更改局部变量的生命周期。

但是请注意static并没有改变作用域!!!

我们用以下代码来证明:

加粗样式

代码中我们可以看到当fun函数调用完后,再次给a赋值发生了报错,a无法再使用了。所以static只是改变了局部变量的生命周期而并没有改变其作用域。且static修饰的局部变量而并非全局变量。

2.全局变量

与静态局部变量相似,静态全局变量就是在全局变量前加上关键字static修饰,该变量就被定义为一个静态全局变量。未经初始化的静态全局变量会被程序自动初始化为0。

静态全局变量的优点:

1)静态全局变量只能在本文件中有效且不能被其他文件所用。

2)其他文件中可以定义相同名字的变量且互不冲突。

为了让大家可以更加容易理解优点1,让我们先了解一下多文件使用:

(1)为什么使用多文件?

当我们写代码时,难免会碰到代码多,且逻辑复杂等情况,这时如果将代码全写在一个文件内,在他人阅读我们的代码时会造成一定的困难,代码的可读性低,代码十分臃肿。并且有多个函数的声明,定义,还有引用头文件,定义之类的东西,在一个文件里太过于复杂,且容易遗漏,所以衍生出来了头文件。

(2)多文件使用的注意事项

一般会有一个头文件(.h)和一个main.c和若干个源文件(.c)文件。头文件中主要用来所有变量的声明,所有函数的声明,#define,类型typedef,struct等等。main.c主要用于实现代码逻辑,其他.c用于实现头文件中声明函数的功能。但是请注意,它们都需要引用自己创建的头文件!!!(例:#include"test.h")

好了,以上就是对于多文件使用的科普,所以话不多说,我们还是接下来用例子来证明优点1吧:

全局变量的跨文件访问:
在这里插入图片描述
我们可以看到在全局变量g_val前加上static,就出现了一系列报错,test.c中定义的全局变量无法在main.c中被使用了!这也恰好证明了static修饰的全局变量不能被外部其他文件直接访问!!!

看到这可能大家会有些疑惑,你不是说静态全局变量只能在本文件内被访问吗,可你这不只证明了静态全局变量不能被跨文件访问,你是不是蒙我们啊?别急,接下来我们就来证明这个结论:

我们将test函数里面加上一行代码,看看g_val能不能被打印出来,结果是可以的。所以,静态全局变量可以在本文件内被访问。

但是请注意由于静态全局变量不能跨文件访问,在运行代码时需要将main.c中对g_val的打印需要注释掉!!!

由代码所示,在test.c中定义test_helper函数,并在test.h中声明该函数,最后在main.c中调用该函数,是没问题的。(但是请注意,无关的代码需要注释掉!!!)

函数是具有外部链接属性的,其他源文件想使用函数,需要正确的声明就可以。但是函数被static修饰,外部链接属性就变成了内部链接属性,这个时候函数只能在自己所在的.c文件内部使用,不能在外部使用。

(补充:外部链接属性 - 所有的其他文件都能找到 内部链接属性 - static 无链接属性 - 局部变量)

以上也就证明了静态函数不能被其他文件所使用,并且实现了静态函数的间接访问。


总结

static是一个很有用的关键字,因为其独特的优点,合理地使用static可以形成一个良好的编码风格。static也因其特性,也是一个对于项目维护和提供安全保证上一个强有力的帮手。作为一名程序员,养成良好的编码风格,也是十分重要的!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/628018.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构--队列2--双端队列--java双端队列

介绍 双端队列&#xff0c;和前面学的队列和栈的区别在于双端队列2端都可以进行增删&#xff0c;其他2个都是只能一端可以增/删。 实现 链表 因为2端都需要可以操作所以我们使用双向链表 我们也需要一共头节点 所以节点设置 static class Node<E>{E value;Node<E…

优化设备管理,提升企业效益——工程设备管理模板的实用价值分析

随着建筑行业的不断发展&#xff0c;建筑企业在施工过程中的各种设备也越来越多&#xff0c;设备的管理已经成为建筑企业发展过程中必须要面对的一个问题。作为低代码开发平台&#xff0c;百数根据建筑业的实际需求搭建了一款工程设备管理系统&#xff0c;从而能够让建筑行业企…

图漾相机—windows- Python SDK(官网下载编译)

文章目录 一、 安装依赖&#xff1a;二. 下载swig和SDK&#xff1a;swig下载连接&#xff1a;[https://www.swig.org/](https://www.swig.org/)下载python SDK下载 Windows Camport3 SDK 三、配置python和swig环境变量编译前&#xff0c;请先&#xff1a;安装 Python。 安装 Nu…

智慧垃圾焚烧发电厂Web3D可视化管理系统

前言 随着我国生产力的飞速发展和经济的迅速崛起&#xff0c;城市生活垃圾作为一种生物质能&#xff0c;将其燃烧用于发电&#xff0c;可以有效节约化石能源。 建设背景 随着城镇化进程加速、人民生活水平持续提升,城市生活垃圾产生量也在逐年增长。生活垃圾是“放错地方的资…

Kuboard

安装 Kuboard 之前&#xff0c;假设&#xff1a; 您已经准备好了一个 Linux 服务器用于安装 Kuboard-V3&#xff0c;并且该机器上的 docker 版本不低于 19.03用于安装 Kuboard v3.x 的机器已经安装了 docker&#xff0c;并且版本不低于 docker 19.03您已经有自己的 Kubernetes…

XXL-JOB任务分片

文章目录 任务类型任务配置路由策略阻塞处理策略&#xff1a; 单个任务和集群任务单机多任务分片集群分片 任务类型 单个任务&#xff1a;一个任务实例便可完成 单机单任务&#xff1a;单机模式下任何路由模式都只有一个实例执行 集群单任务&#xff1a;由路由策略(广播模式除…

接口自动化测试之Fiddler的运用

1.接口介绍&#xff08;基础部分&#xff09; 接口是一种用来定义程序的协议&#xff0c;它描述可属于任何类或结构的一组相关行为应用程序编程接口&#xff0c;它是一些预先定义的函数&#xff0c;目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力接口测…

开源项目合集....

likeshop开源商城系统&#xff0c;公众号商城、H5商城、微信小程序商城、抖音小程序商城、字节小程序商城、头条小程序商城、安卓App商城、苹果App商城代码全开源&#xff0c;免费商用。 适用场景&#xff1a;B2C商城、新零售商城、社交电商商城、分销系统商城、小程序商城、商…

Go单元测试及框架使用

Go自带测试框架 单元测试 建议Go 语言推荐测试文件和源代码文件放在一块&#xff0c;测试文件以 _test.go 结尾。函数名必须以 Test 开头&#xff0c;后面一般跟待测试的函数名参数为 t *testing.T 简单测试用例定义如下&#xff1a; func TestXXXX(t *testing.T) {// ...}…

城市NOA转向BEV,头部Tier 1如何笑傲江湖?

主讲&#xff5c;蒋沁宏 编辑&#xff5c;Amy 编者注&#xff1a; 本文是HiEV出品的系列直播「硬核拆解BEV」第三期问答环节内容整理。商汤绝影量产行车智能驾驶研发负责人蒋沁宏&#xff0c;与连线嘉宾寒武纪行歌自动驾驶总监李想、宏景智驾高级工程经理柴可宁、主持嘉宾周琳…

SpringBoot 源码分析初始化应用上下文(1)-createApplicationContext

前言&#xff1a;springBoot的版本是 2.2.4.RELEASE 一、入口 /*** Run the Spring application, creating and refreshing a new* {link ApplicationContext}.* param args the application arguments (usually passed from a Java main method)* return a running {link A…

2023最新版Java 面试突击手册开源(涵盖 p5-p8 技术栈)

前言: 本文收集整理了各大厂常见面试题N道&#xff0c;你想要的这里都有内容涵盖&#xff1a;Java、MyBatis、ZooKeeper、Dubbo、Elasticsearch、Memcached、Redis、MySQL、Spring、Spring Boot、Spring Cloud、RabbitMQ、Kafka、Linux 等技术栈&#xff0c;希望大家都能找到适…

【免配置】Qt的mingw使用编译opencv库

【免配置】Qt的mingw_32/64使用编译opencv库 网上在qt中使用mingw编译器配置opencv的时候&#xff0c;通常需要使用cmake编译工具&#xff0c;进行预先编译&#xff0c;步骤比较繁琐&#xff0c;这里推荐一个捷径&#xff0c;直接使用前人编译好的opencv库即可&#xff0c;避免…

软件测试金融项目,在测试的时候一定要避开的一些雷区

软件测试金融项目需要格外谨慎和专注&#xff0c;因为这些项目通常涉及大量的交易、用户隐私和其他敏感信息。以下是一些软件测试金融项目时需要关注的方面&#xff1a; 1. 数据保护 在测试金融项目时&#xff0c;必须确保用户数据和投资信息得到保护。测试人员必须确保测试环…

Flink CDC 实时mysql到mysql

CDC 的全称是 Change Data Capture &#xff0c;在广义的概念上&#xff0c;只要是能捕获数据变更的技术&#xff0c;我们都可以称之为 CDC 。目前通常描述的 CDC 技术主要面向数据库的变更&#xff0c;是一种用于捕获数据库中数据变更的技术。 mysqlcdc需要mysql开启binlog&a…

TCP报文段结构

TCP报文段结构 源端口号和目的端口号&#xff1a;含义从名字就能看出来。 序号和确认号&#xff1a;这二个字段被 TCP 发送方和接收方用来实现可靠数据传输服务&#xff0c;每个字段都是32比特。 接收窗口&#xff1a;该字段用于流量控制&#xff0c;大小为16比特。 首部长度…

VTK学习之vtkProp

vtkProp。渲染场景中数据的可视表达&#xff08;Visible Depictions&#xff09;是由vtkProp的子类负责。 也就是说&#xff0c;数据想要进行可视化显示&#xff0c;需要一个转换过程&#xff0c;这个过程就是转换为vtkProp 这样才能进行渲染展示出来。 而vtkProp子类是vtkA…

一阶电路和二阶电路的时域分析(1)——“电路分析”

小雅兰期末加油冲冲冲&#xff01;&#xff01;&#xff01; 动态电路的方程及其初始条件 动态电路&#xff0c;物理学名词&#xff0c;是指含有储能元件L、C的电路&#xff0c;动态电路方程的阶数通常等于电路中动态元件的个数。 动态电路是指含有储能元件的电路。当动态电路状…

openpnp - 底部相机矫正(subject not found)的原因总结

文章目录 openpnp - 底部相机矫正(subject not found)的原因总结概述问题的由来相机的选择相机焦距的选择相机初始安装距离位置的选择相机安装支柱接触面过大会影响相机模组PCB的安装相机支柱的绝缘问题安装相机模组时的平整度问题相机轴垂直度的问题相机成像时间矫正时的Z轴位…

全球顶尖科学家陈松蹊院士出任百分点数据科学研究院名誉院长

近日&#xff0c;百分点科技正式宣布聘请北京大学数学科学学院、光华管理学院教授&#xff0c;中国科学院院士陈松蹊担任百分点数据科学研究院名誉院长。公司将以此深化布局数据科学领域&#xff0c;助推数字中国建设。 全球顶尖科学家 陈松蹊院士主要从事超高维大数据统计分析…