文 | Edward

4.4 变量的补充

前面内容中,我们已经讨论了变量的定义,但是由于函数的概念还没有引入,因而这是不全面的,本节开始,我们再来补充一些变量的其他内容,这就相当于对变量这个概念的重新认识。

我们之前讲的变量定义,都是定义在“main()“函数里面的,并且告诉大家了变量定义的一个原则,即变量先定义后使用。其实早在C90的时候,只允许函数定义完成之后,紧接着将所有的变量都定义好然后再使用,如图4-4-1所示。一旦发现有在程序语句后面定义变量,编译器就会报错。典型的就是51单片机的编程语言KeilC51,它是基于C90开发的一套特殊的C语言,因此相信大家做过51单片机的,都遇到过这种莫名其妙的错误,如图4-4-2所示。这个问题是早期的K&R C就遗留下来的。

图4-4-1 C90的变量定义

图4-4-2 C51变量定义错误

而C99开始就已经修改了这种别扭的设定,从此以后,你可以在任何地方定义你想要定义的变量,只要这个变量是在使用之前被定义的即可。如图4-4-3所示。

图4-4-3 C99变量定义

但是,最根本的原则不能变,即变量要在使用之前被定义,如果先使用变量然后再定义变量,编译器就会报错。如图4-4-4所示。

图4-4-4 变量先使用后定义导致报错

以上是变量定义时的详细补充,下面的内容,我们将细致地讨论以下内容:

Ø全局变量和局部变量;

Ø静态变量和常变量。

(1)全局变量和局部变量

定义在函数内部的变量叫做局部变量,当我们将这个变量定义完成之后,即可以在当前函数内部使用。而一旦函数被调用完成之后,局部变量将会被编译器回收,即只有在使用时才分配存储空间的变量为局部变量。如图4-4-3中的“int a; int b; int c;”,都是局部变量。为了说明定义在函数中的局部变量每次运行完成之后会被回收,每次使用会被重新定义,我们可以设计一个程序来说明这个现象。如图4-4-5所示。

图4-4-5 局部变量验证

图4-4-5中,我们定义了一个函数“LoacalVarPrint”,这个函数的主要功能是,定义一个局部变量,对其自加,然后打印出来,而主函数写了一个“for(;;)”的空循环,这个循环和“while(1)”等价,即不断地调用而不退出,在这个循环里面,主函数不断地调用“LoacalVarPrint”函数,“Sleep(500)”的原型是Sleep(n),它是Windows中的系统函数(API),所以需要包含“windows.h”,其功能是延迟n毫秒。主函数中还有一个不断自加的变量,每调用一次就对其自加。如果加设局部变量退出时是不会被回收,重新调用函数时是不会被重新初始化,那么“LoacalVarPrint”函数中的变量“var_to_watch”应该被不断地自加,但是现在查看程序的输出结果,它永远为1,也就是说,主函数每次调用函数时,这个变量重新被初始化(定义变量缺省初始化时,编译器一般自动赋初值为0),然后自加1,因此这个程序的输出永远为1。退出这个循环程序使用“Ctrl + C”。

全局变量是指定义在函数外面的变量,它其实有个默认的属性,即“静态属性”,所谓静态属性和下面所讲的静态变量类似,一旦编译器分配存储空间给它便不会回收了,它将永远存在。

全局变量存在的形式有两种。

如果是单个.c文件中定义的全局变量,一般将其定义在程序的第一个函数之前。因为全局变量也遵循“先定义后使用”的基本变量定义原则,因而如要被越多的函数使用到,那就要定义在越多的函数前面,因而定义在.c文件第一个函数之前。如图4-4-6所示。我们可以看到,在main函数之前定义了全局变量,每次在GlobalVarPrint函数中自加并且打印,这个变量会一直保留着进行自加,并不会被重新初始化和回收释放。由于全局变量有这么好的特性,因此我们需要用到一些系统状态被工程中的其他函数读写,就可以使用全局变量来传递了。

图4-4-6 全局变量验证

如果一个C语言工程项目中有多个文件,在其中的一个文件中定义一个全局变量是其可以被其他.c文件中的函数读写,那么这个变量和函数一样,不仅需要定义,还要在.h文件中被声明,声明全局变量用“extern”表示。如图4-4-7所示。我们一共定义了四个文件,一个是main.c,里面存放主函数,一个是increase.c里面实现了一个全局变量的自加,一个是increase.h,这是increase.c的头文件,主要存放了函数和全局变量声明,最后一个是它们的依赖文件Makefile。

