Hi~!这里是奋斗的小羊,很荣幸各位能阅读我的文章,诚请评论指点,关注+收藏,欢迎欢迎~~
💥个人主页:小羊在奋斗
💥所属专栏:C语言
本系列文章为个人学习笔记,在这里撰写成文一为巩固知识,二为同样是初学者的学友展示一些我的学习过程及心得。文笔、排版拙劣,望见谅。
这一小节也是属于函数部分,如果与上篇文章写在一起篇幅过长,因此将本小节单独整理成一篇文章以便我们有更好的阅读体验。
一、static 和 extern
1、static 修饰局部变量
2、static 修饰全局变量
3、static 修饰函数
一、static 和 extern
static 和 extern 都是C语言中的关键字;
static 是静态的意思,extern 是用来声明外部符号的;
在学习 static 和 extern 之前,我们先来了解一下作用域和生命周期。
1、作用域和生命周期
作用域是程序设计概念,通常来说,一段程序代码中所有用到的名字并不总是有效(可用)的,而限定这个名字可用性的代码范围就是这个名字的作用域。
(1)局部变量的作用域是变量所在的局部范围;
(2)全局变量的作用是整个工程项目。
我们先来通过示例理解一下(1):
可以看到上面代码中第二个 printf()函数中的参数a是不可用的, 这是因为这个a不在我们创建的变量a的作用域内。
再来看:
当我们把变量a的创建放在小花括号外,这时我们创建的变量a的作用域就是整个主函数。
同样的,我们在主函数中定义的局部变量在其他自定义函数中也是不能用的。
我们再来通过示例理解(2):
相信通过上面的几个实验,我们已经能基本掌握上面的两句话。
再来说一下生命周期:
生命周期指的是变量的创建(申请内存)到变量的销毁(收回内存)之间的一个时间段。
(1)局部变量的生命周期是:进入作用域变量创建,生命周期开始,出作用域变量销毁,生命周期结束。
(2)全局变量的生命周期是:整个程序的生命周期。
2、static 修饰局部变量
我们来看下面两个代码有什么不同:
可以看到在我们给创建 j 变量前加了一个 static 之后,打印的结果发生了变化,通过这个例子我们来猜测 static 的作用。
在没加 static 之前,我们在主函数中四次调用 print ()函数,每次进入 print ()函数时都会重新初始化一次变量 j ,因此每次 j++ 前 j 的值都为0,所以打印出了四个1;加上 static 之后,第一次进入 print()函数时初始化 j 为0,j++为1后打印,print()函数完成,第二次执行 print()函数后打印了2。
我们来倒推一下,此时 j 为2,所以 j++之前 j 的值应该还是1,我们可以猜一下在第二次进入 print()函数的时候是不是就不执行初始化 j 这一条代码了,那么 j++之前 j 还是上次出 print()函数时 j 的值也就是1,j++后 j 为2再打印,以此类推。
按照上面我们的猜测好像说的通,事实上我们已经大致猜出了 static 的作用。在第二次进入 print()函数时,确实不执行 static 修饰的这一条代码。
总结:(1)static 修饰的局部变量在进入作用域前就存在,出作用域也不销毁,而且用的是上次留下来的值。
(2)编译器在编译代码的时候,就为静态变量(即 static 修饰的变量)分配了地址,而不是进入函数创建这种变量。
(3)static 修饰局部变量改变了变量的生命周期,生命周期改变的本质是改变了变量的存储类型,本来一个局部变量是存储在内存的栈区的,但是被 static 修饰后存储到了静态区。存储在静态区的变量和全局变量是一样的,生命周期就和程序的生命周期一样了,只有程序结束,变量才销毁,内存才回收。但是作用域是不变的。
关于局部变量和全局变量的存储我在这篇文章中有简单介绍过 —> 数据和变量
(4)未来一个变量出了函数后,我们还想保留值,等下次进入函数继续使用,就可以使用 static 修饰。
3、static 修饰全局变量
先来看上面的代码, 我们在 Add.c 文件中创建了一个全局变量a,如果我们想在 main.c 文件中使用这个a,因为全局变量默认是带有外部链接属性的,所以只需要用 extern 声明外部变量a即可使用。
再来看:
在我们使用 static 修饰全局变量a后, 在 main.c 文件中就不能正常使用了,为什么呢?
总结:(1)static 修饰全局变量的时候,改变了全局变量的外部链接属性,使得外部链接属性变成了内部链接属性。
(2)这种变量只能在自己所在的 .c 文件中使用,其他 .c 文件中无法使用。
(3)如果一个全局变量只想在所在的源文件内部使用,不想被其他文件发现,就可以使用 static 修饰。
4、static 修饰函数
上面的代码说明了一个问题,函数也是有外部链接属性的。 只要在其他的 .c 文件中正确声明,也是可以直接使用的。
同样的,如果我们写的自定义函数不想被其他人使用,只要用 static 修饰函数即可。
static 修饰函数,让函数的外部链接属性变成了内部链接属性,使得函数只能在自己所在的 .c 文件中使用,其他 .c 文件中无法使用。
其实 static 修饰函数和 static 修饰全局变量是一模一样的。
点击跳转主页—> 💥个人主页:小羊在奋斗