C语言基础篇4:变量与存储

1 局部变量和全局变量

        在介绍局部变量和全局变量前,先了解一些关于作用域方面的内容。作用域的作用就是决定程序中的哪些语句是可用的,换句话说,就是程序中的可见性。作用域有局部作用域和全局作用域,那么局部变量就具有局部作用域,而全局变量就具有全局作用域。

1.1 局部变量

        在一个函数的内部定义的变量就是局部变量,无法被别的函数使用。函数的形参也属于局部变量,作用范围仅限于函数内部的语句块。

【示例1.1】局部变量的作用域

#include <stdio.h>
int main(){
    int i = 1;
    if(i > 0){
        int j = 2;
        if(j > 0){
            int m = 3;
            printf("all number %d %d %d \n",i,j,m);
        }
    }
    return 0;
}

        在C语言中位于不同作用域的变量可以使用相同的标识符,也就是在这种情况下,变量名可以相同。如果在一个函数中,内层作用域中定义的变量和已经声明过的某个外层变量有相同的名字,那么内层作用域中的变量将覆盖外层作用域中的那个变量。

1.2 全局变量

        程序的编译单位是源文件,上面说到,在函数中定义的变量称为局部变量。如果一个变量在所有的函数的外部声明,这个变量就是全局变量。全局变量是可以在程序中的任何位置进行访问的变量。

【注意】全局变量不属于某个函数,而是整个源文件。但如果外部文件要进行调用,需要使用extern进行引用修饰。

        定义全局变量的作用是增加了函数间数据联系的渠道。由于同一个文件中的所有函数都能引用全局变量的值,因此如果在一个函数中改变了全局变量的值,就会影响到其他函数。

【示例1.2】使用全局变量

#include <stdio.h>
int global = 100; //定义全局变量
void Store1Price();
void Store2Price();
void Store3Price();
void ChangePrice();
int main(){
    printf("调整之前,全局变量的值是: %d \n",global);
    Store1Price();
    Store2Price();
    Store3Price();
    ChangePrice();//修改全局变量的值
    printf("调整之后,全局变量的值是: %d \n",global);
    Store1Price();
    Store2Price();
    Store3Price();
}
void Store1Price(){
    printf("全局变量的值是:%d \n",global);
}
void Store2Price(){
    printf("全局变量的值是:%d \n",global);
}
void Store3Price(){
    printf("全局变量的值是:%d \n",global);
}
void ChangePrice(){
    printf("是否需要改变全局变量的值,希望改成:");
    scanf("%d",&global);
}

2 变量的存储类别

        变量的存储类别决定变量什么时候被分配到指定的内存空间中,以及在什么时候释放内存空间。因此,存储类别就是为变量分配使用内存空间的方式,也可以称为存储方式。变量的存储类别分为两种形式,动态存储和静态存储。并且可以通过存储类修改符来告诉编译器要处理什么样的类型变量。具体有自动(auto)、静态(static)、寄存器(register)和外部(extern)4种。

2.1 静态存储和动态存储

         从变量的产生时间上可以分为静态存储和动态存储。

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

        要理解动态存储和静态存储方式,首先要了解内存中用户存储空间的基本情况。系统提供用户的存储空间可以分为3个部分:程序区、静态存储区和动态存储区。

        其中,程序区用来存放用户要执行的程序段。数据分别放在静态存储区和动态存储区中。

        静态存储的变量位于内存的静态存储区,全局变量都保存在静态存储区中,因此全局变量从程序执行时开发分配存储单元,直到程序运行结束,才释放其所占的存储单元。

        在动态存储区中存储跟堆栈操作相关的数据有关,堆栈中的数据随着进栈出栈操作而变化,当变量被弹出堆栈以后,其生存周期也就结束了。在调用函数时,其局部变量也被保存到动态存储区中,当函数结束执行,返回到主调函数时,变量所占用的空间将被释放,此时局部变量也将消失。由此可见,如果一个函数被调用了两次,其中变量的存储空间可能为不同的地址。

        个存储区所存放的数据内容如下:

        1、静态存储区:存储全局变量,在程序执行过程中,全局变量占据固定的内存空间,直到程序执行完毕才释放内存。

        2、动态存储区:

                1)自动变量,在函数调用时分配存储空间,调用完成释放存储空间。

                2)函数调用时现场保护和返回地址,在函数被调用时分配内存空间。

                3)函数形参:只有在调用该函数时才能为形参分配内存空间,调用完以后会将所有的空间释放掉。

        从上述分析可知,静态存储变量是一直都存在的,而动态存储变量则是根据函数执行过程决定是否存在还是消失。