图4-4-7 多文件全局变量定义和声明

(2)静态变量和常变量

静态变量是一种用“static”关键词声明的变量,它表示这个变量本身是一种静态的变量,我们前面说了,静态属性的变量,其好处就是变量不会被编译器回收释放,而用“static”关键词声明的变量不仅能做全局变量,也能做局部变量,做局部变量时,它在函数执行完成之后也不会被编译器回收。

静态变量的定义方式为:static 变量类型变量名;

可能现在大家就有疑问了,静态变量的这种功能岂不是和全局变量一样了?为什么还要再单独弄个静态变量?这真是多此一举。可是这真的是多次一举吗?

这里大家要注意,在C语言中,所有用“static”关键词修饰静态类型都有一个共同的特征,即不能放在.h文件中声明。这一个看似没啥用的特征却对C语言这种简单语言起了很大的作用,即使用static修饰的变量和函数,可以作为每个独立.c源文件的私有变量和函数。私有变量和函数就意味着,当我们将一个功能模块里面的函数和变量定义好之后,又不想被调用者随便更改而造成某些问题,那我们就可以使用私有函数和变量,仅供内部调用。而从C++以后的语言都增加了“private,public,protect”关键词来表示变量的权限。如图4-4-8所示,我们将图4-4-7代码中的GlobalIncNum全局变量静态化声明,并且在.h文件中声明它,结果编译器就抛出异常。

图4-4-8 静态变量声明报错

而图4-4-9中,我们“大胆”地定义了两个变量名完全相同的变量,并且都用static关键词做静态化修饰。main.c函数中的GlobalIncNum变量做自减,而increase.c中的GlobalIncNum变量做自加,结果发现编译正常通过,而且在main函数中输出的是其自己文件中定义的GlobalIncNum变量,因为这个变量是自减的。当然,你也可以在GlobalVarIncrease()函数中也将GlobalIncNum变量打印出来,看看有什么现象。

图4-4-9静态修饰变私有化

static修饰的静态变量还有一个功能,即它在函数退出时不会被编译器回收。如图4-4-10所示,在函数中,将局部变量静态化,那么它每次在函数结束调用后也不会被回收了。

图4-4-10 静态变量不会被编译器回收

C语言中const关键字是constant的缩写,它的意思是常量、常数等。C语言中const功能很强大。这里我们先说明它用来修饰变量时候的用法。Const关键词修饰变量的用法为:const数据类型变量名。如“const intnumber = 5;”这就表面,定义了一个常变量,变量名为number,值为5。而在程序任何地方都不能修改number的值,因为无论你怎么修改,这个程序都编译不过。如图4-4-11所示。

图4-4-11 const变量非法修改

其实const修饰的常变量有点类似于只读变量的意思,事实上编译器处理这些变量的时候,都是将其直接编译进程序的代码里,而不作为数据来用,这么说可能做PC端开发的读者不明白。如果你用哈佛结构的计算机,如绝大多数单片机,你会知道,它们的程序和数据是分别存在两个不同的存储器上面的一个类似于PC的硬盘,一个类似于内存。不同的是哈佛架构的计算机,程序直接可以在硬盘里面运行,不需要像冯诺依曼架构计算机一样,拷贝到内存上,而运行过程中的数据(如一般变量)是存放在数据存储器上的。而如果用const关键词修饰的常变量,编译器会将它直接放到程序存储器里面,因为它是只读的。

