C语言程序设计P5-5【应用函数进行程序设计 | 第五节】—知识要点:变量的作用域和生存期

news2024/12/14 9:58:14

知识要点:变量的作用域和生存期

视频:

目录

一、任务分析

二、必备知识与理论

三、任务实施


一、任务分析

有一个一维数组,内放 10 个学生成绩,写一个函数,求出平均分、最高分和最低分。

任务要求用一个函数来完成一组数据中求平均分、最高分和最低分。也就是说希望从函数得到三个结果值,除了可以得到一个函数的返回值以外,还可以利用全局变量得到另外两个值。

二、必备知识与理论

1. 变量的作用域

C语言中变量可以在三种基本位置加以定义:函数内部、函数参数中及所有函数外部,不同的定义范围决定了变量有不同的作用域。变量的作用域是变量在程序中可以有效索引、适当操作的特定区域,也就是作用范围。根据变量的作用范围不同,变量可以分为局部变量和全局变量。

(1)局部变量

局部变量也称为内部变量,该变量是在一个函数内部定义说明的,其作用域仅限于函数内有效,即只有在本函数内才能使用它们,在此函数以外是不能使用的,称之为“局部变量”。

(2)全局变量

全局变量也称为外部变量,该变量在函数外部定义说明。它不属于哪一个函数,而属于一个源程序文件,故全局变量可以为本文件中其它函数所共用。全局变量的位置可以在文件的开头所有函数之前,也可以在两函数之间,甚至在文件的末尾所有函数之后。它的作用域为:从定义变量的位置开始到本源文件结束。

关于全局变量的作用域还要说明以下几点:

(1)全局变量可加强函数模块之间的数据联系。由于同一文件中的所有函数都能引用全局变量的值,因此如果在一个函数中改变了全局变量的值,就能影响到其它函数,相当于各个函数间有直接的传递通道。由于函数的调用只能带回一个返回值,因此有时可以利用全局变量增加与函数联系的渠道,从函数中得到一个以上的返回值。

(2)建议在不必要时不要使用全局变量,因为:

①全局变量在程序的整个执行过程中都占用内存,而不是仅在需要时才开辟内存单元。

②它使函数的通用性降低了,因为函数在执行时要依赖于其所在的外部变量。

③使用全局变量过多,会降低程序的清晰性,人们往往难以清楚地判断出每个瞬时 各个外部变量的值。在各个函数执行时都可能改变外部变量的值,程序容易出错。因此,要限制使用全局变量。

(3)在同一源文件中,允许全局变量和局部变量同名。在局部变量的作用域内,全局变量被“屏蔽”,即不起作用。

【例5.10】全局变量与局部变量同名。

#include <stdio.h>

int y=5;

void f1()

{ y=8;  /*此处是对全局变量y赋值,f1()函数中没有定义任何变量*/

printf("y=%d\n",y);

}

main()

{ int y;

y=3;

  f1();

printf("y=%d\n",y);  /*输出的是main()函数中定义的局部变量y的值*/

}

程序的运行结果为:

y=8

y=3

注意,此例中定义了两个y,一个是全局变量y,定义时被初始化为5,在f1()函数中又被赋值为8,所以在f1()函数中输出的是全局变量y的值,“y=8”。一个是定义在main()函数中的局部变量y,这两个y也只是名称相同的两个不同实体。所以在main()函数中输出的y值是3。

2.变量的生存期

根据前面介绍,从变量的作用域(即从空间)角度来分,可以分为全局变量和局部变量。从变量值存在的时间(即生存期)角度来分,可以分为静态存储变量和动态存储变量。

所谓静态存储方式,是指在程序运行期间分配固定的存储空间的方式。而动态存储方式则是在程序运行期间根据需要进行动态的分配存储空间的方式。

(1)静态存储变量:存放在内存静态存储区中的变量称为静态存储变量。如果在定义静态存储变量时没赋初值,编译系统自动给静态变量赋初值为0。

(2)动态存储变量:存放在内存动态存储区中的变量称为动态存储变量。生存期和作用域是从时间和空间这两个不同角度来描述变量的特性,这两者既有联 系,又有区别,一个变量究竟属于哪一种存储方式,并不能仅从其作用域来判断,还应明确其存储类型说明。

