static和extern关键字详解

news2025/1/12 23:03:30

目录

创作不易,如对您有帮助,还望一键三连,谢谢!!!

回顾

1.作用域和声明周期

1.1作用域

1.2生命周期

2.static和extern

2.1extern

2.2static

2.2-1static修饰局部变量

2.2-2static修饰全局变量


创作不易,如对您有帮助,还望一键三连,谢谢!!!

回顾

之前我们学习了数据在内存中的存储,知道了整数和浮点数在内存中的存储方式,对于整形来说内存中存放的是该整形的补码,

而对于浮点形来说,是根据IEEE754标准在内存中存放的,其表示形式如下图所示:

同时,我们也发现数据在内存中是“倒着”存放的,由此我们讲解了大小端的概念。

小端存储模式:把数据的低位字节内容保存在内存的低地址处,把数据的高位字节内容保存在内存的高地址处。

大端存储模式:把数据的低位字节内容保存在内存的高地址处,把数据的高位字节内容保存在内存的低地址处。

在讲解题目之前,我们先来讲解一下static和extern这两个关键字。而讲解这两个关键字之前,我们先来讲一下作用域和生命周期。

1.作用域和声明周期

1.1作用域

作用域,顾名思义就是可以正常工作的区域,出了该区域就会失效。

标准解释:作用域是程序设计的概念,一段程序代码中所⽤到的名字并不总是有效(可⽤)
的,⽽限定这个名字的可⽤性的代码范围就是这个名字的作⽤域。

还是有点小抽象的,我们来看一段代码以便学习一下这个概念:

这段代码,我们创建了一个局部变量a,并且在不同区域内想要两次打印a的值。

运行代码我们发现,编译器会报错,如下图所示:

这是为什么呢?

这就涉及到我们上面讲的作用域了,a是个局部变量,那么它的作用域就是第一个大括号内,出了大括号a就会被销毁,所以第二次打印就会报错,如下图所示:所以才会出现上面的报错,那么如果我们这样创建a,结果还会是这样吗?

运行代码,发现此时没有错误,代码会正常运行。这是因为此时a是全局变量,作用域是整个工程文件,所以说代码会运行无误。

结论:

1. 局部变量的作⽤域是变量所在的局部范围。
2. 全局变量的作⽤域是整个⼯程(项⽬)。

1.2生命周期

什么是生命周期?就像一样,都会经历出生和死亡,而这个过程,就是人的生命周期,在程序中代码也是如此。

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

1. 局部变量的生命周期是:进入作用域变量创建,生命周期开始,出作用域销毁,生命周期结束。
2. 全局变量的生命周期是:整个程序的生命周期。

这个概念只能靠自己理解,我们来看下面一个例子:

2.static和extern

2.1extern

extern关键字是来声明外部符号的。

我们先来看下面一段代码:

我们在add.c文件中创建了一个全局变量y,这时候,我们如果直接在test.c文件中打印y,编译器就会报错,此时,想让代码运行,我们只需用extern声明一下变量y即可,修改后的代码如下:

此时,代码便可以正常运行。

extern就是“告诉”了编译器,这个变量在别的文件中存在,别再报错了。

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

2.2static

static是静态的意思,它可以用来:

1.修饰局部变量

2.修饰全局变量

3.修饰函数

我们来分别讲解。

2.2-1static修饰局部变量

我们先来看下面一段代码:

这段代码运行结果是什么呢?

这段代码比较简单,main函数内部for循环5次调用test函数,而test函数内部创建了局部变量j,j的生命周期开始,j++后j就变成了1,出了test函数后,也就是出了j的作用域,j的生命周期结束,j被销毁,所以说打印结果是1 1 1 1 1。

那么下面这段代码打印结果又是什么呢?

运行代码,结果如下图所示:

我们从输出结果来看,j的值有累加的效果,其实test函数中的i创建好后,出函数的时候是
不会销毁的,重新进⼊函数也就不会重新创建变量,直接上次累积的数值继续计算。

这是为什么呢?其实这是因为static修饰局部变量所致。

static修饰局部变量,会改变局部变量的生命周期,而生命周期的改变本质是改变来该变量在内存中的存储位置。

