C语言知识(1) static修饰详解分享

news/2024/11/16 3:41:32/

1.前言

哈喽大家好啊,今天来给大家分享c中static的使用,希望能对大家有所帮助,请大家多多点赞,收藏支持我哦~

2.正文

在讲解static之前,先给大家铺垫三个概念,方便大家理解。

2.1三则知识铺垫

2.1.1作用域与生命周期

2.1.1.1作用域

作用域(scope)主要用来控制变量、函数或对象在程序中的可见性和生命周期。具体来说,作用域限定了一个变量、函数或对象在代码中的哪一部分可以被访问和使用。作用域的种类包括全局作用域、局部作用域和块级作用域。

2..1.1.2生命周期

生命周期,也指生存期(Lifetime),通常指的是一个对象、变量或数据结构在内存中存在的时间长度,即从它被创建或分配内存开始,到它不再被需要并被销毁或释放内存为止的这段时间。

3..1.1.3作用域和生命周期的联系

变量的作用域决定了它在代码中的可见性,而生存期决定了它在内存中的存在时间。虽然作用域和生存期经常是相关的,但它们不是同一个概念。例如,在C++中,一个局部变量在其作用域内是可见的,并且当控制流离开其定义的作用域时,它的生存期就结束了。总而言之,一个关注存活时间,另一个关注可适用范围。

2.1.2内存

相信读者会有一个疑问,我们static为什么要讲内存呢,因为static的使用本质上牵扯到一些内存的概念,将这里理解了就会对static的使用带来极大的帮助。

 

  • 栈区是一种后进先出的数据结构,用于存储程序运行时的局部变量和函数调用信息。当一个函数被调用时,其局部变量和函数参数会被分配到栈上。当函数返回时,这些变量会自动被销毁,栈的空间会被回收。。
  • 堆区是用于动态分配内存的区域,通常用于存储程序中需要在运行时进行分配和释放的数据。
  • 静态区(也称为全局区)用于存储程序中声明为静态的全局变量和静态局部变量。这些变量在程序运行期间都存在,并且它们的值在函数调用之间保持不变。静态区是在编译时分配内存空间的,因此其大小和位置在程序运行期间是固定的。静态区的生命周期与整个程序的执行周期相同,直到程序结束才由系统释放内存。

3.1.3链接属性

链接属性分别包括外部链接属性和内部链接属性。详细解释如下:

  • 外部链接通常指的是程序中定义的标识符(如全局变量或函数)在多个编译单元(通常是源文件)之间的可见性和共享性。当一个标识符被声明为具有外部链接时,它可以在整个程序的不同部分中被访问和引用,就好像它们是同一个实体一样。
  • 内部链接(也称为静态链接)是指标识符的作用域限制在其定义的编译单元内。与外部链接不同,具有内部链接的标识符在链接过程中不会暴露给其他编译单元,也不会与其他编译单元中的同名标识符发生冲突。

2.2static的使用

上面铺垫了这么多,接下来开始上正餐:

2.2.1修饰局部变量

接下来我举例子会使用包含俩个函数的代码:

第一段代码:

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

输出结果如图:

我们发现,上段没有实现逐个打印1,2,3,4,5的功能,那是因为func函数中i一旦完成便被销毁下一次for循环再进行func函数时,便还是重新创建i=0的操作。

第二段代码:

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

输出结果如图:

经过static的修饰后,我们发现可以输出1,2,3,4,5了。因此我们可以得出,static的修饰本质上是使变量的生命周期得到了改变,i这个局部变量本来是储存在栈区,经修饰后储存在了静态区,特征就相当于全局变量了,生命周期延长,但作用域不变。

2.2.2修饰全局变量

局部变量经过static的修饰以后使用可以相当于全局变量,那么static修饰全局变量会有什么影响呢。

为了能够表现出static修饰全局变量后的效果,这里要引用一个extern

extern 是⽤来声明外部符号的,如果⼀个全局的符号在A⽂件中定义的,在B⽂件中想使⽤,就可以使用extern。

代码1:(以下是俩个源文件)
int a = 1;
#include<stdio.h>
int main() {extern int a;printf("%d", a);return 0;
}

这个代码可以正常输出1;

代码2:

static int a = 0;
#include<stdio.h>
int main() {extern int a;printf("%d", a);return 0;
}

