编程语言|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关键字修饰的静态全局变量,是内部链接,限制了变量只在当前文件使用。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

超越极限!《无名之辈》高阶武学与战术应对策略一览!

欢迎来到《无名之辈》世界&#xff01;在这里&#xff0c;决战不仅需要勇气&#xff0c;更需要智慧和策略。为了让你在游戏中游刃有余&#xff0c;以下是一份全面的游戏攻略&#xff0c;助你成为战场上的无敌之王&#xff01; 一、主角战斗技巧&#xff1a; 反击属性至关重要&a…

Vue3状态管理库--Pinia

Pinia快速入门 一、什么是Pinia &#xff1f; Pinia 是 Vue 的专属的最新状态管理库 &#xff0c;是 Vuex 状态管理工具的替代品。 Pinia官网链接 提供更加简单的API &#xff08;去掉了 mutation &#xff09;提供符合组合式风格的API &#xff08;和 Vue3 新语法统一&…

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

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

【C++实验1】学生成绩信息管理系统题解

【问题描述】编写一个基于结构体得学生成绩信息管理系统。 主要功能如下&#xff1a; 1. 用结构体存放所有数据。 2. 每个功能都用函数实现。 3. 输入10个学生的学号和三门课程的成绩。 4. 计算每个学生的总分。 5. 按总分从高到低排序。 6. 加上名次一列。 7. 输出最后…

ssm婚纱摄影管理系统的设计+1.2w字论文+免费调试

项目演示视频&#xff1a; ssm婚纱摄影管理系统的设计 项目介绍: 随着现在网络的快速发展&#xff0c;网上管理系统也逐渐快速发展起来&#xff0c;网上管理模式很快融入到了许多商家的之中&#xff0c;随之就产生了“婚纱摄影网的设计”&#xff0c;这样就让婚纱摄影网的设计更…

【微服务】Nacos(注册中心)

文章目录 1.基本介绍1.概述2.Nacos下载和运行&#xff08;java8/maven3.2.x&#xff09;1.解压到没有中文路径的2.双击startup3.浏览器输入http://192.168.242.124:8848/nacos4.用户名和密码为nacos5.cmd输入netstat -anb | more查看监听端口 2.创建Nacos服务提供者 100041.项目…

springboot实战---4.常用内容小结

&#x1f388;个人主页&#xff1a;靓仔很忙i &#x1f4bb;B 站主页&#xff1a;&#x1f449;B站&#x1f448; &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;SptringBoot &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处…

【项目技术介绍篇】若依管理系统功能介绍

作者介绍&#xff1a;本人笔名姑苏老陈&#xff0c;从事JAVA开发工作十多年了&#xff0c;带过大学刚毕业的实习生&#xff0c;也带过技术团队。最近有个朋友的表弟&#xff0c;马上要大学毕业了&#xff0c;想从事JAVA开发工作&#xff0c;但不知道从何处入手。于是&#xff0…

【scala】使用gradle和scala构建springboot程序

零、版本说明: springboot: 2.7.18 使用log4j2&#xff0c;不使用springboot自带的logback scala版本&#xff1a;2.11 jackson版本&#xff1a;2.16.0 一、依赖&#xff1a; buildscript {dependencies {// using spring-boot-maven-plugin as package toolclasspath("…

Scala第十三章节(作为值的函数及匿名函数、柯里化、闭包及控制抽象以及计算器案例)

章节目标 掌握作为值的函数及匿名函数的用法了解柯里化的用法掌握闭包及控制抽象的用法掌握计算器案例 1.高阶函数介绍 Scala 混合了面向对象和函数式的特性&#xff0c;在函数式编程语言中&#xff0c;函数是“头等公民”&#xff0c;它和Int、String、Class等其他 类型处于…

【华大 HC32L110】调用`printf`和串口接收中断的冲突问题解决