我们之前讲过,局部变量是在内存的栈区存储的,而被static修饰后放在了内存的静态区中,而静态区中存放的是全局变量和静态变量(被static修饰的变量就是静态变量)。而存储在静态区的变量和全局变量是一样的,声明周期就是程序的生命周期,只有程序结束,变量才销毁,内存才会回收。示意图如下:

那么,被static修饰的局部变量的作用域变没变?

答案:作用域不变。

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

2.2-2static修饰全局变量

还是这段代码,如果此时我们用static修饰全局变量y,代码还会正常运行吗?

此时,编译器会报错:无法解析的外部符号y。

为什么会这样呢?原因就在与static修饰全局变量所导致。

结论:⼀个全局变量被static修饰,使得这个全局变量只能在本源⽂件内使⽤,不能在其他源⽂件内使⽤

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

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

2.2-3static修饰函数

代码一和代码二谁能正常运行呢?

答案:代码一会正常运行,而代码二会报错。

这就是static修饰函数所导致的。我们会发现static修饰函数和static修饰全局变量是一模一样的。一个函数和全局变量原本是可以在整个工程中使用的(这叫做外部链接属性),但被static修饰后变只能在自己所在的源文件内使用,(这叫做内部链接属性)。

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

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

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

相关文章

k8s使用calico网络插件时,集群内节点防火墙策略配置方法

前言 我们在内网使用k8s时,有时候需要针对整个集群的节点设置防火墙,阻止一些外部访问,或者是仅允许白名单内的ip访问,传统做法是使用firewall之类的防火墙软件,但是,使用firewall存在如下问题&#xff1a…

资料总结分享:数据库:1.设计概念

目录 1 数据库设计任务 3 数据库设计方法 4 数据库设计的基本步骤 4.1 需求分析阶段 4.2 概念结构设计阶段 4.3 逻辑结构设计阶段 4.4 物理结构设计 4.5 数据库的实施阶段 4.6 数据库的运行和维护阶段 5 数据库结构设计阶段 6 数据库设计与模式结构 根据一个单位的信…

比特币减半倒计时:NFT 生态将受到怎样的影响?

BTC 减半倒计时仅剩不到 1 天,预计在 4 月 20 日迎来减半。当前区块奖励为 6.25 BTC,减半后区块奖励为 3.125 BTC,剩余区块为 253。比特币减半无疑是比特币发展史上最重要的事件之一,每当这一事件临近,整个加密社区都充…

qt tcp 连接 秒断连

问题: tcp连接总是秒成功后断连 debug会出现下面这些 onecore\net\netprofiles\service\src\nsp\dll\namespaceserviceprovider.cpp(550)\nlansp_c.dll!00007FFDA2A1D93D: (caller: 00007FFDD8BEACF6) LogHr(1) tid(336c) 8007277C ¡£¡£ one…

Python交换两个变量的值

问题 python交换两个变量的值很简单: x, y y, x 复制号右侧的元祖会首先计算内部的值,然后安装从左到右的顺序,依次赋值给赋值号右侧的变量。 有一种情况需要注意: 如图,交换下标为0的数字2和下标为2的数字4。返回…

在React函数组件中使用错误边界和errorElement进行错误处理

在React 18中,函数组件可以使用两种方式来处理错误: 使用 ErrorBoundary ErrorBoundary 是一种基于类的组件,可以捕获其子组件树中的任何 JavaScript 错误,并记录这些错误、渲染备用 UI 而不是冻结的组件树。 在函数组件中使用 ErrorBoundary,需要先创建一个基于类的 ErrorB…

加州大学欧文分校英语中级语法专项课程01:Perfect Tenses and Modals 学习笔记

Perfect Tenses and Modals course certificate 本文是学习https://www.coursera.org/learn/perfect-tenses-modals?specializationintermediate-grammar 这门课的学习笔记,如有侵权,请联系删除。 这门课是如下专项中的一门:Learn English:…

【前端】3. CSS【万字长文】

CSS 是什么 层叠样式表 (Cascading Style Sheets). CSS 能够对网页中元素位置的排版进行像素级精确控制, 实现美化页面的效果. 能够做到页面的样式和结构分离. CSS 就是 “东方四大邪术” 之化妆术. 基本语法规范 选择器 {一条/N条声明} 选择器决定针对谁修改 (找谁)声明决…

Hadoop——Yarn基础架构

