《C和指针》笔记14: 作用域和存储类型总结(例子说明)
文章目录
- 题目
- 答案
- 解释
- 总结
本文是作用域和存储类型的总结,以一个例子来说明,如果不看解释可以很直接地回答每一条语句的作用域和存储类型,那么说明已经很熟练地掌握这个知识点了。
关于作用域和存储类型可以参考我前面的博客:
《C和指针》笔记10:作用域
《C和指针》笔记12: 存储类型(自动变量、静态变量和寄存器变量)
题目
请看下面的代码,回答每一行的标识符的链接属性、存储类型和作用域
答案
行数 | 标识符 | 链接属性 | 存储类型 | 作用域 |
---|---|---|---|---|
1 | a | external | 静态存储 | 第1-第12行,第17-第29行 |
2 | b | external | 静态存储 | 第2-第6行,第25-第29行 |
3 | c | internal | 静态存储 | 第3-第29行 |
4 | d | external | 静态存储 | 第4行-文件结束 |
4 | e | external | 自动存储 | 第6-11行,第17-19行以及第23-24行 |
6 | f | 不具有链接属性 | 自动存储 | 至函数结束 |
7 | b | 不具有链接属性 | 寄存器存储 | 至函数结束 |
8 | g | 不具有链接属性 | 静态存储 | 至函数结束 |
9 | a | external | 静态存储 | 和第一行的a 一样 |
12 | e | 不具有链接属性 | 自动存储 | 延伸至16行 |
13 | g | 不具有链接属性 | 自动存储 | 延伸至16行 |
14 | h | external | 静态存储 | 当前的代码块 |
19 | x | 不具有链接属性 | 自动存储 | 当前的代码块 |
20 | e | 不具有链接属性 | 自动存储 | 当前的代码块 |
25 | i | internal | 静态存储 | 从它声明的位置直到这个源文件结束 |
解释
- 第1行的a
- 链接属性:
external
,因为它属于文件作用域的声明在缺省情况下为external
链接属性,可以被其他源文件访问。 - 存储类型:静态存储。
- 作用域:第1-第12行,第17-第29行。静态变量在程序执行之前创建,并一直保持它们的值,直到程序结束。当程序开始执行时,变量a将初始化为5。其作用域应一直延伸到这个源文件结束为止。但是第13行出现的a的局部变量将隐藏同名的静态变量。
- 链接属性:
- 第2行的b
- 链接属性:
external
,如果b的定义在其他地方,第2行的extern
关键字在技术上并非必需,但在风格上却是加上这个关键字为好,可以被其他源文件访问。 - 存储类型:静态存储。
- 作用域:第2-第6行,第25-第29行。静态变量在程序执行之前创建,并一直保持它们的值,直到程序结束。其作用域应一直延伸到这个源文件结束为止。 但是由于第7行出现的b的局部变量将隐藏同名的静态变量。
- 链接属性:
- 第3行的c
- 链接属性:
internal
。static
关键字修改了c的缺省链接属性,把它改为internal
。只能被当前的源文件访问。 - 存储类型:静态存储。
- 作用域:第3-第29行。静态变量在程序执行之前创建,并一直保持它们的值,直到程序结束。其作用域应一直延伸到这个源文件结束为止。
- 链接属性:
- 第4行的d
- 链接属性:
external
。作为函数名,d在缺省情况下具有external链接属性,所以其他源文件只要在文件上存在d的原型 ,就可以调用d。函数d的定义对于这个源文件中任何以后想要调用它的函数而言起到了函数原型的作用,如果我们将函数声明为static,就可以把它的链接属性从external改为internal,但这样做将使其他源文件不能访问这个函数。 - 存储类型:静态存储。对于函数而言,存储类型并不是问题,因为代码总是存储于静态内存中。
- 作用域:第4行直到文件结束。静态变量在程序执行之前创建,并一直保持它们的值,直到程序结束。其作用域应一直延伸到这个源文件结束为止。
- 链接属性:
- 第4行的e
- 链接属性: 不具有链接属性,所以我们只能从函数内部通过名字访问它。
- 存储类型:自动存储。在函数被调用时被创建,当函数返回时消失。
- 作用域:第6-11行,第17-19行以及第23-24行。与局部变量冲突导致了作用域的变化。
- 第6行-第8行的f,b,g
- 链接属性: 不具有链接属性,所以它们不能在函数的外部通过名字访问(这是它们称为局部变量的原因)
- 存储类型:
- f是自动存储,当函数每次被调用时,它通过隐式赋值被初始化为15。
- b是寄存器存储,所以它的初始值是垃圾。
- g是静态存储,在程序的整个执行过程中一直存在。当函数每次被调用时,它并不会被重新初始化。
- 作用域:到函数结束为止。由于与局部变量冲突,它的作用域限于。
- 第9行的a
- 它的声明并不需要。这个代码块位于第1行声明的作用域之内。所以它和第一行的a的连接属性、存储类型都是一样的。
- 第12行的-第13行的e,a
- 链接属性: 不具有链接属性,和先前声明的a和e不同,在这个代码块中,以前声明的同名变量是不能被访问的。
- 存储类型:自动存储
- 作用域:延伸至第16行。
- 第14行的h
- 链接属性:
external
。相当一个全局变量。这是唯一一个必须使用extern关键字的声明,如果没有它,h将变成另一个局部变量。 - 存储类型:静态存储
- 作用域:当前的代码块。
- 链接属性:
- 第19和20行的x,e
- 链接属性: 不具有链接属性,和先前声明的a和e不同,在这个代码块中,以前声明的同名变量是不能被访问的。
- 存储类型:自动存储
- 作用域:当前的代码块。
这里的e和第4行函数的形参e是不同的变量,它和第12行声明的e也不相同。在这个代码块中,从第11行到第18行并无嵌套,所以编译器可以使用相同的内存来存储两个代码块中不同的变量e。如果想让这两个代码块中的e表示同一个变量,那么你就不应该把它声明为局部变量。
- 第25行的i
- 链接属性:
internal
,该属性可以防止它被这个源文件之外的任何函数调用。其他的源文件也可能声明它自己的函数i,但它与这个源文件的i是不同的函数。 - 存储类型:静态存储
- 作用域:从它声明的位置直到这个源文件结束。
- 链接属性:
函数d不可以调用函数i,因为在d之前不存在i的原型。
总结
具有external
链接属性的实体在其他语言的术语里称为全局(global)实体,所有源文件中的所有函数均可以访问它。只要变量并非声明于代码块或函数定义内部,它在缺省情况下的链接属性即为external
。如果一个变量声明于代码块内部,在它前面添加extern关键字将使它所引用的是全局变量而非局部变量。除了实体的具体定义位置之外,在它的其他声明位置都使用extern
关键字。
具有external
链接属性的实体总是具有静态存储类型。全局变量在程序开始执行前创建,并在程序整个执行过程中始终存在。从属于函数的局部变量在函数开始执行时创建,在函数执行完毕后销毁,但用于执行函数的机器指令在程序的生命期内一直存在。
局部变量由函数内部使用,不能被其他函数通过名字引用。它在缺省情况下的存储类型为自动,这是基于两个原因:
- 当这些变量需要时才为它们分配存储,这样可以减少内存的总需求量。
- 在堆栈上为它们分配存储可以有效地实现递归。
如果觉得让变量的值在函数的多次调用中始终保持原先的值非常重要的话,可以修改它的存储类型,把它从自动变量改为静态变量。
变量类型 | 声明的位置 | 是否存在于堆栈 | 作用域 | 如果声明为static |
---|---|---|---|---|
全局 | 所有代码块之外 | 否 | 从声明处到文件尾 | 不允许从其他源文件访问 |
局部 | 代码块起始处 | 是 | 整个代码块 | 变量不存储于堆栈中,它的值在程序整个执行器一直保持 |
形式参数 | 函数头部 | 是 | 整个函数 | 不允许 |
参考
- 《C与指针》
相关文章:

《C和指针》笔记14: 作用域和存储类型总结(例子说明)
文章目录 题目答案解释总结 本文是作用域和存储类型的总结,以一个例子来说明,如果不看解释可以很直接地回答每一条语句的作用域和存储类型,那么说明已经很熟练地掌握这个知识点了。 关于作用域和存储类型可以参考我前面的博客: …...
Linux之系统操作参数详解
Linux之系统操作参数详解 date //显示当前日期 日期格式化 %Y year年 %y 年份(以00-99来表示) %j 该年中的第几天 %m month月 (01…12) %w 该周的天数,0代表周日,1代表周一 %D 日期(含年月日) %d day of month (e.g., 01) %T 时间(含时分秒࿰…...
datax 使用
环境准备 List itemLinuxJDK(1.8以上,推荐1.8)Python(2或3都可以)Apache Maven 3.x (Compile DataX) 下载 wget https://datax-opensource.oss-cn-hangzhou.aliyuncs.com/202308/datax.tar.gz建立datax 用户 useradd datax ; echo "datax" | passwd -…...

【C/C++】#define宏替换高级用法
创作不易,本篇文章如果帮助到了你,还请点赞 关注支持一下♡>𖥦<)!! 主页专栏有更多知识,如有疑问欢迎大家指正讨论,共同进步! 🔥c系列专栏:C/C零基础到精通 🔥 给大…...
Android 之 传感器专题 (4) —— 其他传感器了解
本节引言: 在上一节的结尾说了,传感器部分因为笔者没怎么玩过,本节就简单的把剩下的几个常用的 传感器介绍一遍,当作科普,以后用到再慢慢研究~ 1.磁场传感器(Magnetic field sensor) 作用:该传感器主要用…...
【高级搜索】双向广搜,A*,IDDFS,IDA *算法总结 (terse版)
一、双向广搜 双向广搜就是从起点和终点同时往中间搜的一个算法。 注意事项: 在搜索过程中,同一层次下的顺序应该为:搜完一边所有的当前深度的子节点,在搜索另一边。 队列使用 (1)合用…...

