🚀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也因其特性,也是一个对于项目维护和提供安全保证上一个强有力的帮手。作为一名程序员,养成良好的编码风格,也是十分重要的!!!