Hadoop——Yarn基础架构 Hadoop YARN(Yet Another Resource Negotiator)是Apache Hadoop生态系统中的一个子项目,它是用于集群资源管理的框架,负责为运算程序提供服务器运算资源,相当于一个分布式的操作系统平台&…

前端发送请求,显示超时取消

前端发送请求,显示超时取消 问题说明:后台接口请求60s尚未完成,前端控制台显示取消(canceled) 原因 1、前端设置60s超时则取消 2、后台接口响应时间过长,过长的原因统计的数据量多(实际也才17…

Docker的数据管理、网络通信和dockerfile

目录 一、Docker的数据管理 1. 数据卷 1.1 数据卷定义 1.2 数据卷配置 2. 数据卷容器 2.1 创建数据卷容器 2.2 使用--volume-from来挂载test1 二、端口映射 三、容器互联 1. 创建容器互联 ​编辑2. 进入test2测试(ping 容器名/别名) 四、Dock…

进制转换问题

1.十进制转二进制&#xff08;善于使用__int128&#xff09; 3373. 进制转换 - AcWing题库 #include<bits/stdc.h> using namespace std; __int128 x; int x_; string s1; int main(){stack<int> s;while(cin>>s1){int lens1.size();for(int i0;i<len;i)…

【原创教程】EPLAN如何制作专属的封面

想要给EPLAN制作专属封面吗?没问题,我来给你支个招。在EPLAN设计电气图纸时,封面就是第一印象,得好好弄。咱们以口罩机项目为例,来看看怎么做吧! 首先,得新建个封面。在项目属性里找到表格名称,点那个数值下拉菜单,选择“查找”。在弹出的表格里挑个你喜欢的模版,点击…

jmeter5.4.1源码编译(IDEA)问题解决

问题现象&#xff1a;最近想更深入的研究下jmeter5.4.1的原理及功能具体实现&#xff0c;从官网down了个源码&#xff0c;在本地使用IDEA工具导入项目、编译时&#xff0c;报以下错误&#xff1a; class jdk.internal.loader.ClassLoaders$PlatformClassLoader cannot be cast…

P44,45 属性预处理,执行后游戏效果回调,附录指定区域内修改变量

这节课主要是怎么对Attribute进行在进行到游戏角色前先进行处理,以及游戏效果如何回调 AuraAttributeSet.h // Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h" #include "AttributeSet.h&…

前端常用样式组元SCSS

* { margin: 0; padding: 0; border: 0; box-sizing: border-box; } #主题色 $primary: #183ee4; $success: #0cce63; $danger: #f00c63; mixin setThemeBgColor($name, $oClor, $start, $end) { .#{$name}-color { color: $oClor } .#{$name}-color-active { color: dark…

MATLAB非均匀网格梯度计算

在matlab中&#xff0c;gradient函数可以很方便的对均匀网格进行梯度计算&#xff0c;但是对于非均匀网格&#xff0c;但是gradient却无法求解非均匀网格的梯度&#xff0c;这一点我之前犯过错误。我之前以为在gradient函数中指定x&#xff0c;y等坐标&#xff0c;其求解的就是…

《MATLAB科研绘图与学术图表绘制从入门到精通》示例:绘制婴儿性别比例饼图

在MATLAB 中可以使用 pie 函数来创建饼图。饼图是一种展示不同部分占总体的相对比例的图表。 本示例从“婴儿出生数据.csv”文件读取婴儿出生数据&#xff0c;然后计算男性和女性婴儿的数量&#xff0c;使用MATLAB绘制饼图。 配套图书链接&#xff1a;https://item.jd.com…

用c++实现起泡排序、哈密顿回路问题、TSP问题

5.3.2 起泡排序 【问题】 起泡排序(bubble sort)的基本思想是&#xff1a;两两比较相邻记录&#xff0c;如果反序则交换&#xff0c;直至没有反序的记录&#xff0c;如图5.8所示。【想法】下表给出了一个起泡排序的例子&#xff08;方括号括起来的为无序区&#xff09;&#x…

数组模拟几种基本的数据结构

文章目录 数组模拟单链表数组模拟双链表数组实现栈数组模拟队列总结 数组模拟单链表 首先类比结构体存储单链表&#xff0c;我们需要一个存放下一个节点下标的数组&#xff0c;还需要一个存储当前节点的值的数组&#xff0c;其次就是一个int类型的索引&#xff0c;这个索引指向…