2.2 auto变量

        该存储类型是C语言中使用最广泛的一种类型。C语音规定,函数内凡未加存储类型说明的变量,默认都是自动变量,也就是说自动变量可以省去说明符auto。

        自动变量有以下特点:

        1、自动变量的作用域仅限于定义该变量的个体内。在函数中定义的自动变量,只在该函数中有效。在复合语句中定义的自动变量只在该复合语句中有效。

        2、自动变量属于动态存储方式,只有在使用它时,即定义该变量的函数被调用时才给它分配存储单元,函数调用结束,释放存储单元。因此函数调用结束后,自动变量的值不能保留。同样在复合语句中定义的自动变量,在退出复合语句后也不能在使用。
 

2.3 static变量

        在编写程序的过程中,有些函数的局部变量的值在函数调用结束后不希望值消失,也就是不释放该变量所占用的存储单元;同样,有时在程序设计中也希望某些外部变量只限于被本文件引用,而不能被其他文件引用。这时就需要使用关键词static对变量进行声明。

        1、静态局部变量

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

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

        1)、静态局部变量在函数内定义,但与自动变量不同,当调用时就已经存在,退出函数时消失。静态局部变量属于静态存储类别,在静态存储区内分配存储单元,在程序整个运行期间都不会释放,静态局部便令始终存储,也就是说它的生存期为整个源程序。

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

        3)、对基本类型的静态局部变量,如果在声明时没有赋初始值,则系统自动赋值0。而对于自动变量不赋初值,其值是不确定的。

【示例2.3】使用静态变量

#include <stdio.h>
int add(int x){
    static int n = 0;
    n = n + x;
    return n;
}
int main(){
    int i,j,sum;
    printf("请输入一个整数:\n");
    scanf("%d",&i);
    for (j = 1;  j< i; j++) {
        sum = add(j);
        printf("%d:%d \n",j,sum);
    }
    return 0;

}

        上面代码中的静态局部变量n是一种生存期为真个源程序的变量。每次调用add函数时,静态局部变量n都保存了前次被调用后留下的值。如果将static改成auto,那么运行结果是:

 

        因此,从运行结果可以看出,自动变量占动态存储区空间,而不占静态存储区空间,导致每次调用后变量n的值都被释放,每次调用add方法时,n的值都是从0开始。

        2 静态全局变量

        在全局变量的变量类型说明之前加上static就构成了静态的全局变量。全局变量本身就是静态存储方式,静态全局变量自然也是静态存储方式。两者在存储方式上并不同。两者的区别在于作用域不同,非静态全局变量的作用域是整个源程序,当一个源程序有多个源文件组成时,非静态的全局变量在各个源文件都是有效的。

        例如,在file1.c中定义了非静态全局变量i,则在其他的源文件(如file2.c)中也可以调用;而静态全局变量则限制了其作用域,即只在定义该变量的源文件中有效,在同一源程序的其他源文件中不能使用它。例如,在file1.c中定义了静态全局变量,则在其他的源文件(file2.c)中不可以调用。

        【说明】static说明符在不同的地方所起的作用是不同的。将局部变量改变为静态变量后是改变了它的存储方式,即改变了其生存周期。将全局变量改变为静态变量后是改变了它的作用域,限制其使用范围。

2.4 register变量

        通常变量的值是存放在内存中,当对一个变量频繁读写时,则需要反复访问内存,从而花费大量的时间。为了提高效率,C语言提供了另一种变量,即寄存器变量。这种变量允许将局部变量的值存放在CPU的寄存器中,使用时不需要访问内存,而直接从寄存器中读写。寄存器变量的说明符是register。

        对寄存器变量还需要说明以下几点:

        用户无法获取寄存器变量的地址,因为绝大多数计算机的硬件寄存器都不占用内存地址。而且,即使编译器忽略register而把变量存放在可设定的内存中,也是无法获取变量的地址的。

        如果想要有效地利用寄存器register关键字,必须像汇编语言程序员那样了解处理器的内部结构,直到可用于存储变量的寄存器的数量、种类以及工作方式。但是,对于这些细节不同的计算机还可能是不同的。因此,对于一个要具备可移植的程序来说,regis作用不大。

