【C语言】详解static和extern关键字

文章目录

  • 1. 前言
  • 2. 作用域和生命周期
    • 2.1 作用域
      • 2.1.1 全局变量和局部变量
    • 2.2 生命周期
  • 3. static关键字
    • 3.1 static修饰的局部变量
  • 4. extern关键字
  • 5. extern和static关键字的相互作用
    • 5.1 static修饰函数
  • 6.总结

1. 前言

可能在你遇到这篇文章之前,你可能并未听过C语言中还有staticextern这两个关键字。或者你也许听过但是并未使用过。
这些都不是问题,在本文中,我将细细的给大家揭晓这两个关键字背后的秘密,及以后我们该如何使用它们。🥇🥇😊

2. 作用域和生命周期

再讲staticextern这两个关键字之前,有必要先给大家讲一下变量的作用域和生命周期。

2.1 作用域

作用域是个什么东东?
顾名思义,作用域就是变量能够作用的范围。换句话说,就是变量能够在这个范围内生效,出了这个范围之后,变量就不起作用了。

这就又引发出一个问题:这个所谓的"范围"在代码中如何界定?
界定的方法:是以一个 {} 为 标志,每一个{}就代表着一个作用域。

听到这里,你可能还是一头雾水。下面我就给几个例子,让你感受到作用域带来的魅力!
1
我们稍微再修改一下(就是在变量a后面加一个花括号并在里面写一点内容):
2

3

那如果我们在图示花括号后面,要打印一个变量b的值,程序还能正确运行吗?

4
可以看到,编译器给我们报的错误:“b”未声明的标识符。这也就说明了,这个范围已经超出了变量b的作用域了,因此编译器才无法识别出变量b。

通过上述的例子,我相信大家已经对作用域的概念已经深刻的理解了。

2.1.1 全局变量和局部变量

既然都讲到了作用域,那就必须得聊一下全局变量和局部变量了。
变量按照作用域进行分类,可以分为全局变量和局部变量。

全局变量:拥有整个项目工程的作用域。换句话说,就是它能够在整个代码文件中都有效。全局变量是存储在内存的静态区
局部变量:拥有在该范围内的作用域,出了这个范围该变量就失去作用了。局部变量是存储在内存的栈区的

注意:全局变量应尽量少地在编程的过程中使用。因为,全局变量所带来地不可控的因素太多了,比较容易错误的使用。

全局变量和局部变量
那我们该如何在代码中,识别出哪个变量是全局变量还是局部变量呢?

很简单,仔细观察上面的代码,可以看到,全局变量是写在main函数外部的。
所以,我们可以由此得到一个结论:全局变量是出现在main函数的外部的,局部变量是出现在函数内部(包括自定义函数、库函数等)的变量

另外,再向大家声明一个点:
在我们初步学习变量的命名规则时,里面规定:变量的命名是不能重复的。这里我拓展一个点就是,此条件是在同一个作用域下才生效。
可能有的读者已经get到我的点了。

你不是说这个条件是在同一个作用域下才生效的麻,也就说明了在不同作用域下我可以使用相同的变量名。

那么,如果我全局变量和局部变量都用同一个变量名时,编译器又该如何接招呢
答案是:局部变量优先。换句话说,在局部变量所处的作用域中,用该局部变量的值,而不是全局变量。

下面我就写一段代码,验证我们的猜想:

#include<stdio.h>
int a = 88;int main()
{int a = 66;printf("%d\n", a); //打印a的值为66return 0;
}

结果是:
结果
可以看到,打印出来的值是66,而不是88。这就正是验证了我们的猜想是正确的。

2.2 生命周期

所谓的生命周期就更容易理解了,它就是:

⽣命周期指的是变量的创建(申请内存)到变量的销毁(收回内存)之间的⼀个时间段。

  1. 局部变量的⽣命周期是:进⼊作⽤域变量创建,⽣命周期开始,出作⽤域⽣命周期结束。
  2. 全局变量的⽣命周期是:整个程序的⽣命周期。

3. static关键字

static关键字修饰的变量我们称它为静态变量

static关键字的作用:改变变量的生命周期,使之拥有全局变量的生命周期。(但是注意一点,这样的操作并未改变变量的作用域)

那我们说的到底对不对,下面我就写代码,来探讨一下这个问题:

3.1 static修饰的局部变量

例子
可以看到,含有static修饰变量似乎有种记忆能力,它给我们的一种感觉就是能够在之前操作的结果基础上继续进行操作。

对⽐代码1和代码2的效果,你就能理解 static 修饰局部变量的意义。

  • 代码1的test函数中的局部变量i是每次进⼊test函数先创建变量(⽣命周期开始)并赋值为0,然后
    ++,再打印,出函数的时候变量⽣命周期将要结束(释放内存)。
  • 代码2中,我们从输出结果来看,i的值有累加的效果,其实 test函数中的i创建好后,出函数的时候是
    不会销毁的,重新进⼊函数也就不会重新创建变量,直接上次累积的数值继续计算。

使用建议:未来⼀个变量出了函数后,我们还想保留值,等下次进⼊函数继续使⽤,就可以使⽤static
修饰。

4. extern关键字

extern关键字的作用:赋予变量外部链接属性。

什么是外部链接?
这个问题通常会出现在这么一个场景中,就是我们在大型程序编写中,我们都会将程序的代码划分为多个.c文件,这样做的目的不仅可以增加代码的可读性,还可以提高团队的编程效率。那我们现在假设有个A文件和B文件,A文件的内容和B文件的内容是不能相互使用(相信这个点,大家在编程时都知道),如果强行使用,编译器就会报出错误。

那么现在我接受到了一个任务:我必须要在文件B中使用文件A的内容(一些变量的值、函数等等)。

那我们该怎么做?
用extern关键字。

在展示代码之前,想跟大家聊一聊,为什么就是用这个关键字?
对于文件A来说,文件B是属于外部文件。那么对于文件B来说,文件A里面的内容就属于外部内容。试想一下,两个毫不相干的东西想要相互使用双方的内容,那就必须得建立一个桥梁(链接)。而这个桥梁能够让文件A能够使用文件B的内容,建立桥梁的操作就是在建立外部链接属性。extern在这方面就是专业对口的。

在下面就举个例子:

首先在用这个关键字时,至少得创建两个或两个以上的.c文件。在本例中,创建两个.c文件。

在test1.c的内容:

int a = 66;

在test.c的内容:

#include<stdio.h>
extern int a;//这里的变量名必须与test1.c中你想引用的变量名得是一致的
int main()
{printf("a = %d\n", a);return 0;
}

extern关键字

5. extern和static关键字的相互作用

上面的例子如果你看懂的话,那就太好了。我们继续突发奇想地改造上述的代码。

我们这样改造:
将test1.c中的变量变为静态变量

static int a = 66;

再编译会出现什么情况?
例子
😲😲😲既然改了一下代码就报错了,这是什么原因呢?
就是static和extern关键字相互作用的结果。

结论:⼀个全局变量被static修饰,使得这个全局变量只能在本源⽂件内使⽤,不能在其他源⽂件内使⽤。
本质原因是全局变量默认是具有外部链接属性的,在外部的⽂件中想使⽤,只要适当的声明就可以使
⽤;但是全局变量被 static 修饰之后,外部链接属性就变成了内部链接属性,只能在⾃⼰所在的源
⽂件内部使⽤了,其他源⽂件,即使声明了,也是⽆法正常使⽤的。

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

5.1 static修饰函数

相信初学C语言的读者们可能都没有看过这种写法,static竟然还能修饰函数。

情况一:
在test1.c中的内容:

int Add(int x, int y)
{return x + y;
}

在test.c中的内容:

#include<sdtio.h>
extern int Add(int x, int y);
int main()
{printf("%d\n",Add(2,3));return 0;
}

1
注意,在Add函数形参这部分,可以不用专门写x和y,只写类型也可以。
2

情况二:

在test1.c内容中:

static int Add(int x, int y)
{return x + y;
}

在test.c内容中:

#include<sdtio.h>
extern int Add(int x, int y);
int main()
{printf("%d\n",Add(2,3));return 0;
}

再看看和之前的代码有什么不同?
编译
发现代码直接报错了。

解释:
其实 static 修饰函数和 static 修饰全局变量是⼀模⼀样的,⼀个函数在整个工程都可以使用,
被static修饰后,只能在本⽂件内部使用,其他文件无法正常的链接使用了。