华大单片机 HC32L110调用printf和串口接收中断的冲突问题解决,经过查找是官方库 去使能了 串口的接收功能,记录解决问题的过程 目录 1.硬件MCU资料2. printf和串口接收中断的冲突解决3.重新封装 fputc 函数4.查找问题,发现是官方库配置有误5. 查找寄存器手册,修改寄存器配置…

智慧光伏:企业无纸化办公

随着科技的快速发展&#xff0c;光伏技术不仅成为推动绿色能源革命的重要力量&#xff0c;更在企业办公环境中扮演起引领无纸化办公的重要角色。智慧光伏不仅为企业提供了清洁、可持续的能源&#xff0c;更通过智能化的管理方式&#xff0c;推动企业向无纸化办公转型&#xff0…

MySQL三种开窗函数详细用法,图文详解

开窗函数的详细用法 第一章、开窗函数的语法1.1&#xff09;从聚合开窗函数讲起1.2&#xff09;开窗函数之取值1.3&#xff09;排名开窗函数 第一章、开窗函数的语法 开窗函数的语法为&#xff1a;over(partition by 列名1 order by 列名2 )&#xff0c;括号中的两个关键词par…

谈到视频编码标准时,实际指什么?

当在谈论一个视频编码标准时&#xff0c;实际指是什么&#xff1f;相关论文&#xff0c;还是编解码器代码&#xff0c;或者其他东西&#xff1f; 比如H.264视频编码标准&#xff0c;当论文或书上看到它时&#xff0c;通常是H.264/AVC的形式&#xff0c;如下&#xff1a; It was…

Linux:详解TCP协议(一)

文章目录 认识TCPTCP协议段格式 本篇主要总结的是TCP协议的一些字段 认识TCP TCP协议全称是传输控制协议&#xff0c;也就是说是要对于数据的传输进行一个控制 以上所示的是对于TCP协议进行数据传输的一个理解过程 全双工 至此就可以对于TCP协议是全双工的来进行理解了&…

蓝桥OJ3510 冶炼金属(暴力+二分)

冶炼金属 学习了b站Turing_Sheep的思路 一、暴力模拟 思路&#xff1a; b[i] a[i] / v b[1] a[1] / v b[2] a[2] / v .... b[n] a[n] / v 以上列举中v要满足所有的记录&#xff0c;但凡一个记录不满足&#xff0c;v就不满足题意。 从小到大列举v,设置v最大为1e6 设置一个标…

鸿蒙开发之ArkUI组件常用组件-CustomDialog/Video

CustomDialog 自定义弹窗&#xff08;CustomDialog&#xff09;可用于广告、中奖、警告、软件更新等与用户交互响应操作。我们可以通过CustomDialogController类显示自定义弹窗。 创建自定义弹窗 使用CustomDialog装饰器装饰自定义弹窗CustomDialog装饰器用于装饰自定义弹窗&a…

Vuepress 2从0-1保姆级进阶教程——美化与模板

Vuepress 2 专栏目录 1. 入门阶段 Vuepress 2从0-1保姆级入门教程——环境配置篇Vuepress 2从0-1保姆级入门教程——安装流程篇Vuepress 2从0-1保姆级入门教程——文档配置篇Vuepress 2从0-1保姆级入门教程——范例与部署 2.进阶阶段 Vuepress 2从0-1保姆级进阶教程——全文搜索…

【Java程序设计】【C00388】基于(JavaWeb)Springboot的校园竞赛管理系统(有论文)

Springboot的校园竞赛管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业六年&#xff0c;已经做了六年的毕业设计程序开发&#xff0c;开发过上千套毕业设计程序&#xff0c;博客…

基于ZHW3548的红外额温枪解决方案

红外额温枪&#xff0c;非接触式测量最典型的方法是红外测温。自红外辐射原理被发现以来&#xff0c;红外技术被广泛应用在温度测量中。红外测温仪具有测温范围广&#xff0c;响应速度快&#xff0c;灵敏度高等特点。红外耳温枪、红外额温计和红外筛检仪都属于非接触式体温计。…