19.《C语言》——【如何理解static和extern?】


🎇开场语

亲爱的读者,大家好!我是一名正在学习编程的高校生。在这个博客里,我将和大家一起探讨编程技巧、分享实用工具,并交流学习心得。希望通过我的博客,你能学到有用的知识,提高自己的技能,成为一名优秀的程序员。如果你有任何疑问或建议,请随时在评论区留言,让我们一起成长进步!现在,让我们开始这场知识之旅吧!


🕷️ 个人主页:FEN03

🕸️ 收入专栏:C语言


文章目录

  • 🎇开场语
  • 🎇文章前言
  • [🕸️作用域 和 生命周期](#🕸️作用域 和 生命周期)
  • [🕸️1. extern](#🕸️1. extern)
    • [🕷️1.1 extern](#🕷️1.1 extern)
  • [🕸️2. static](#🕸️2. static)
    • [🕷️2.1 static 修饰局部变量](#🕷️2.1 static 修饰局部变量)
    • [🕷️2.2 static 修饰全局变量](#🕷️2.2 static 修饰全局变量)
    • [🕷️2.3 static 修饰函数](#🕷️2.3 static 修饰函数)
  • 🕸️结束语

🎇文章前言

staticextern 都是C语言中的关键字,对于这两个的理解和运用是如何的呢?本章就让我们来探讨吧▶️


🕸️作用域 和 生命周期


在此之前,我们需要大概先了解作用域生命周期 ,有助于我们更好的了解后续!

  1. 作用域 :是程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效的,而限定这个名字的可用性的代码范围就是这个名字的作用域。

    1.1 局部变量的作用域是变量所在的局部范围。

    2.2 全局变量的作用域是整个工程。

  2. 生命周期: 指的是变量创建到变量的销毁之间的时间段

    2.1 局部变量的生命周期是:进入作用域变量创建,生命周期开始,出了作用域生命周期结束。

    2.2 全局变量的生命周期:整个程序的生命周期。


🕸️1. extern


🕷️1.1 extern


extern 是用来声明外部符号的,如果一个全局的符号在A文件中定义,在B文件中想要使用,就可以使用extern进行声明,然后使用。


🕸️2. static


  1. static是静态的意思,可以用来:
    1.1 修饰局部变量
    1.2 修饰全局变量
    1.3 修饰函数

🕷️2.1 static 修饰局部变量


为了更好的了解,我们看一段代码:

代码1:

c 复制代码
//代码1
#include <stdio.h>
void test()
{
	int i = 0;
	i++;
	printf("%d ", i);
}
int main()
{
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		test();
	}
	return 0;
}

代码2:

c 复制代码
// 代码2
#include <stdio.h>
void test()
{
	//static修饰局部变量
	static int i = 0;
	i++;
	printf("%d ", i);
}
int main()
{
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		test();
	}
	return 0;
}

代码1和代码2的运行结果比较;

分析:

  1. 对比代码1和代码2的运行结果,可以看到代码2中static的修饰局部变量的意义。
    1.1 代码1中的test函数中的局部变量 i 是每一次进入test函数先创建,初始值为0,随后进行i++,输出 i 的值。但是,当再次进入函数执行代码,输出的值还是一样,这是因为,进入函数是生命周期的开始,出了函数,生命周期就结束了。
  2. 代码2中,变量 i 被static修饰,所以每一次执行test函数,i 的值都会被累计,这是因为static修饰局部变量,局部变量的生命周期被改变,只有当工程结束,生命周期才结束。

结论:

static修饰局部变量改变了变量的生命周期,生命周期改变的本质上是改变了变量的存储类型,本来一个局部变量是存储在内存的栈区 ,但是被static修饰后,变为了存储在静态区,存储在静态区的变量和全局变量是一样的,生命周期就和程序的生命周期一样,只有程序结束,变量才销毁,内存回收。但是作用域不会被改变。


🕷️2.2 static 修饰全局变量


我们看代码:

这是在项目A中的代码:

c 复制代码
int a = 100;

这是在项目B中的代码:

c 复制代码
#include<stdio.h>
extern int a; 
int main()
{
	printf("%d\n", a); 
	return 0; 
}

因为我们合理的声明,运行结果是没问题的:

但是如果项目A中的代码,经过static修饰,结果会是怎样❓

项目A中的代码,被static修饰

c 复制代码
static int a = 100;

项目B中的代码:

c 复制代码
#include<stdio.h>
extern int a; 
int main()
{
	printf("%d\n", a); 
	return 0; 
}

运行结果是报错,提示无法解析外部连接符号

所以,当我们不想B项目使用A项目时,可以给A项目代码中使用static修饰,相当于上锁,这样B项目就不能够使用。


🕷️2.3 static 修饰函数


static修饰函数我们可以通过一段代码就能够理解:

这是项目A中的代码:

c 复制代码
int Add(int x, int y)
{
	return x + y; 
}

这是项目B中的代码:

c 复制代码
extern int Add(int, int); 

#include<stdio.h>
int main()
{
	int ret = Add(3, 5);  
	printf("%d\n", ret); 
	return 0;
}

运行结果:

我们观察到,我们合理的声明,代码的运行是完全没问题,如果我们加上static会怎样?

项目A中的代码加上static :

c 复制代码
static int Add(int x, int y)
{
	return x + y; 
}

项目B中的代码:

c 复制代码
extern int Add(int, int); 

#include<stdio.h>
int main()
{
	int ret = Add(3, 5);  
	printf("%d\n", ret); 
	return 0;
}

运行结果:

我们看到了A项目中的代码,被static修饰后,B项目是无法去使用的,所以得出结论,当使用函数时,A项目中的代码不想被B项目中的代码使用,可以使用static修饰。


🕸️结束语


非常感谢您花时间阅读我的博客,希望我的分享能为您带来收获。如果您对本文有任何想法或疑问,欢迎在评论区留言交流。如果您喜欢我的博客,请继续关注,我会定期更新更多精彩内容。最后,别忘了行动起来的力量,让我们一起实践这些方法,见证自己的成长和进步!

再见,祝您生活愉快! 🌹


相关推荐
湫ccc13 分钟前
《Python基础》之字符串格式化输出
开发语言·python
mqiqe1 小时前
Python MySQL通过Binlog 获取变更记录 恢复数据
开发语言·python·mysql
AttackingLin1 小时前
2024强网杯--babyheap house of apple2解法
linux·开发语言·python
Ysjt | 深1 小时前
C++多线程编程入门教程(优质版)
java·开发语言·jvm·c++
ephemerals__2 小时前
【c++丨STL】list模拟实现(附源码)
开发语言·c++·list
码农飞飞2 小时前
深入理解Rust的模式匹配
开发语言·后端·rust·模式匹配·解构·结构体和枚举
一个小坑货2 小时前
Rust 的简介
开发语言·后端·rust
湫ccc2 小时前
《Python基础》之基本数据类型
开发语言·python