3.变量的存储类别

C语言中的变量和函数都有两个属性:数据类型和存储类别。数据类型决定给数据分配的内存以及操作。存储类别是指数据在内存中的存放位置。对于数据类型,读者已熟悉,在定义一个变量时首先定义数据类型,实际上,还应该定义它的存储类别。变量的存储类别决定了变量的生存期以及给它分配在哪个存储区。

C语言中变量的存储类别共有4种:

(1)自动存储类型

自动变量的类型说明符为auto,这种存储类型是C语言程序中使用最广泛的一种类型。自动变量一般为函数或复合语句内定义的变量(包括形参)。C语言规定,函数内凡未加存储类别说明的变量均视为自动变量,也就是说自动变量可省去说明符auto。在前面程序中所定义的变量都是自动变量。

(2)寄存器存储类型

一般情况下,程序运行时各变量的值是存放在内存中的。如要对某变量进行访问,由控制器发出指令将该变量的值从内存中读到运算器中进行运算。如果变量在程序运行中使用非常频繁,则存取该变量要消耗很多时间,为提高执行效率,C语言允许将局部变量的值存放在CPU的寄存器中,称为寄存器变量。寄存器变量占用CPU的高速寄存器,不占用内存单元,使用时不需要访问内存,寄存器的读写速度比内存读写速度快,因此,可以将程序中使用频率高的变量(如控制循环次数的变量)定义为寄存器变量,这样可提高程序的执行速度。寄存器变量用关键字register作存储类别标识符。 

(3)静态存储类型

静态变量的类型说明符是static,静态变量属于静态存储方式。

①静态局部变量:在局部变量的说明前加上static说明符就构成静态局部变量。

静态局部变量属于静态存储方式,它具有以下特点:

1)静态局部变量在函数内定义,但不像自动变量那样,在调用时存在,退出函数时就消失。静态局部变量始终存在着,数据的值有继承性,每次进行函数调用时可以保存原有数据的值,也就是说它的生存期为整个源程序。

2)静态局部变量的生存期虽然为整个源程序,但是其作用域仍与自动变量相同,即只能在定义该变量的函数内使用该变量。退出该函数后,尽管该变量还继续存在,但不能在其它的函数中使用此变量。

3)对静态局部变量是在编译时赋初值的,即只赋初值一次,在程序运行时它已有初值。以后每次调用函数时不再重新赋初值而只是保留上次函数调用结束时的值。而对自动 变量赋初值,不是在编译时进行的,而是在函数调用时进行的。每调用一次函数重新赋一次初值,相当于执行一次赋值语句。

4)对基本类型的静态局部变量若在说明时未赋以初值,则系统自动赋予0值。而对自动变量不赋初值,则其值是不定的。

②静态全局变量:在函数外定义的变量若没有用static说明,则是全局变量(外部变量)。全局变量的类型说明之前再加以static就构成了静态的全局变量。

(4)外部存储类型

如果在一源文件中将某些变量定义为全局变量,而这些全局变量允许其它源文件中的函数引用,就需要把程序的全局变量告诉所有的模块文件。解决的办法是,在一个模块文件中将变量定义为全局变量,而在其它模块文件中,用extern来说明这些变量。

三、任务实施

本任务是有一个一维数组,内放10个学生成绩,写一个函数,求出平均分,最高分和最低分。

任务要求用一个函数来完成一组数据中求平均分、最高分和最低分。也就是说希望从函数得到三个结果值,除了可以得到一个函数的返回值以外,还可以利用全局变量得到另外两个值。

(1)首先是定义两个全局变量来存放最高分和最低分。

(2)自己定义一个有参函数average()用来完成求10个学生的平均分这个功能并且将平均分作为返回值返回到main()函数中。

(3)在main()函数中调用average()函数完成任务。

程序代码如下:

#include <stdio.h>

float max=0,min=0;

float average(float array[],int n)   /* 定义函数,形参为数组 */

{ int i; 

 float aver,sum=array[0];

 max=min=array[0];

 for(i=1;i<n;i++)

   {if(array[i]>max) max=array[i];

       else if(array[i]<min) min=array[i];

     sum=sum+array[i];

    }

  aver=sum/n;

  return(aver);

   }

