C语言中的static

1. C语言中的static主要有三个功能:

  • 隐藏
  • static变量的生命周期更长
  • static变量的初始值为‘0’

1.1 隐藏

* 任何变量和函数都具有全局可见性 (外部链接属性)

* 如果对变量和函数加上static前缀,那么对会对其源文件隐藏使其失去外部链接的属性

例:

这是变量和函数(函数可不使用‘extern’但建议使用)具有的全局可见性。(需要使用方法正确)

当函数和变量加上static前缀的时候,原本具有的外部属性消失仅仅为内部属性

问:那变量和函数加上static前缀的意义是什么?全局可见性不好吗?

  在整个代码的创造中并不是所有的函数和变量都需要它们的全局可见性,所以利用static特性可以在不同的文件中定义同名函数和同名变量,而不必担心命名冲突。static 可以用作函数和变量的前缀,对于函数来讲,static 的作用仅限于隐藏,而对于变量,static 还有下面两个作用。

1.2 static变量的生命周期更长

* 下面这张截图可以使大家对变量有一个较为清晰的概念

 由这个图我们可以知道所有的局部变量都是存储在栈区内,而所有的全局变量和静态变量(后面有介绍)是存储在静态区的

* 静态变量-->被static修饰的局部变量改变了变量的存储类型(位置,这里指由栈区变为静态区)故称为静态变量

* 下面就看看static修饰局部变量和局部变量的区别

局部变量:

 *这是一个正常局部变量在代码运行中展示的结果,应为局部变量的存储位置在栈区,而栈区上的变量的特点是,进入变量的作用域时就创建,出了变量的作用域时就将原先用于储存变量的内存空间归还操作系统(就像你出去旅游住酒店一样,开始旅游地方了就开好房,旅游结束了就退房,酒店整理干净后,就给另外有需要的人),所以在while循环中,每次进入add()自定义函数a都会重新创建并且重新赋值,所以a--;并没有发挥原本想要的作用。

 static变量/static修饰的局部变量:

* 与前面的局部变量不同的是a--;发挥了作用,那么说明a的值得到了延续,也就是在while循环中每次离开add()自定义函数,a变量这块存储空间没有在因为出了add()的作用域而重新被还给操作系统,而这一特点恰恰就是储存空间在静态区的变量所拥有的,所以static修饰的局部变量使其储存类型(位置)变为了静态区,而此时被static修饰的局部变量也叫做静态变量。所以也可以说static延长了局部变量的生命周期。

 1.3 static变量的初始值为‘0’

* 其实全局变量也具备这一属性,因为全局变量也存储在静态数据区。在静态数据区,内存中所有的字节默认值都是 0x00,某些时候这一特点可以减少程序员的工作量。比如初始化一个稀疏矩阵,我们可以一个一个地把所有元素都置 0,然后把不是 0 的几个元素赋值。如果定义成静态的,就省去了一开始置 0 的操作。再比如要把一个字符数组当字符串来用,但又觉得每次在字符数组末尾加 \0 太麻烦。如果把字符串定义成静态的,就省去了这个麻烦,因为那里本来就是 \0 。

例:

 这里编译器报错了,说“i”未初始化值,其实这个时候的“i”就是一个随机值,编译器会因为代码安全性,而提示你显示报错,这就是栈区的变量未初始化的变量的数值就是随机值,而且需要你手动去给他初始化。

根据这个运行结果可以证实刚刚说的在静态数据区,内存中所有的字节默认值都是 0x000,静态区内的变量的初始值都是‘0’,不需要手动去初始化

 那么我们思考一个问题,如果将字符数组定义成静态区的变量,是不是可以免去最后加‘0’/‘\0’的操作呢,看代码:

 对比下面俩张截图可以看出来,对于有static修饰的字符数组用strlen()来计算长度时,可以准确的计算出数组中的字符个数,而我们知道strlen()的停止条件就是遇到‘\0’,所以这样说明了static可以使字符数组自行补充‘\0’

 

 2. 最后对 static 的三条作用做一句话总结首先

static 的最主要功能是隐藏,其次因为 static 变量存放在静态存储区,所以它具备持久性和默认值0。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值