本质是因为函数默认是具有外部链接属性,具有外部链接属性,使得函数在整个工程中只要适当的声
明就可以被使用。但是被 static 修饰后变成了内部链接属性,使得函数只能在自己所在源文件内部
使用。

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

6.总结

在本文中,介绍了变量的作用域和生命周期,还说明了static和extern两个关键字以及它们如何使用。
希望能帮到大家。

文章创作不易,如果你觉得写得好不错的话,请不要吝啬你们的点赞和收藏哦!!!🙏🙏🙏

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/24012.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于jeecgboot-vue3的Flowable流程-已办任务(二)

因为这个项目license问题无法开源&#xff0c;更多技术支持与服务请加入我的知识星球。 接上一节&#xff0c;这个部分主要讲功能代码 1、注册列表数据显示 //注册table数据const { prefixCls, tableContext, onExportXls, onImportXls } useListPage({tableProps: {title: …

1898java疫情防控管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java 疫情防控管理系统 是一套完善的web设计系统&#xff0c;对理解JSP java编程开发语言有帮助采用了java设计&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统采用web模式&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发…

顶顶通呼叫中心中间件-如何配置识别不同语种的ASR

文章目录 前言联系我们创建不同语种的语音识别任务开始对接识别不同语种的ASR重启 asrproxy 程序使用识别不同语种的ASR 前言 之前讲过顶顶通的 asrproxy 程序如何对接第三方的ASR&#xff0c;比如&#xff1a;阿里云的ASR。不知道如何对接的&#xff0c;可以参考&#xff1a;…

idea2023如何创建普通maven工程项目

解决 1.创建新项目 1.进入创建项目 File -> new -> project 2&#xff0c;project 中有 build system 选择maven 2.在已有项目中创建普通maven工程 1.右键项目选择 new -> Module 2.选择 new Module 其实与新建maven工程没什么区别 em:问题 idea以前的版本是在Mav…

“能监测、会预警、快处置”,51WORLD智慧应急数字孪生解决方案

我国自然灾害多发&#xff0c;安全生产基础薄弱。加之城市运行日益复杂&#xff0c;安全隐患、安全问题不断涌现&#xff0c;探索构建全新的应急管理体系和能力迫在眉睫。 面对新形势&#xff0c;依托数字孪生、云计算、大数据、人工智能等新一代信息技术打造统分结合、协调联…

别让你的品牌默默无闻,掌握建设与营销的关键技巧……

管理学大师彼得德鲁克曾经说过&#xff0c;“企业两个最重要的功能是创新和营销&#xff0c;其他一切都是成本。” 在商业领域中&#xff0c;有很多类型的营销。 它们中的每一个都不同&#xff0c;且都是有特定场景的。 有些用于区别于竞争对手&#xff0c;有些用于适应用户…

本地运行feishu-chatgpt项目结合内网穿透实现无公网IP远程访问

文章目录 前言环境列表1.飞书设置2.克隆feishu-chatgpt项目3.配置config.yaml文件4.运行feishu-chatgpt项目5.安装cpolar内网穿透6.固定公网地址7.机器人权限配置8.创建版本9.创建测试企业10. 机器人测试 前言 本文主要介绍如何在飞书中创建chatGPT机器人并且结合内网穿透工具…

怎么发送超大文件?困扰已久的邮件大附件发送问题解决了

邮件是日常中使用最多的文件流转工具&#xff0c;特别是对于企业内部的员工间、及企业与企业间的业务开展&#xff0c;数据和文件的发送、业务留痕大多都基于邮箱展开。 邮箱的普遍使用给用户基于邮箱进行业务沟通提供了前提&#xff0c;其中&#xff0c;Outlook邮箱是使用最广…

JVM学习-JVM运行时参数

JVM参数选项 标准参数选项 特点 稳定&#xff0c;后续版本不会变化以【-】开头 各种选项 运行java或者java -help可以看到所有的标准选项 补充内容 -server&#xff1a;64位机器上只支持Server模式的JVM&#xff0c;适用于需要大内存的应用程序&#xff0c;默认用并行垃圾回…

18 - 各赛事的用户注册率(高频 SQL 50 题基础版)