main()   /* 主函数 */

{ float ave,score[10];

  int i;

  for(i=0;i<10;i++)

     scanf("%f",&score[i]);

 ave=average(score,10); /* 调用average函数,将得到的值赋给ave */

 printf("max=%6.2f\nmin=%6.2f\naverage=%6.2f\n",max,min,ave);

}

程序的运行结果为:

99 45 78 97 100 67.5 89 92 66 43↙

max=100.00

min= 43.00

average= 77.65

可以看出array和n的值由main提供,单向传递,函数average中aver的值传回main函数,也是单向的,max和min是全局变量,它的值既可以传入函数内,也可从函数传出去。

由此可见,可利用全局变量以减少函数实参与形参的个数,从而减少内存空间以及传递数据时的时间消耗。

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

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

相关文章

Jenkins与SonarQube持续集成搭建及坑位详解

Jenkins和SonarQube都是软件开发过程中常用的工具,它们在代码管理、构建、测试和质量管理方面发挥着重要作用。以下是关于Jenkins与SonarQube的作用及整合步骤环境搭建的详细解释: 一、Jenkins与SonarQube的作用 Jenkins: Jenkins是一个开源的持续集成和交付工具,它可以帮…

item2 for macos

安装Item2 brew install iterm2 查看终端类型 cat /etc/shells Mac OS X 10.15 已经将默认的shell从Bash换成了zsh&#xff0c;所以不用安装&#xff0c;10.15以前的可以使用下面的命令进行安装 brew install zsh 安装Oh My ZSH # curl sh -c "$(curl -fsSL https://ra…

[搜广推]王树森推荐算法——基于物体的协同过滤

基于物体的协同过滤 ItemCF 基于物体的协同过滤&#xff08;Item-Based Collaborative Filtering&#xff0c;简称ItemCF&#xff09;是一种经典的推荐系统算法 基本思想 量化用户对物品的兴趣&#xff0c;通过分析用户的行为来找到与目标物品相似的其他物品&#xff0c;然后…

3D 生成重建035-DiffRF直接生成nerf

3D 生成重建035-DiffRF直接生成nerf 文章目录 0 论文工作1 论文方法2 实验结果 0 论文工作 本文提出了一种基于渲染引导的三维辐射场扩散新方法DiffRF&#xff0c;用于高质量的三维辐射场合成。现有的方法通常难以生成具有细致纹理和几何细节的三维模型&#xff0c;并且容易出…

计算机毕业设计Python+CNN卷积神经网络高考推荐系统 高考分数线预测 高考爬虫 协同过滤推荐算法 Vue.js Django Hadoop 大数据毕设

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

linux - 存储管理

1.了解硬件 -- 磁盘 硬盘有机械硬盘(HDD)和固态硬盘(SDD) 接下来&#xff0c;主要以机械磁盘为例(更具代表性&#xff0c;在linux系统层面&#xff0c;无论是机械磁盘还是固态硬盘&#xff0c;文件的读取和写入都iNode(索引节点)管理文件的元数据和实际数据块) 1.盘片&#x…

打造高效的HIS与DAT文件解析工具

在工业数据采集和存储中&#xff0c;HIS 和 DAT 文件是非常常见的二进制数据格式。然而&#xff0c;解析这些固定块大小的二进制文件并将其转换为易读的 CSV 格式并非易事。本文将深入讲解如何使用 Python 和 PyQt5 打造一款图形化工具&#xff0c;轻松解析和转换这些文件&…

设计模式-装饰器模式(结构型)与责任链模式(行为型)对比,以及链式设计

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言1.装饰器模式1.1概念1.2作用1.3应用场景1.4特点1.5类与对象关系1.6实现 2责任链模式2.1概念2.2作用2.3应用场景2.4特点2.5类与对象关系2.6实现 3.对比总结 前言…

【JavaEE】网络(2)

一、网络编程套接字 1.1 基础概念 【网络编程】指网络上的主机&#xff0c;通过不同的进程&#xff0c;以编程的方式实现网络通信&#xff1b;当然&#xff0c;我们只要满足进程不同就行&#xff0c;所以即便是同一个主机&#xff0c;只要是不同进程&#xff0c;基于网络来传…