用编译器一编译发现,这段代码没有办法正常输出。由此我们可以得出被static修饰后的全局变量只能在当下源文件去使用,全局变量本身是被默认具有外部连接属性,被修饰后该变量由外部连接属性变成内部连接属性,即使声明了,也是无法正常使用。

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

 2.2.3修饰函数

接下来再给大家附上俩段代码

代码1:

int func(int x, int y) {return x + y;
}
#include<stdio.h>
extern int func(int x ,int y);
int main() {int a = 0, b = 0;scanf("%d%d", &a, &b);printf("%d",func(a, b));return 0;
}

 这段代码运行后发现可以实现调用加法函数的功能,即能正常输出a+b的值。

代码2:

extern int func(int x, int y) {return x + y;
}
#include<stdio.h>
extern int func(int x ,int y);
int main() {int a = 0, b = 0;scanf("%d%d", &a, &b);printf("%d",func(a, b));return 0;
}

 调试后发现,这段代码无法正常输出,原因和static修饰全局变量类似,函数本身带有外部链接属性,经过extern修饰后,转换成内部链接属性,则函数的调用仅限于当前源文件中了。

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

3.小结

今天的分享到这里就结束了,希望喜欢的朋友多多支持我哦~


http://www.ppmy.cn/news/1423129.html

相关文章

老师学生蒸馏模型实战

参考&#xff1a;知识蒸馏Pytorch代码实战_哔哩哔哩_bilibili import torch import torch.nn.functional as F from torch import nn, optim import torchvision from torchvision import datasets, transforms from torch.utils.data import DataLoader from torchinfo impor…

ChatGPT辅助下的论文写作之道

ChatGPT无限次数:点击直达 ChatGPT辅助下的论文写作之道 在当今信息爆炸的时代&#xff0c;学术论文写作是每个研究者和学生不可或缺的技能。然而&#xff0c;对于许多人来说&#xff0c;写作是一个具有挑战性和耗时的过程。幸运的是&#xff0c;随着人工智能技术的不断进步&a…

Linux 1.文件编程(dup、dup2)

重定向 重定向是什么&#xff1f;dupdup2 重定向是什么&#xff1f; 进程在最开始运行的时候&#xff0c;首先打开了三个文件&#xff0c;分别是标准输入流、标准输出流、标准错误输出流。证明的时候我是把标准输出留给关闭了&#xff0c;然后紧接着创建的文件就会占用已关闭的…

上班记事备忘的软件有什么 工作记事本软件

在繁忙的工作节奏中&#xff0c;我常常感到自己的记忆力似乎不够用。开会时&#xff0c;脑海中灵光一闪的想法&#xff0c;转眼就忘得一干二净&#xff1b;与客户的约定&#xff0c;总是在忙碌中错过。记性不好&#xff0c;不仅影响了工作效率&#xff0c;更让我在同事和客户面…

c++ 拷贝构造函数 简单实验

1.概要 什么时候调用拷贝构造&#xff0c;就是有对象创建的时候&#xff0c;就会调用拷贝构造&#xff0c;无论对象是构造&#xff08;类&#xff08;来源&#xff09;&#xff09;还是赋值&#xff08;对象&#xff09;都会调用拷贝构造。 赋值函数调用的时机是两个对象都已经…

想要私域流量翻倍?这四个关键要素绝对不能错过!

在当今“得流量者得天下”的时代&#xff0c;拥有稳定且高质量的私域流量对于企业或是个人来说至关重要。然而&#xff0c;如何才能实现私域流量翻倍呢&#xff1f; 今天就给大家分享私域流量的四个关键要素&#xff0c;让大家都能实现私域流量的快速增长。 第一个&#xff1…

ChatGPT之道:巧用写作技巧

ChatGPT无限次数:点击直达 ChatGPT之道&#xff1a;巧用写作技巧 在当今快节奏的社会中&#xff0c;写作是一项非常重要的技能&#xff0c;不仅可以帮助我们有效表达思想&#xff0c;还可以提升个人能力和吸引力。而借助人工智能技术&#xff0c;如OpenAI推出的ChatGPT&#x…

遇事不决 量子力学?

文章目录 引入量子力学产生的必然性量子力学名称的由来粒子&#xff1f;波&#xff1f;波粒二象性测不准原理 &#xff08;不确定原理&#xff09;叠加态原理 量子纠缠态叠加量子纠缠量子纠缠实验 逻辑判断&#xff0c;量子力学到底完善吗观测量子纠缠&#xff1f;那我们宏观世…