18 - 各赛事的用户注册率 -- 注册率注册用户数/所有用户数 selectr.contest_id,round(100*count(*)/(select count(*) from Users),2) percentage from Register r group by r.contest_id order bypercentage desc,r.contest_id ASC;

Phpstorm使用xdebug断点调试

一、目标 1、在浏览器地址栏里操作页面访问接口时&#xff0c;可以在项目代码对应入口处断点拦截调试&#xff1b; 2、在postman调用接口时&#xff0c;可以在项目代码对应入口处断点拦截调试&#xff1b; phpstorm版本&#xff1a;PhpStorm 2024.1.2 二、具体操作 1、安装…

Python离线查询IP地址对应的国家和城市

使用场景&#xff1a; 在没网的情况下使用python代码实现对ip地址进行查询国家和地市 代码实现&#xff1a; 需要安装 pip install geoip2 库 import geoip2.databasedef get_location_by_ip(ip_address, db_path):reader geoip2.database.Reader(db_path)try:response r…

什么是输入偏置电流?

输入偏置电流&#xff08;input bias current&#xff09;&#xff1a;运放同相与反相端流入和流出的电流。理想的运放同相和反相端的阻抗是无穷大的&#xff0c;所以是无法流进和流出电流。 第一种定义&#xff1a;同相与反相端电流和的平均值 以AD8031运放举例&#xff0c;…

HCIP与CCNP,中级认证里哪个更香?

如果你是网络领域的从业者&#xff0c;一定听说过HCIP&#xff08;华为认证网络工程师&#xff09;和CCNP&#xff08;思科认证网络专业人员&#xff09;这两个中级认证。 那么&#xff0c;在这两者之间&#xff0c;你更倾向于选择哪一个呢&#xff1f; 今天就对这两个认证进…

wine和crossover哪个好 使用crossover有什么优势

如果你是Mac或Linux用户&#xff0c;你可能会遇到这样的情况&#xff1a;你想要运行一些Windows上的应用程序或游戏&#xff0c;但是你的操作系统并不支持它们。这时候&#xff0c;你有几种选择&#xff1a;一是安装双系统&#xff0c;也就是在你的电脑上同时安装Windows或Linu…

教师常用小程序分享

和大家分享几款超级实用的教学小程序&#xff0c;不仅能够提高我们的办公效率&#xff0c;还能让我们的教学生活变得更加轻松有趣。 腾讯文档&#xff1a;云端协作的利器 教学协作是必不可少的。腾讯文档小程序&#xff0c;就是云端协作的利器。支持多人在线编辑文档&#xff…

《中国科技成果》是什么级别的期刊?是正规期刊吗?能评职称吗?

​问题解答 问&#xff1a;《中国科技成果》是不是核心期刊&#xff1f; 答&#xff1a;不是&#xff0c;是万方、维普收录的正规学术期刊 问&#xff1a;《中国科技成果》是什么级别的&#xff1f; 答&#xff1a;国家级。主管单位&#xff1a;中华人民共和国科学技术部 …

积极乐观的心态对学习和研究机器人相关技术非常重要

微案例 把难换成有趣&#xff0c;动力就会足一些。 或者把难换成“有挑战”等。 负面情绪描述&#xff1a; 学习和研究机器人很难。 中性情绪描述&#xff1a; 学习和研究机器人有挑战。 正面情绪描述&#xff1a; 学习和研究机器人很有趣。 机器人专业不合格且失败讲师如何让…

解决Windows Hosts 文件因为权限无法修改的问题

如何修改 Windows Hosts 文件并添加域名映射 在日常工作中&#xff0c;可能需要修改 Windows 的 hosts 文件&#xff0c;以将特定的域名映射到指定的 IP 地址。本文介绍三种方法来完成这一任务&#xff1a;直接手动编辑 hosts 文件&#xff0c;使用批处理文件自动完成任务&…

4秒惊艳!Stable Cascade AI绘画神器,设计师和普通用户的无限创意新选择

近日&#xff0c;一款AI绘画模型Stable Cascade发布。 只需输入一段描述文字&#xff0c;即可在4秒钟内获得令人惊艳的图像。 无论你是设计师、艺术家&#xff0c;还是普通用户&#xff0c;都能轻松上手&#xff0c;释放无限创意。 Stable Cascade不仅在使用上极具便捷性&am…