CATIA Composer R2023安装教程
软件下载 软件:CATIA Composer版本:2023语言:简体中文大小:1.82G安装环境:Win11/Win10/Win8/Win7硬件要求:CPU2.60GHz 内存8G(或更高)下载通道①百度网盘丨64位下载链接:https://pa…...
git,修改远程分支名称
获取所有远程分支 git branch -r删除远程指定分支 git push --delete origin 测试添加新页面提交新命名本地分支 git push origin 新分支本地分支和远程分支关联 git branch --set-upstream-to origin/远程分支...

信息系统项目管理师(第四版)教材精读思维导图-第六章项目管理理论
请参阅我的另一篇文章,综合介绍软考高项: 信息系统项目管理师(软考高项)备考总结_计算机技术与软件专业技术_铭记北宸的博客-CSDN博客 本章思维导图PDF格式 本章思维导图XMind源文件 目录 6.1 PMBOK的发展 6.2 项目基本要素 6.3…...

[Android]JNI的基础知识
目录 1.什么是JNI 2.配置JNI开发环境NDK 3.创建Native C类型的项目 4. 了解CMakeLists.txt 文件 5.了解native-lib.cpp 文件 6.在 Android 的 MainActivity 中调用 native-lib.cpp 中实现的本地方法 1.什么是JNI JNI(Java Native Interface)是一…...
力扣-哈希-字母异位词分组
题目 给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的所有字母得到的一个新单词。 示例 1: 输入: strs ["eat", "tea", "tan", "ate", "nat&q…...

excel 分组排序
excel中会遇到对不同分组数据进行排序,比如对于不同班级里的学生按照分数高低进行升序排序,可以采用如下公式 SUMPRODUCT((A$2:A$12A2)*(C$2:C$12>C2))1 如果需要 进行降序排序,将公式中的大于号替换为小于号即可...

vue三级市区联动
默认返回值格式:all:code、name都返回 name:只返回name code:只返回code,level:可设置显示层级 1: 省 2: 省、市 3: 省、市、区 v-model 默认值 可以是 name: [ "天津市", "天津市",…...
C++ 组合类
所谓组合类便是一个类中含有其他类的对象: #include <iostream> #include <string.h> using namespace std;class dog { public:dog() {}dog(const char *n, int age, const char *v) : age(age){strcpy(this->name, n);strcpy(this->var, v);}// 显示这条狗…...

HTML总结2 [转]
以下转载和参考自:HTML 表单。 1、表格 可以通过 CSS 设置表格的样式: 如下为将上面table.lamp th,td样式中的padding注释掉,开启table.lamp中的padding的效果: 2、列表 3、导航栏 导航栏使用<ul>列表实现,…...

【LeetCode-中等题】2. 两数相加
文章目录 题目方法一:借助一个进制位,以及更新尾结点方法一改进:相比较第一种,给head一个临时头节点(开始节点),最后返回的时候返回head.next,这样可以省去第一次的判断 题目 方法一…...

postman接口参数化设置
为什么需要参数化? 我们在做接口测试的过程中,会遇到需要测试同一个接口使用不同的数据的情况,如果每次去一个个填写数据就太麻烦了,这时我们就需要用到接口参数化,我们把数据单独的存放在一个文件中管理,…...

easyexcel poi根据模板导出Excel
1.导入依赖 <!-- poi依赖--> <dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.0.1</version> </dependency> <!-- poi对于excel 2007的支持依赖--> <dependency…...

怎么把pdf图片转换成jpg?pdf转jpg的方法分享
pdf文件在我们的日常工作中非常的常见,因为这种文件安全性高,不会轻易的乱码,所以受到了我们的欢迎,但是它不容易被编辑,而且占用内存会比较大,所以我们需要将pdf文件进行转换,接下来小编会为大…...

MongoDB 双机热备那篇文章是 “毒”
开头还是介绍一下群,如果感兴趣polardb ,mongodb ,mysql ,postgresql ,redis ,Oracle ,Oceanbase 等有问题,有需求都可以加群群内有各大数据库行业大咖,CTO,可以解决你的问题。加群请加微信号 liuaustin3 (…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...

04-初识css
一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...

基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...

pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)
目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 (1)输入单引号 (2)万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...
如何配置一个sql server使得其它用户可以通过excel odbc获取数据
要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据,你需要完成以下配置步骤: ✅ 一、在 SQL Server 端配置(服务器设置) 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到:SQL Server 网络配…...

6.9-QT模拟计算器
源码: 头文件: widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QMouseEvent>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nullptr);…...