2.5 extern变量

        由于C语言允许将一个较大的程序分成若干独立模块文件分别编译,如果一个源文件中的函数想引用其他源文件中的变量,就可以用extern来声明外部变量,也就是说extern变量可以扩展外部变量的作用域。

        

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

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

相关文章

火山引擎 DataLeap 计算治理自动化解决方案实践和思考

更多技术交流、求职机会&#xff0c;欢迎关注字节跳动数据平台微信公众号&#xff0c;回复【1】进入官方交流群 【导读】本文旨在探讨火山引擎 DataLeap 在处理计算治理过程中所面临的问题及其解决方案&#xff0c;并展示这些解决方案带来的实际收益。主要内容包括&#xff1a;…

专业开源人员的需求仍在增长

Linux 基金会执行总监根据 Dice.com 的一项调查结果表示&#xff1a;「开源正变得越来越专业化&#xff0c;各大公司都在寻求具备这方面技能的专业型人才。」网上有研究分析了两组「2017 年度开源工作调查与报告」&#xff0c;主要分析结果如下&#xff1a; 89% 的招聘人员表示…

代码人生里哪些书触动灵魂?技术大咖精选8本好书为你揭秘!

导语 | 在这个快节奏、信息繁杂的时代&#xff0c;我们总在寻找那些能够触动内心、启迪思维的知识瑰宝。书籍&#xff0c;无疑是我们忠诚的伙伴和引路人。10 月 18 日&#xff0c;腾讯云 TVP 举办了第八期 TVP 读书分享会&#xff0c;汇集 4 位技术大咖&#xff0c;为你倾情推荐…

[pytorch]设备选择以及卷积神经网络的应用

0.写在前面: 首先这篇文章还没写完,因为今天要尝试对我之前的一个框架做一个简单的更新迭代,所以目前先更新这么多. 1.关于设备的选择 首先,目前的大多数电脑都是自带一些GPU(图形计算单元,在这里被称之为cuda), 需要安装相关的驱动才能正常使用这些设备和调用他们的具体情况…

浪涌保护器(SPD)常见的几种抑制器件特点及应用

浪涌保护器&#xff0c;Surge protection Device&#xff0c;是一种为各种电子设备、仪器仪表、通讯线路提供安全防护的电子装置&#xff0c;适用于交流50/60HZ&#xff0c;额定电220V/380V的供电系统中。当电气回路或者通信线路中因为外界的干扰突然产生尖峰电流或者电压时&am…

名师助阵龙讯旷腾PWmat+半导体缺陷培训暨半导体缺陷计算大赛

半导体缺陷计算大赛 选拔赛截止日期&#xff1a;11月23日 参与杭州线下培训直接跳过选拔赛 大赛亮点 线上免费培训、线下限时领取免费名额 线下杭州培训可直通决赛&#xff0c;跳过选拔赛 线上培训有3次机会参与考试进入决赛 已购/未购用户均可参加、无身份限定 使用Mc…

el-table解决数据过少小于高度有留白的问题

问题:给el-table设置个高度,高度为500px,之后就添加如下4条数据,那么底部就没数据,直接就空白了,本文章就是为了解决这个问题,如果底部留白那么就添加几条空数据就行了.如果数据已达到高度了那么就不会留白了 1.效果 这个空列可以根据高度来决定添加几个空格子去铺满列表&…

UE基础必学系列:项目和文件结构

官方文档:https://learn.unrealengine.com/course/ 张佳亮:UE4插件相关说明文档 1、uproject,以商城下载的ActionRPG为例 {"FileVersion": 3,"EngineAssociation": "4.20","Category": "Samples","Description&qu…

Springboot+vue的人力资源管理系统(有报告)。Javaee项目,springboot vue前后端分离项目

演示视频&#xff1a; Springbootvue的人力资源管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot vue前后端分离项目 项目介绍&#xff1a; 本文设计了一个基于Springbootvue的前后端分离的企业资产管理系统&#xff0c;采用M&#xff08;model&…

SystemC 学习之 VCS 仿真工具安装(八)

1、安装包下载 vcs、verdi 等工具下载地址&#xff08;如果下载链接失效&#xff0c;可以私信我&#xff09; 链接&#xff1a;https://pan.baidu.com/s/19CtwqWcxpv-4wPyAD4_ITw 提取码&#xff1a;3pib vcs-mx 下载地址 链接&#xff1a;https://pan.baidu.com/s/1dYELrG…

