C语言圣经KR笔记 1.10外部变量和作用域

1.10外部变量和作用域

上一节main中的变量,如line、longest等等,对main来说是私有的或者说是局部的。因为它们是在main中定义的,其他函数不能直接访问它们。其他函数中的变量也是如此,例如,getline中的变量 i 与copy中的变量 i 没有关系。函数中的局部变量只在函数被调用时存在,当函数退出后就消失了。这就是为什么这样的变量通常被称作“自动”变量(遵循其他语言的术语)。我们后续也将使用“自动”这个词来指代这些局部变量。(第4章会谈到static存储类型,其中的局部变量可以在调用间保持它们的值。)

因为自动变量伴随着函数的调用或退出而出现或消失,它们不能在调用之间保持它们的值,每次进入时都必须明确地设定值。如果不设定值,就会包含垃圾值。

如果不想用自动变量的话,可以定义对所有函数来说都是“外部”的变量,也就是说,任何函数都可以用名字来访问该变量。(这个机制很像Fortan的COMMON,或者是Pascal最外层块中定义的变量。)因为外部变量是全局可访问的,因此可以用来取代参数列表,以实现函数间的数据通信。进一步来说,因为外部变量永远存在(不会随着函数的调用和退出,出现和消失),它们甚至能在设置它们的函数返回后保持它们的值。

外部变量必须被“定义”在所有函数之外,有且仅有一次;这会为它们分配存储空间。外部变量还必须在所有需要访问它的函数内“声明”;这是用于指明变量类型。声明必须是一个extern语句,或者在某些上下文时隐式声明。为了让上面的讨论更好理解,我们重写前面的计算最长行程序,并把line、longest和max作为外部变量。这要求改变所有三个函数的调用、声明和函数主体。

注意:getline已经是C标准库函数了(POSIX.1-2008.),如果要在新环境下编译运行代码,要给getline改个名字。

#include <stdio.h>#define MAX_LINE 1000    /*最长的行长度*/int max;                /* 目前的最大长度 */
char line[MAX_LINE];    /* 当前输入行 */
char longest[MAX_LINE]; /* 最长行存这里 */int getline(void);
void copy(void);/* 输出最长输入行,特别版 */
main()
{int len;extern int max;extern char longest[];max = 0;while ((len = getline()) > 0)if (len > max) {max = len;copy();}if (max > 0)printf("%s", longest);return 0;
}/* getline: 特别版 */
int getline(void)
{int c, i;extern char line[];for (i = 0; i < MAX_LINE-1 && (c = getchar())!=EOF && c != '\n'; ++i)line[i] = c;if (c == '\n') {line[i] = c;++i;}line[i] = '\0';return i;
}/* 拷贝,特别版 */
void copy(void)
{int i;extern char line[], longest[];i = 0;while ((longest[i] = line[i]) != '\0')++i;
}

main、getline、copy中的外部变量在代码的最前几行定义,这指明了它们的类型并给它们分配了存储空间。从语法上来说,外部变量的定义和局部变量的定义是一样的,但由于它们在函数外面出现,故变量就是外部的。在函数使用外部变量之前,必须要让函数知道它的名字。一种方法是在函数内写一个extern声明;声明与前面的写法一致,区别在于前面加了个extern关键字。

在某些环境下,extern声明可以省略。如果在源文件中,外部变量的定义先于它在某个函数中的使用,那就没有必要在这个函数中加入extern声明。这样main、getline和copy中的extern声明其实是冗余的。实际上,通常的实践方式是把所有外部变量的定义放在源文件开头,就能去掉所有的extern声明。

如果程序有几个源文件,且一个变量在文件1中定义,并在文件2和文件3中使用,那么在文件2和文件3中就需要extern声明,以便关联这个变量的出现。通常的实践是把所有的外部变量和函数的声明放在一个单独的文件中(历史上被称为header头文件),在每个源文件的开头用#include来包含它。按惯例使用.h作为头文件名的后缀。例如,标准库里的函数在如<stdio.h>之类的头文件里面声明。这个主题的详细讨论会在第四章,而标准库会在第七章和附录B。

由于特别版的getline和copy没有参数,故从逻辑上看它们的原型应当是getline() 和 copy()。但为了和旧的C程序兼容,C标准将空参数列表当作是旧风格的声明,并会为其关闭参数列表校验;空参数列表必须明确地用void来表示。第四章会进一步讨论。

