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

C语言的重要知识点☞static关键字

static译为"静态的",该关键字可以修饰以下内容:

  • 修饰局部变量
  • 修饰全局变量
  • 修饰函数

在讲解static的具体作用前需要先知道"作用域"以及"生命周期"的概念: 

作用域:

作用域是一个程序设计概念,通常来说,一段程序代码中用到的名字并不总是有效的(可用)的,而限定这个名字的可用性的代码范围就是这个名字的作用域

大白话讲就是:这个东西在哪块地方可以使用,它的作用域就在哪儿 

举个例子:

#include<stdio.h>
void f()
{int tmp=0;tmp++;// 在作用域内有效,可用对其进行操作
}
int main()
{tmp++;// 报错,tmp的作用域只在f函数的范围内,出了作用域就不可用了return 0;
}
作用域范围:
  1. 局部变量的作用域是变量所在的局部范围(如上面例子中的tmp变量)
  2. 全局变量的作用域是整个工程(项目) 

举一个全局变量的例子:

#include<stdio.h>int a = 0;// 定义在全局
// a = 10;// 全局作用域不能进行赋值语句
void f()
{a = 10;// 可以在任意函数中访问
}
int main()
{f();a++;// 可以在任意函数中访问printf("%d", a);return 0;
}

额外补充一个知识点:C 语言规定,在全局作用域只能进行变量定义和初始化不能直接执行语句(如 a++;a=10。 

生命周期:

生命周期指的是变量的创建(申请内存空间)到 变量的销毁(收回内存空间)之间的一个时间段

联系前面说到的作用域,我们知道作用域限定了变量的可用/有效范围,不难想到从本质上看其实就是出了作用域变量就被销毁了,所以就不可用即无效了

生命周期时间段:
  1. 局部变量的生命周期是:进入作用域变量创建,生命周期开始,出作用域生命周期结束
  2. 全局变量的生命周期是:整个程序的生命周期

static关键字的作用:

①static修饰局部变量会改变局部变量的生命周期,生命周期会和程序的生命周期一样

来看两段代码:

             

从上面两段代码的结果不难看出,变量 的生命周期在被static修饰后明显发生了改变,原先的生命周期(如代码1所示)只在test()函数中,故每次调用test()函数,就会重新创建一次变量 ,因为 出了函数(作用域)销毁了,所以每次打印的值都是1

但是被static修饰后,打印的结果是累加的,也就是变量 的值没有在中途销毁过,也就是出了函数没有被销毁,故重新进入函数就不会重新创建变量 ,直接用上一次的值进行运算

为什么会这样呢?

因为static修饰变量后,本质上改变了变量的存储类型本来一个局部变量是存储在内存的"栈区"

但是被static修饰后存储到了静态区,存储在静态区的变量和全局变量是一样的,生命周期就和程序的生命周期一样了,只有程序结束,变量才销毁,内存才回收。但是作用域不变哦

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


②static修饰全局变量会使得这个全局变量只能在本源文件内使用,不能在其他源文件内使用

      

extern关键字用于声明外部符号,如果一个全局的符号在A文件中被定义,在B文件中想被使用,就可以使用extern关键字进行声明,然后就可以使用了

上面的代码,左边的可以正常运行,但是右边的代码编译时会出现链接性错误

这就是static修饰后,使得这个全局变量只能在本源文件中使用,不能在其他源文件使用

为什么会这样呢?

本质原因全局变量默认是具有外部链接属性的,在外部文件中想要使用,只要适当的声明就可以使用;但是全局变量被static修饰后,外部链接属性就变成了内部链接属性,只能在自己所在的源文件内部使用了,其他源文件,即使声明了,也是无法正常使用的

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


③static修饰函数,和static修饰全局变量的效果是一样的

一个函数在整个工程中都可以使用,如果想在外部源文件使用,一样的加上extern关键字修饰并且在另一个文件中声明就可以了

但是一旦被static关键字修饰后,就只能在本文件内部使用,其他文件无法正常的链接使用了

本质原因也是函数默认具有外部链接属性,具有外部链接属性,使得函数在整个工程中只要适当声明就可以被使用。但是被static修饰后变成了内部链接属性,使得函数只能在自己所在的源文件内部使用

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


相关文章:

  • 探索SQLMesh中的Jinja宏:提升SQL查询的灵活性与复用性
  • 人工智能任务24-AI学习中的模型训练中稀疏化参数与稀疏损失函数,以及实战项目应用
  • conda 安装cudnn
  • Android第六次面试总结之Java设计模式(二)
  • LeetCode 1. 两数之和(Java)
  • flex布局打印对联
  • 如何对 Redis 进行水平扩展和垂直扩展以应对微服务流量的增长?
  • C++ 重载
  • Matplotlib 饼图
  • 【C++】C++中的命名/名字/名称空间 namespace
  • 爱普生VG7050EFN压控晶振在小基站的应用优势
  • 【T2I】DreamBench++: A Human-Aligned Benchmark for Personalized Image Generation
  • Kali:利用rockyou文本字典hash破解zip压缩包密码
  • NetApp SAS 连接线:铜缆与光缆的全面介绍
  • 开源智能体MetaGPT记忆模块解读
  • 【5G通信】天线调整
  • 【AI】用AI将文档、文字一键生成PPT的方法(百度的自由画布版)
  • STL详解 - map和set
  • 性能分析硬核特训 · Perf 全面指南:内核实例 + 原理实战 + 面试答疑
  • JAVA SE(9)——多态
  • 上市不足一年,吉利汽车拟私有化极氪并合并:整合资源,杜绝重复投入
  • 夜读丨母亲的手擀面
  • 外交部回应西班牙未来外交战略:愿与之一道继续深化开放合作
  • 这个五月,有三部纪录电影值得一看
  • 1101名优秀运动员拟保送,全红婵、黄雨婷、盛李豪在列
  • 人民日报今日谈:坚决克服麻痹思想,狠抓工作落实