编程语言|C语言——C语言变量的存储方式

前言

变量是程序中数据的存储空间的抽象。变量的存储方式可分为静态存储和动态存储两种。

静态存储变量通常是在程序编译时就分配一定的存储空间并一直保持不变,直至整个程序结束。在上一部分中介绍的全局变量的存储方式即属于此类存储方式。

动态存储变量是在程序执行过程中使用它时才分配存储单元,使用完毕立即释放。典型的例子是函数的形参。在函数定义时并不给形参分配存储单元,只是在函数被调用时,才予以分配,调用函数完毕立即释放。如果一个函数被多次调用,则反复地分配、释放形参变量的存储单元。

从以上分析可知,静态存储变量是一直存在的,而动态存储变量则时而存在时而消失。因此,这种由于变量存储方式不同而产生的特性称为变量的生存期,生存期表示了变量存在的时间。

生存期和作用域是从时间和空间这两个不同的角度来描述变量的特性。这两者既有联系,又有区别。一个变量的存储方式究竟属于哪一种存储方式,并不能仅仅从作用域来判断,还应有明确的存储模型说明。

变量的存储模型由作用域、链接点及存储期三大属性来描述。其中,存储期描述的是变量在内存中的生存时间。存储模型也经常被表达为存储类,共有以下5种存储模型。

一、自动auto

变量的声明语法为

<存储类型> 数据类型 变量名

auto为存储类说明符,可以说明一个变量为自动变量。该类具有动态存储期、代码块的作用域和空链接。如果变量没有初始化,它的值是不确定的。

代码块或者函数头部定义的变量,可使用存储类修饰符auto来明确标识属于自动存储类型。若没有使用auto修饰,也属于自动存储类型。

例如:

{int i,j,k;charc;
)

等价于:

{auto int i,j,k;auto charc;
}

自动变量具有以下特点:

  • 自动变量的作用域仅限于定义该变量的模块内。在函数中定义的自动变量,只在该函数内有效。在复合语句中定义的自动变量,只在该复合语句中有效。
  • 自动变量属于动态存储方式,只有在定义该变量的函数被调用时才给它分配存储单元,开始它的生存期。函数调用结束,释放存储单元,结束生存期。因此函数调用结束之后,自动变量的值不能保留。在复合语句中定义的自动变量,在退出复合语句后也不能再使用,否则将引起错误。
  • 由于自动变量的作用域和生存期都局限于定义它的模块内(函数或复合语句内),因此不同的模块中允许使用同名的变量而不会混淆。即使在函数内定义的自动变量也可与该函数内部的复合语句中定义的自动变量同名,但读者应尽量避免使用这种方式。

例如:

int loop(int n)
{int m;m=2;{int i,m;//m,i的作用域m=20;for(i=m;i<n;i++)printf(……);}//m作用域,i消失return m;
}

二、寄存器

在一个代码块内(或在一个函数头部作为参量)使用修饰符register声明的变量属于寄存器存储类。register修饰符暗示编译程序相应的变量将被频繁使用,如果可能的话,应将其保存在CPU的寄存器中,从而加快其存取速度。该类与自动存储类相似,具有自动存储期、代码块作用域和空链接。如果没有被初始化,它的值也是不确定的。

使用register修饰符有几点限制。

  • register变量必须是能被CPU寄存器所接受的类型,这通常意味着register变量必须是一个单个的值,并且其长度应小于或等于整型的长度(int char *p)。这与处理器的类型有关。
  • 声明为register仅仅是一个请求,而非命令,因此变量仍然可能是普通的自动变量,没有放在寄存器中。
  • 由于变量有可能存储在寄存器中,因此不能用取地址运算符“&”获取register变量的地址。如果有这样的写法,编译器会报错。
  • 只有局部变量和形参可以作为register变量,全局变量不行。
  • 实际上有些系统并不把register变量存放在寄存器中,而优化的编译系统则可以自动识别使用频繁的变量而把它们放在寄存器中。

三、静态和空链接

静态变量的类型说明符:static。在一个代码块内使用存储类修饰符static声明的局部变量属于静态空链接存储类。该类具有静态存储时期、代码块作用域和空链接。

静态变量的存储空间是在编译完成后就分配了,并且在程序运行的全部过程中都不会撤销。这里要区别的是,属于静态存储方式的变量不一定就是静态变量。

例如外部变量虽属于静态存储方式,但不一定是静态变量,必须由static加以定义后才能称为静态外部变量,或称静态全局变量。

对比图

静态变量可分为静态局部变量和静态全局变量。静态局部变量属于静态存储方式,它具有以下特点。

  • 静态局部变量在函数内定义,它的生存期为整个程序执行期间,但是其作用域仍与自动变量相同,只能在定义该变量的函数内使用该变量。退出该函数后,尽管该变量还继续存在,但不能使用它。
  • 可以对构造类静态局部量赋初值、例如数组。若未赋初值,则由系统自动初始化为0。
  • 基本数据类型的静态局部变量若在说明时未赋初值,则系统自动赋予0。而对自动变量不赋初值。值就是不确定的,根据静态局部变量的特点,可以看出它是一种生存期为整个程序运行期的变量。虽然离开定义它的函数后不能使用、但如再次调用定义它的函数时,它又可以继续使用,并且保留了上次被调用后的值,

因此、当多次调用一个函数且要求在调用之前保留某些变量的值时,可以考虑采用静态局部变量。虽然用全局变量也可以达到上述目的,但全局变量有时会造成意外的副作用、因此仍以采用静态局部变量为宜。

四、静态和外部链接

未使用static修饰的全局变量属于静态、外部链接存储类。具有静态存储时期、文件作用域和外部链接。仅在偏译时初始化一次。如未明确初始化,它的字节也被设定为0。在使用外部变量的函数中使用extern关键字来再次声明。如果是在其他文件中定义的,则必须使用extern。

五、静态和内部链接

全局变量在关键字之前再冠以static就构成了静态的全局变量,属于静态、内部链接存储类。与静态、外部链接存储类不同的是、具有内部链接,使得仅能被与它在同一个文件的函数使用。这样的变量也是仅在编译时初始化一次。如未明确初始化,它的字节被设定为0。

这两者的区别在于非静态全局变量的作用域是整个源程序,但当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的;而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效、在同一源程序的其他源文件中不能使用。

由于静态全局变量的作用域局限于一个源文件内,只能被该源文件内的函数使用,因此可以避免在其他源文件中引起错误。

静态全局变量及非静态全局变量的区别示意图。

从以上分析可以看出,把局部变量改变为静态变量后改变了它的存储方式,即改变了它的生存期。把全局变量改变为静态变量后改变了它的作用域,限制了它的使用范围。因此static这个说明将在不同的地方所起的作用是不同的。
例如:源文件a.c

	int a=10;/全局变量,静态外部链接static int b=20:/静态全局变量,静态内部链接intf(){int m=30;return m;}

源文件b.c

	#include<stdio.h>/*使用extern关键字,声明外部变量*/extern int b;extern int a:int main(){printf("a=%d\n",a);printf("b=%d\n",b);return 0:}

编译程序,出现以下错误:

error:In function*main':
static _b.c:(. text+0x22):undefined reference to'b'
collect2:Id returned 1 exit status

分析:本例说明了,普通全局变量,是外部链接,可以被其他文件引用。有static关键字修饰的静态全局变量,是内部链接,限制了变量只在当前文件使用。

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

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

相关文章

Wireshark 抓包工具与长ping工具pinginfoview使用,安装包

一、Wireshark使用 打开软件&#xff0c;选择以太网 1、时间设置时间显示格式 这个时间戳不易直观&#xff0c;我们修改 2、抓包使用的命令 1&#xff09;IP地址过滤 ip.addr192.168.1.114 //筛选出源IP或者目的IP地址是192.168.1.114的全部数据包。 ip.sr…

AcWing 2816. 判断子序列(双指针)

—>原题链接 思路: 1.首先定义两个指针 i 和 j 分别指向x和y的起始位置 2.开始循环遍历x和y数组,如果 x[i] y[j] 那么i,否则j,遍历到最后in那么就说明x是y的子序列 图解 上代码: #include <iostream> using namespace std;const int N 111111;int n,m,x[N],y[N]…

2024年黑龙江省安全员C证证模拟考试题库及黑龙江省安全员C证理论考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年黑龙江省安全员C证证模拟考试题库及黑龙江省安全员C证理论考试试题是由安全生产模拟考试一点通提供&#xff0c;黑龙江省安全员C证证模拟考试题库是根据黑龙江省安全员C证最新版教材&#xff0c;黑龙江省安全员…

Git命令及GUI基本操作

不习惯使用Git命令的可移步下面Git GUI基本操作 Git 常用命令 git branch 查看本地所有分支 git status 查看当前状态 git commit 提交 git branch -a 查看所有的分支 git branch -r 查看本地所有分支 git commit -am "init" 提交并且加注释 git remote add orig…

实用攻略:选择最佳项目管理软件!适合远程团队使用!

2019年新冠疫情爆发&#xff0c;这场全球范围的大流行病不仅对经济构成威胁&#xff0c;还引发了大家对经济衰退的担忧。许多先进企业和组织立即转变思路通过远程办公的方式开展工作。本文为大家介绍适合远程团队的项目管理软件&#xff0c;项目管理软件选型指南。 现实中&…

尚宝罗邀您参观2024第13届生物发酵展

参展企业介绍 尚宝罗江苏节能科技股份有限公司坐落于扬州市的北大门素有“中国荷藕之乡”、“中国生态示范县”---宝应。这里环境优美&#xff0c;气候宜人&#xff0c;交通十分便利。 尚宝罗公司占地面积36000平方米,建筑面积15800平方米。公司拥有大型加工设备60台套,精密加…

MySQL数据库高阶语句②

目录 一.子查询与多表查询 1.子查询 2.update子查询 3.多表查询 4.delete子查询 5.exists关键字也用于子查询 6.结果集 二.MySQL视图 1.定义 2.作用场景 3.视图与表的区别与联系 &#xff08;1&#xff09;区别 ①视图是已经编译好的sql语句。而表不是 ②视图没有…

Pytorch入门实战 P4-猴痘图片,精确度提升

目录 一、前言&#xff1a; 二、前期准备&#xff1a; 1、设备查看 2、导入收集到的数据集 3、数据预处理 4、划分数据集&#xff08;8:2&#xff09; 5、加载数据集 三、搭建神经网络 四、训练模型 1、设置超参数 2、编写训练函数 3、编写测试函数 4、正式训练 …

【C++初阶】之类和对象(下)

【C初阶】之类和对象&#xff08;下&#xff09; ✍ 再谈构造函数&#x1f3c4; 初始化列表的引入&#x1f498; 初始化列表的语法&#x1f498; 初始化列表初始化元素的顺序 &#x1f3c4; explicit关键字 ✍ Static成员&#x1f3c4; C语言中的静态变量&#x1f3c4; C中的静…

Linux(3)软件安装-Centos 8.1安装-硬盘分区方案对比-linux上运行jar包-File上传下载

四、软件安装 1、Centos 8.1安装 1.1 安装过程 1、下载 CentOS 8.1 ISO 镜像文件 访问 CentOS 官方网站的下载页面。选择适当的版本&#xff0c;例如 CentOS Linux 8.1 (Linux Kernel 5.10.0-36)。根据您的硬件架构下载对应的 ISO 镜像文件&#xff08;如 CentOS-8.1-x86_6…

vue3全局引入element-plus使用Message教程

文章目录 安装引入 Element Plus和组件样式示例注意安装与引入&#xff1a;按需引入&#xff1a;API 使用&#xff1a;样式问题&#xff1a;组件上下文&#xff1a;版本兼容性&#xff1a;错误处理&#xff1a; 这是 Element UI 的 Vue 3 版本。ElMessage 是 Element Plus 中的…

2024上半年软考软件评测师报名流程及注意事项

2024年5月软考软件评测师报名入口&#xff1a; 中国计算机技术职业资格网&#xff08;http://www.ruankao.org.cn/&#xff09; 2024年软考报名时间暂未公布&#xff0c;考试时间上半年为5月25日到28日&#xff0c;下半年考试时间为11月9日到12日。不想错过考试最新消息的考友…

如何用Flask中的Blueprints构建大型Web应用

本文分享自华为云社区《构建大型Web应用Flask中的Blueprints指南》&#xff0c;作者&#xff1a; 柠檬味拥抱。 什么是Blueprints&#xff1f; 什么是Blueprints&#xff1f; Blueprints是Flask中的一种模式&#xff0c;用于将应用程序分解为可重用的模块。每个蓝图实际上是…

大型网站集群管理负载均衡

课程介绍 结合企业大规模应用&#xff0c;解决应用高并发问题&#xff0c;解决单节点故障问题&#xff0c;缓存数据库的应用。学完掌握知识点&#xff1a;企业应用实现四七层负载均衡&#xff0c;以及Nginx等应用的高可用性&#xff0c;Redis缓存数据库的部署应用以及高可用方…

Mongodb入门到入土,安装到实战,外包半年学习的成果

这是我参与「第四届青训营 」笔记创作活动的的第27天&#xff0c;今天主要记录前端进阶必须掌握内容Mongodb数据库,从搭建环境到运行数据库,然后使用MongodB; 一、文章内容 数据库基础知识关系型数据库和非关系型数据库为什么学习Mongodb数据库环境搭建及运行MongodbMongodb命…

Swift 周报 第四十八期

文章目录 前言新闻和社区苹果突然不造车了&#xff0c;雷军&#xff1a;非常震惊&#xff01;分析师&#xff1a;马斯克或是最大赢家你会爱上的开发者活动 提案通过的提案正在审查的提案 Swift论坛推荐博文话题讨论关于我们 前言 本期是 Swift 编辑组自主整理周报的第四十八期…

SQLiteC/C++接口详细介绍sqlite3_stmt类(八)

返回&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;SQLiteC/C接口详细介绍sqlite3_stmt类&#xff08;七&#xff09; 下一篇&#xff1a; SQLiteC/C接口详细介绍sqlite3_stmt类&#xff08;九&#xff09; 27、sqlite3_column_int 函数 sqlite3_column_int 用于返…

实物档案管理系统是做什么的

实物档案管理系统是用于管理和组织实物档案的信息系统。它的主要功能包括记录、查找、归档实物档案&#xff0c;以及提供相关的管理功能。 具体来说&#xff0c;玖拓智能实物档案管理系统可以帮助单位完成以下任务&#xff1a; 1. 档案登记与归档&#xff1a;将新收到的实物档案…

2024年【低压电工】实操考试视频及低压电工考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 低压电工实操考试视频是安全生产模拟考试一点通生成的&#xff0c;低压电工证模拟考试题库是根据低压电工最新版教材汇编出低压电工仿真模拟考试。2024年【低压电工】实操考试视频及低压电工考试试题 1、【单选题】()…

MySQL ② —— 索引原理

1. 索引 1.1 分类 主键索引、唯一索引、普通索引、组合索引、以及全文索引 主键索引 非空唯一索引&#xff0c;一个表只有一个主键索引&#xff1b;在 innodb 中&#xff0c;主键索引的 B 树包含表数据信息。 唯一索引 不可以出现相同的值&#xff0c;可以有 NULL 值。 …