乐创杯c语言大赛形式,【连载】(学了这么多年C语言,你真的了解static关键词吗)乐创DIY C语言讲义​——4.4节...相关推荐

  1. 任杰中山大学计算机技术,喜讯 | 港中大(深圳)学子在2020年“外研社·国才杯”全国英语大赛(广东复赛)创造佳绩...

    原标题:喜讯 | 港中大(深圳)学子在2020年"外研社·国才杯"全国英语大赛(广东复赛)创造佳绩 11月7日,由广东省教育厅主办.外语教学与研究出版社协办.中山大学新华学院承办的 ...

  2. 国信蓝点杯第二届(2011)C语言大赛样题整合

    http://blog.sina.com.cn/s/blog_44e1ec3801018d3r.html 国信蓝点杯第二届(2011)C语言大赛样题整合(2012-12-26 08:49:16) 比赛 ...

  3. 2012年华为杯校园编程大赛决赛 类别:软件C/C++语言

    2012年华为杯校园编程大赛决赛 类别:软件C/C++语言 编程题(共1题,100分.请上机编写程序,按题目要求提交文件.测试用例不对考生公开,凡不满足提交要求导致不能运行或用例不通过,不予评分.) ...

  4. 合肥工业大学宣城校区计算机大赛,合肥工业大学宣城校区“建行杯”计算机设计大赛 颁奖典礼举行...

    4月11日下午,合肥工业大学宣城校区"建行杯"计算机设计大赛颁奖典礼在教学楼114室举行.宣城校区领导陈朝阳.田作淳.蒋传东.胡学钢及各部门负责人.各系部主任,学校教务部副教务长张 ...

  5. 湖北大学计算机学院周双娥,科学网—“第三届‘蓝桥杯’全国软件大赛”湖北分赛区组委会组成名单 - 程学先的博文...

    经大赛组委会批准,"第三届'蓝桥杯'全国软件专业人才设计与创业大赛"湖北分赛区组委会组成名单如下: 湖北分赛区组委会主任:华科大软件学院院长陈传波 湖北分赛区组委会常务副主任:湖北 ...

  6. 计算机应用基础word说课,全国“XX杯”说课大赛计算机应用基础类优秀作品:Word图文混排教案.doc...

    全国"XX杯"说课大赛计算机应用基础类优秀作品:Word图文混排教案.doc 文档编号:1054624 文档页数:5 上传时间: 2020-05-30 文档级别:精品资源 文档类型 ...

  7. 【开赛啦!邀你来战 】2022年“桂林银行杯”数据建模大赛暨全国大学生数学建模竞赛广西赛区热身赛

    2022年"桂林银行杯"数据建模大赛 大赛背景 桂林银行股份有限公司(以下称"桂林银行"),以金融成就美好生活为使命,以承接国家和地方发展战略为己任,服务地方经 ...

  8. 2019「友盟杯」数据分析大赛结果公布

    " 如果将一次参赛看作是一回登峰之旅,你觉得自己能走到哪里? 是不到终点不罢休,还是半路即返航? " 故事要从这里开始说起: 4 月 1 日,由友盟+和人人都是产品经理联合举办的& ...

  9. 计算机基础教学能力比赛教案,全国“XX杯”说课大赛计算机应用基础类优秀作品:Word图文混排教案...

    <全国"XX杯"说课大赛计算机应用基础类优秀作品:Word图文混排教案>由会员分享,可在线阅读,更多相关<全国"XX杯"说课大赛计算机应用基础 ...

最新文章

  1. 全网最详细的大数据集群环境下如何正确安装并配置多个不同版本的Cloudera Hue(图文详解)...
  2. python pyecharts_基于Python的数据可视化库pyecharts介绍
  3. 简述http请求中的同步和异步
  4. python 微信_wxpy: 用 Python 玩微信
  5. Java IO篇:什么是 Reactor 网络模型?
  6. TensorFlow学习笔记(五)Session的2种用法
  7. java第一季2.2
  8. 【ArcGIS遇上Python】python批量获取栅格数据四至(top,bottom,left,right)坐标代码
  9. Android Studio开发基础之启动Service,并通过从Activity向Service传递数据
  10. LoRaWAN的四大优势及适用领域
  11. 微信“拍一拍”新增“炸一炸”功能;爱奇艺 CEO:会费涨价是行业必然趋势;微软终止 Windows 10X 开发|极客头条...
  12. js判断操作系统与浏览器
  13. 彻底了解 suid, sgid ,sticky权限
  14. Cmn递推函数c语言,Cmn排列组合 高三数学知识点总结归纳5篇精选
  15. 中华五千年的朝代顺序
  16. 《肖申克的救赎》观后
  17. C++ 类中的 构造函数、拷贝构造函数、析构函数
  18. 三角函数诱导公式大全
  19. Linux第二次试验:Linux下的进程通信实验
  20. 每次抢票都被某软件坑加速包的钱?这个脚本你值得拥有,一毛不用花。

热门文章

  1. 点云笔记01---点云基本概念
  2. GameFi独角兽区块帝国,今日开启全球IDO
  3. TheProjetXXXXXneedstobedeployedbeforeitanbestarted
  4. 微信小程序template模板与component自定义组件的区别和使用
  5. 传奇如何读取服务器信息,传奇服务器修改之命令服务脚本详细使用方法介绍
  6. android跑马灯效果不起作用,Android跑马灯效果失效问题
  7. 手动升级11.2.0.3到12.2.0.1
  8. 高仿人人车 范围选择器
  9. 爬虫:汽车之家字体反爬
  10. 你真的适合做前端开发吗?