题海拾贝:力扣 141.环形链表

Hello大家好&#xff01;很高兴我们又见面啦&#xff01;给生活添点passion&#xff0c;开始今天的编程之路&#xff01; 我的博客&#xff1a;<但凡. 我的专栏&#xff1a;《编程之路》、《数据结构与算法之美》、《题海拾贝》 欢迎点赞&#xff0c;关注&#xff01; 1、题…

SEC_ASA 第二天作业

拓扑 按照拓扑图配置 NTP&#xff0c;Server端为 Outside路由器&#xff0c;Client端为 ASA&#xff0c;两个设备的 NTP传输使用MD5做校验。&#xff08;安全 V4 LAB考点&#xff09; 提示&#xff1a;Outside路由器作为 Server端要配置好正确的时间和时区&#xff0c;ASA防…

IDEA 未启用lombok插件的Bug

项目中maven已引用了lombok依赖&#xff0c;之前运行没有问题的&#xff0c;但有时启动会提示&#xff1a; java: You arent using a compiler supported by lombok, so lombok will not work and has been disabled. Your processor is: com.sun.proxy.$Proxy8 Lombok support…

markdown入门

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

知识库系统,集成neo4j,集成activiti工作流,集成es全文检索,知识图谱血缘关系,nlp知识库

一、项目介绍 一款全源码&#xff0c;可二开&#xff0c;可基于云部署、私有部署的企业级知识库云平台&#xff0c;一款让企业知识变为实打实的数字财富的系统&#xff0c;应用在需要进行文档整理、分类、归集、检索、分析的场景。 为什么建立知识库平台&#xff1f; 助力企业…

AI技术架构:从基础设施到应用

人工智能&#xff08;AI&#xff09;的发展&#xff0c;正以前所未有的速度重塑我们的世界。了解AI技术架构&#xff0c;不仅能帮助我们看懂 AI 的底层逻辑&#xff0c;还能掌握其对各行业变革的潜力与方向。 一、基础设施层&#xff1a;AI 技术的坚实地基 基础设施层是 AI 技…

钉钉机器人消息推送类型案例

CSDN 目录展示 目录 钉钉机器人消息推送1- 文本text类型推送代码案例推送结果参数说明 2- 链接Link类型推送代码案例推送结果参数说明 3- Markdown类型推送代码案例1推送结果1推送代码案例2推送结果2推送代码案例2 (版本2)推送结果2(版本2)参数说明 4- 整体跳转ActionCard类型…

6_Sass 选择器函数 --[CSS预处理]

Sass 提供了一系列的选择器函数&#xff0c;用于操作和组合CSS选择器。这些函数可以帮助你更灵活地创建样式规则&#xff0c;并且可以减少重复代码。以下是几个常用的选择器函数及其用法&#xff1a; 1. selector-append($selector1, $selector2...) selector-append($select…

Wireshark如何查看数据包时间间隔

1.如果数据包量不大&#xff0c;抓包本身也不大&#xff0c;建议从绝对时间判断&#xff0c;打开wireshark软件&#xff0c;并点开相应要分析的抓包文件。 进入到最上方菜单<视图>,在弹出菜单选择时间显示格式&#xff0c;再在右侧菜单中选择自捕获经过的秒数。 这样就可…

jvm内存优化方式

1. JVM&#xff08;Java Virtual Machine&#xff09;&#xff1a; • 定义&#xff1a;Java虚拟机&#xff0c;是运行Java字节码的抽象计算机。 • 内存管理&#xff1a;负责内存的分配和回收&#xff0c;是JVM内存优化的核心。 2. 堆&#xff08;Heap&#xff09;&#xff1a…

【AI日记】24.12.13 kaggle 比赛 2-3 大扫除、断舍离、自己做饭

【AI论文解读】【AI知识点】【AI小项目】【AI战略思考】【AI日记】 工作 参加&#xff1a;kaggle 比赛 Regression with an Insurance Dataset参考&#xff1a;kaggle 回归类入门比赛 House Prices - Advanced Regression Techniques内容&#xff1a;构建自己的EDA&#xff08…