如何选择共享wifi项目服务商,需要注意哪些?

在移动互联网时代&#xff0c;无线网络已经成为人们生活中不可或缺的一部分。随着5G时代的到来&#xff0c;共享WiFi项目成为了市场上备受关注的焦点。在众多共享WiFi公司中&#xff0c;如何选择共享wifi项目服务商合作&#xff0c;今天我们就来盘点下哪些公司可靠&#xff01;…

Java实现一个简单的贪吃蛇小游戏

一、创建新项目 首先创建一个新的项目&#xff0c;并命名为贪吃蛇。 其次在贪吃蛇项目下创建一个名为images的文件夹用来存放游戏相关图片。 用到的图片如下&#xff1a; 游戏标题&#xff1a; 贪吃蛇的身体&#xff1a; 贪吃蛇的头部&#xff1a; 因为要向四个方向移动&am…

【Proteus仿真】【STM32单片机】停车场车位管理系统

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真STM32单片机控制器&#xff0c;使用按键、LED、蜂鸣器、LCD1602、红外传感器、74HC595模块等。 主要功能&#xff1a; 系统运行后&#xff0c;LCD1602显示进入、驶出、剩余车位数…

TikTok与心灵成长:娱乐与启发并重

社交媒体已成为我们生活的一部分&#xff0c;其中TikTok以其短视频内容和创新性而闻名。然而&#xff0c;TikTok不仅仅是一个娱乐平台&#xff0c;它还具有潜力成为心灵成长的有力工具。本文将探讨TikTok如何在娱乐与启发之间取得平衡&#xff0c;以促进心灵成长和积极影响。 娱…

Kotlin Multiplatform稳定版本发布:加速跨平台开发的新里程碑

Kotlin Multiplatform稳定版本发布&#xff1a;加速跨平台开发的新里程碑 引言 在最新的消息中&#xff0c;JetBrains团队宣布Kotlin Multiplatform&#xff08;KMP&#xff09;将于2023年10月稳定发布。这一消息对于广大开发者来说毫无疑问是一个令人振奋的消息。KMP的正式生…

Spring Data JPA方法名命名规则

最近巩固一下JPA&#xff0c;网上看到这些资料&#xff0c;这里记录巩固一下。 一、Spring Data Jpa方法定义的规则 简单条件查询 简单条件查询&#xff1a;查询某一个实体类或者集合。 按照Spring Data的规范的规定&#xff0c;查询方法以find | read | get开头&…

2020年五一杯数学建模C题饲料混合加工问题解题全过程文档及程序

2020年五一杯数学建模 C题 饲料混合加工问题 原题再现 饲料加工厂需要加工一批动物能量饲料。饲料加工需要原料&#xff0c;如加工猪饲料需要玉米、荞麦、稻谷等。加工厂从不同的产区收购了原料&#xff0c;原料在收购的过程中由于运输、保鲜以及产品本身属性等原因&#xff…

比尔·盖茨谈他对软件应用和人工智能代理未来的见解

比尔盖茨在他的 Gatesnotes 网站中发表了一篇文章&#xff0c;分享了他对软件应用和人工智能代理未来的见解。他认为人工智能代理将大行其道&#xff0c;在接下来的五年里&#xff0c;这将完全改变。你不需要为不同的任务使用不同的应用程序。你只需用日常语言告诉你的设备你想…

C++编程案例讲解-评委打分案例

评委打分案例 案例说明 案例说明 有5名选手&#xff0c;10个评委分别对每一名选手打分&#xff0c;去除最高分&#xff0c;去除最低分&#xff0c;取平均分 要求以下步骤&#xff1a; 创建5名选手&#xff0c;放到vector中遍历vector容器&#xff0c;取出来每一位选手&#x…

SMART PLC 和S7-1200PLC MODBUSTCP通信速度测试

SMART PLC MODBUSTCP通信详细介绍请参看下面文章链接: S7-200SMART PLC ModbusTCP通信(多服务器多从站轮询)_matlab sumilink 多个modbustcp读写_RXXW_Dor的博客-CSDN博客文章浏览阅读6.4k次,点赞5次,收藏10次。MBUS_CLIENT作为MODBUS TCP客户端通过S7-200 SMART CPU上的…