注意要区分“定义”和“声明”。“定义”是变量被创建并分配存储的地方。“声明”是指明变量的性质的地方,并不分配存储。

顺带一提,有人倾向是把所有能看到的东西都变成extern变量,因为这看起来能简化通信——参数列表很短,而且只要你想,你总是能访问这些变量。但问题在于,即使你不想要的时候,外部变量也总是存在着。过于依赖外部变量是非常危险的,因为它导致程序的数据关联完全不明显——变量可能因意外甚至疏忽被改变,程序也很难修改。第二版的最长行程序比第一版差,部分是由于这个原因,而部分是因为破坏了两个有用函数的通用性(把它们和它们操作的变量绑定起来了)。

本章到这里我们已经覆盖了C语言的常规核心部分。用这些基础部分,可能写成长度相当可观的、有用的程序,建议你在往下学之前试试。后面的练习题包含了比本章前面样例更复杂的程序。

(第一章完)

 

 

 

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

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

相关文章

睿趣科技:抖音开网店卖玩具怎么样

近年来&#xff0c;随着社交媒体平台的飞速发展&#xff0c;抖音作为一款短视频分享应用也迅速崭露头角。而在这个充满创业机遇的时代背景下&#xff0c;许多人开始探索在抖音平台上开设网店&#xff0c;尤其是卖玩具类商品&#xff0c;那么抖音开网店卖玩具究竟怎么样呢? 首先…

傅里叶变换(FFT)笔记存档

参考博客&#xff1a;https://www.luogu.com.cn/blog/command-block/fft-xue-xi-bi-ji 目录&#xff1a; FFT引入复数相关知识单位根及其相关性质DFT过程&#xff08;难点&#xff09;DFT结论&#xff08;重要&#xff09;IDFT结论&#xff08;重要&#xff09;IDFT结论证明&…

巨人互动|游戏出海游戏出海需要考虑哪些方面?

游戏出海是指将游戏产品推向国外市场&#xff0c;以扩大用户群体和增加盈利空间&#xff0c;那么要成功地进行游戏出海&#xff0c;需要考虑哪些方面呢&#xff1f;本文小编对此来讲讲吧&#xff01; 1、目标市场选择 选择适合游戏产品的目标市场是出海的首要考虑因素&#xf…

word中标题及公式自动编号

word中公式自动编号 1. 实现目标2. 详细步骤2.1 添加自动编号功能2.2 输入标题并编号2.3 新建公式2.3.1 编辑公式2.3.4 公式编号的交叉引用2.3.5 公式位置变动以及更新正文中的编号 在word中自动编号公式一直是一个老大难问题&#xff0c;现在通过总结网友们提供的方法&#xf…

2023年京东方便食品行业数据分析(京东数据报告)

​疫情中方便食品的销售一度火爆&#xff0c;但随着当前消费场景的开放&#xff0c;方便食品销售又恢复常态并开始下滑。根据鲸参谋电商数据分析平台的相关数据显示&#xff0c;今年7月份&#xff0c;京东平台方便食品的销量为800万&#xff0c;环比降低约23%&#xff0c;同比降…

C++贪吃蛇(控制台版)

C自学精简实践教程 目录(必读) 目录 主要考察 需求 输入文件 运行效果 实现思路 枚举类型 enum class 启动代码 输入文件data.txt 的内容 参考答案 学生实现的效果 主要考察 模块划分 文本文件读取 UI与业务分离 控制台交互 数据抽象 需求 用户输入字母表示方…

外观模式:简化复杂子系统的访问与使用

文章目录 1. 简介2. 外观模式的基本结构3. 外观模式的实现步骤4. 外观模式的应用与实例4.1 图形界面库的外观模式应用4.2 文件压缩与解压缩的外观模式应用4.3 订单处理系统的外观模式应用 5. 外观模式的优缺点5.1 优点5.2 缺点 6. 总结 1. 简介 外观模式是一种结构型设计模式&…

基于java+springboot+vue的点餐平台网站-lw-源码

​ 系统介绍&#xff1a; 随着现在网络的快速发展&#xff0c;网上管理系统也逐渐快速发展起来&#xff0c;网上管理模式很快融入到了许多商家的之中&#xff0c;随之就产生了“点餐平台网站”&#xff0c;这样就让点餐平台网站更加方便简单。 对于本点餐平台网站的设计来说…

