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

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.小结

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

  • 52
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱吃烤鸡翅的酸菜鱼

希望大家对我多多支持喔~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值