实操教程 | 触发器实现 Apache DolphinScheduler 失败钉钉自动告警

作者 | sqlboy-yuzhenc 背景介绍 在实际应用中&#xff0c;我们经常需要将特定的任务通知给特定的人&#xff0c;虽然 Apache DolphinScheduler 在安全中心提供了告警组和告警实例&#xff0c;但是配置起来相对复杂&#xff0c;并且还需要在定时调度时指定告警组。通过这篇文…

BIO到NIO、多路复用器, 从理论到实践, 结合实际案例对比各自效率与特点(上)

文章目录 文章引入IO模型及概念梳理BIO简单介绍代码样例压测结果 NIO(单线程模型)简单介绍与BIO的比较代码样例压测结果 多路复用器问题引入 文章引入 如果你对BIO、NIO、多路复用器有些许疑惑, 那么这篇文章就是肯定需要看的, 本文将主要从概念, 代码实现、发展历程的角度去突…

JavaScript设计模式(二)——简单工厂模式、抽象工厂模式、建造者模式

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…

使用element-ui中的el-table回显已选中数据时toggleRowSelection报错

最近在写一个后台&#xff0c;需要在表格中多选&#xff0c;然后点击编辑按钮的时候&#xff0c;需要回显已经选中的表单项 <el-table v-loading"loading" :data"discountList" :row-key"(row) > row.id" refmultipleTable selection-cha…

[ES]二基础 |

一、索引库操作 1、mapping属性 mapping是对索引库中文档的约束&#xff0c;常见的mapping属性包括&#xff1a; 1)type&#xff1a;字段数据类型&#xff0c;常见的简单类型有&#xff1a; ①字符串&#xff1a;text(可分词的文本)、keyword&#xff08;精确值&#xff0c…

基于JavaWeb和mysql实现校园订餐前后台管理系统(源码+数据库)

一、项目简介 本项目是一套基于JavaWeb和mysql实现网上书城前后端管理系统&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。 包含&#xff1a;项目源码、项目文档、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都…

【Terraform学习】Terraform模块基础操作(Terraform模块)

本站以分享各种运维经验和运维所需要的技能为主 《python》&#xff1a;python零基础入门学习 《shell》&#xff1a;shell学习 《terraform》持续更新中&#xff1a;terraform_Aws学习零基础入门到最佳实战 《k8》暂未更新 《docker学习》暂未更新 《ceph学习》ceph日常问题解…

SpringBoot中自定义starter

SpringBoot自动装配原理&#xff1a; EnableAutoConfiguration注解开启自动装配功能&#xff0c;该注解通常放在应用的主类上。spring.factories文件位于META-INF目录下的配置文件中定义各个自动装配类的全限定名 当SpringBoot启动时&#xff0c;会加载classpath下所有的spri…

说说Flink运行模式

分析&回答 1.开发者模式 在idea中运行Flink程序的方式就是开发模式。 2.local-cluster模式 Flink中的Local-cluster(本地集群)模式,单节点运行&#xff0c;主要用于测试, 学习。 3.Standalone模式 独立集群模式&#xff0c;由Flink自身提供计算资源。 4.Yarn模式 把Fl…

android frida 逆向 自吐加密算法

前言&#xff1a; ♛ frida hook android Android 逆向神器 前几天在学习 Android 逆向的时候发现了一个神器&#xff1a;通过 frida hook 我们可以 “劫持” 一些函数 为我们所用&#xff0c; 今天就和大家上手一个 加密函数的劫持 让打印出&#xff1a; 加密秘钥 …

Window11-Ubuntu双系统安装

一、制作Ubuntu系统盘 1.下载Ubuntu镜像源 阿里云开源镜像站&#xff1a;https://mirrors.aliyun.com/ubuntu-releases/ 清华大学开源软件镜像网站&#xff1a;https://mirrors.tuna.tsinghua.edu.cn/ubuntu-releases/ 选择想要的版本下载&#xff0c;我用的是20.04版本。 2…

【广州华锐互动】AR昆虫认知学习系统实现对昆虫形态的捕捉和还原

随着科技的不断发展&#xff0c;人们对自然界的认识也在不断加深。在这个过程中&#xff0c;AR&#xff08;增强现实&#xff09;技术的出现为人们带来了全新的体验方式。为此&#xff0c;广州华锐互动开发了AR昆虫认知学习系统&#xff0c;本文将为大家详细介绍这款系统的特点…