当前位置: 首页 > 新闻 > 信息荟萃
编号:5267
啊哈C语言逻辑的挑战修订版附答案.pdf
http://www.100md.com 2020年11月6日
第1页
第8页
第11页
第22页
第50页
第233页

    参见附件(6134KB,378页)。

     《啊哈C语言!逻辑的挑战(修订版)》从开始学习与计算机对话到自己独立制作一个游戏,由浅入深地讲述编程的思维。同时,与计算机展开的逻辑较量一定会让你觉得很有意思

    内容简介

    这是一本非常有趣的编程启蒙书,全书从中小学生的角度来讲述,没有生涩的内容,取而代之的是生动活泼的漫画和风趣幽默的文字。并配合超萌的编程软件,从开始学习与计算机对话到自己独立制作一个游戏,由浅入深地讲述编程的思维。同时,与计算机展开的逻辑较量一定会让你觉得很有意思。你可以在茶余饭后阅读本书,甚至蹲在马桶上时也可以看得津津有味。编程将会改变我们的思维,教会我们如何思考,让我们的思维插上计算机的翅膀,以一种全新的方式来看世界。现在就让我们一起走进计算机编程的神奇世界,探索和发现计算机编程的魔力吧!

    作者简介

    啊哈磊,原名纪磊,毕业于武汉大学。曾在中科院玩单片机,在微软亚洲研究院开发“爬虫”,在IEEE国际会议上发表论文,也做过老师,是全国青少年信息学奥林匹克金牌教练。著有《啊哈C!语言》和《啊哈!算法》系列编程科普丛书,并被引进至港澳台地区。非常喜欢小朋友,每天都过得很开心。为什么叫“啊哈磊”呢?因为这是一个很喜庆的名字。

    精彩书评

    百度移动云首席布道师张辉:学习编程能为自己打开一扇全新的窗户。本书可能是*通俗易懂、生动好玩的C语言教程,它不只是让你成为编程大师,更是帮你理解身边的种种奇妙。

    chd9527:想学C,发现其他入门书的门槛挺高,看不懂。偶尔发现这本小学生都能读懂的C语言书籍,学习了一下,觉得写得很好,和“入门”一词真的很贴切。

    阳光雨:不但教大家怎样去做,关键是告诉大家原理!语言幽默生动,有很亲切的感觉。比奥数有趣有意思,可以提升孩子的逻辑思考力。

    家长100鱼小肥:通俗易懂,可以作为孩子的编程启蒙读物,是很好的科普书,能把复杂的知识用简单的方式表达出来,孩子看了很感兴趣。如果编程书都能写得如此风趣,自学将变得很轻松。

    tingting:这本书从小朋友的角度和立场读起来一点都不费劲。跟同类的书籍比起来,更加通俗易懂,生动有趣。

    mijianxing:我一直想通过学编程更好地了解这个世界,对照这本书,自己编一些小程序,亲自设计的感觉很奇妙。

    jocal:推荐的啊哈C编程工具也挺好用的,简洁明了!小朋友看着书,自己跟着一步步操作,很有成就感!

    目 录

    第1章 编程改变思维 1

    第1节 为什么要学习编程 1

    第2节 本书是讲什么的,写给谁看的 4

    第2章 梦想启航 7

    第1节 编程的魔力 7

    第2节 让计算机开口说话 9

    第3节 多彩一点 18

    第4节 让计算机做加法 21

    第5节 数字的家――变量 26

    第6节 数据输出――我说咋地就咋地 31

    第7节 数据输入――我说算啥就算啥 33

    第8节 究竟有多少种小房子 37

    第9节 拨开云雾见月明 40

    第10节 逻辑挑战1:交换小房子中的数 42

    第11节 天啊!这怎么能看懂 45

    第3章 较量才刚刚开始 49

    第1节 大于、小于还是相等 49

    第2节 判断正数 50

    第3节 偶数判断 54

    第4节 神器else 56

    第5节 请告诉我谁大 59

    第6节 逻辑挑战2:3个数怎么办 61

    第7节 逻辑挑战3:我要排序 66

    第8节 运算符总结 71

    第9节 1>2究竟对不对 71

    第10节 讨厌的嵌套 74

    第11节 if-else语法总结 78

    第4章 重量级选手登场 79

    第1节 永不停止的哭声 79

    第2节 我说几遍就几遍 83

    第3节 if对while说:我对你很重要 88

    第4节 求和!求和!!求和!!! 90

    第5节 逻辑挑战4:60秒倒计时开始 95

    第6节 这个有点晕――循环嵌套来了 99

    第7节 逻辑挑战5:奔跑的字母 104

    第8节 究竟循环了多少次 108

    第9节 逻辑挑战6:奔跑的小人 110

    第10节 for隆重登场 114

    第5章 好戏在后面 118

    第1节 程序的3种结构 118

    第2节 嗦一下 119

    第3节 逻辑挑战7:判读质数很简单 120

    第4节 更快一点:break 125

    第5节 continue 126

    第6节 逻辑挑战8:验证哥德巴赫猜想 127

    第7节 逻辑挑战9:水仙花数 130

    第8节 逻辑挑战10:解决奥数难题 135

    第9节 逻辑挑战11:猜数游戏 138

    第10节 逻辑挑战12:你好坏,关机啦 142

    第6章 天啊!一大串数正在接近 144

    第1节 逆序输出 144

    第2节 申请100个小房子怎么办 145

    第3节 100个数的逆序 147

    第4节 逻辑挑战13:陶陶摘苹果 148

    第5节 逻辑挑战14:一个萝卜一个坑 151

    第6节 逻辑挑战15:选择排序 156

    第7节 二维数组 159

    第8节 剩下的一些东西 161

    第7章 有了它你能做更多的事 165

    第1节 字符的妙用 165

    第2节 多余的回车键 167

    第3节 字符的本质 169

    第4节 人名怎么存储呢 171

    第5节 逻辑挑战16:字母的排序 176

    第6节 逻辑挑战17:字典序 177

    第7节 多行字符 179

    第8节 存储一个迷宫 182

    第8章 游戏时间到了 184

    第1节 走迷宫 184

    第2节 推箱子 194

    附录A 标识符命名规则 197

    附录B 运算符的优先级和结合性 199

    啊哈C语言逻辑的挑战修订版截图

    啊哈C语言!

    逻辑的挑战

    修订版

    啊哈磊著

    電子工業出版社 ·

    Publishing House of Electronics Industry

    北京·BEIJING内容简介

    这是一本非常有趣的编程启蒙书,全书从中小学生的角度来讲述,没有生涩的内容,取而代之的是生动活泼的漫画和风趣幽默的文字。配

    合超萌的编程软件,本书从开始学习与计算机对话到自己独立制作一个

    游戏,由浅入深地讲述编程的思维。同时,与计算机展开的逻辑较量一

    定会让你觉得很有意思。你可以在茶余饭后阅读本书,甚至坐在马桶上

    也可以看得津津有味。编程将会改变我们的思维,教会我们如何思考,让我们的思维插上计算机的翅膀,以一种全新的方式来感知世界。未经许可,不得以任何方式复制或抄袭本书之部分或全部内容。

    版权所有,侵权必究。

    图书在版编目(CIP)数据

    啊哈C语言!:逻辑的挑战啊哈磊著.—修订本. —北京:电子工业

    出版社:2017.1

    ISBN 978-7-121-30462-0

    Ⅰ.①啊… Ⅱ.①啊… Ⅲ.①C语言-程序设计-青少年读物

    Ⅳ.①TP312.8-49

    中国版本图书馆CIP数据核字(2016)第284866号

    责任编辑:徐津平

    印 刷:中国电影出版社印刷厂

    装 订:中国电影出版社印刷厂出版发行:电子工业出版社

    北京市海淀区万寿路173信箱 邮编100036

    开 本:787×980 116

    印 张:13

    字 数:255千字

    版 次:2013年9月第1版

    2017年1月第2版

    印 次:2017年1月第1次印刷

    印 数:4000册

    定 价:49.00元

    凡所购买电子工业出版社图书有缺损问题,请向购买书店调换。若书店

    售缺,请与本社发行部联系,联系及邮购电话:(010)88254888,88258888。

    质量投诉请发邮件至zlts@phei.com.cn,盗版侵权举报请发邮件至

    dbqq@phei.com.cn。

    本书咨询联系方式:(010)51260888-819, faq@phei.com.cn。修订版序

    自《啊哈C》出版以来,我与编程爱好者们便有了更多的交流机

    会。这些编程爱好者之中不乏大学生、中学生、老师、家长,更有小学

    二、三年级的学生。令我惊喜的是,二、三年级的小读者们与我探讨的

    并不是浅显的语法或BUG调试问题,更多的是他们通过独立思考发的书

    中的错误,他们向我阐述自己的思想,与我交流游戏开发中遇到的逻

    辑、算法等。还有一些读者留言说:“这本书不仅仅是小学生坐在马桶

    上都能看懂的书,是连我妈妈或是我姥姥都能看懂的编程书!”这些读

    者实在是太捧场了,有幸让我体验了一次漫卷诗书喜欲狂的感觉。也有

    好多读者看完后直呼不过瘾,常常询问何时能有第二部。一晃已是三

    年,借此《啊哈C语言!逻辑的挑战》修订之际,第二部《啊哈C语

    言!游戏实验室》也如期而至,它景致依旧,故事常新,希望你能喜

    欢!让我们再次共同探索编程与梦想的一切可能。

    啊哈磊

    2016年12月第一版序

    我经常被问到一个问题:当初为什么会去学编程?我的回答是,因

    为我很喜欢玩游戏。每一个喜欢玩游戏的人,都梦想着可以通过修改游

    戏的程序使游戏中的自己变得非常强大,而这需要学习编程。其实每一

    个喜欢玩游戏的人都曾有过创造游戏的梦想,那我们为什么不把这种梦

    想变成学习的动力呢?我就是这样踏上编程之路的。

    牛人肯·汤普逊(Kenneth Lane Thompson)自己编写了一个叫作“星

    际旅行(Star Travel)”的游戏。而汤普逊为了能更顺畅地玩这个游戏,竟然自己动手用汇编写了UNIX操作系统。后来他觉得用汇编写UNIX操

    作系统非常麻烦和辛苦,于是和另一个牛人丹尼斯·里奇一起创造了C语

    言。没想到吧,C语言竟然是一个牛人为了玩自己写的游戏而创造的。

    其实这在计算机界很正常,程序员们往往就是因为某个游戏或者软件的

    现有功能不能满足自己的需求,才开发出了更加优秀的游戏和软件。本

    书中超萌、超简洁的“啊哈C语言”编程软件也是这样来的。

    我经常被问到的第二个问题:为什么普通人需要关心编程呢?我的

    答案是,因为当下程序员几乎主宰了整个世界,控制着生活的方方面

    面。我们住的房子、穿的衣服、吃的东西、用的各种电子产品,以及我

    们去ATM取钱、坐电梯、开汽车、坐飞机、坐火车等,都离不开编

    程。你坐火车时有没有想过,一条铁轨上同时运行的那么多列火车是如

    何调度才没有导致它们相撞的。这个时代很难想象还有什么不是通过计

    算机程序控制的。如果想理解这个时代,就必须理解计算机编程。编程

    会让我们以一种全新的方式来看世界。当然,在学习编程的过程中还可以提高我们的逻辑推理能力、批判性思维和动手解决问题的能力。与计

    算机展开的逻辑较量一定会让你觉得很有意思。

    我还经常被问到第三个问题:什么样的人可以自学编程,学习编程

    需要什么基础?答案是,你只需具有小学四年级以上文化程度,并且熟

    练运用鼠标和键盘就可以。你若不信,那就从这本书开始吧。

    编程很容易让我们实现梦想。如果我们觉得某个游戏玩得不爽想提

    升体验,或者觉得某个软件不够好用想自己做一个,没问题,现在就可

    以!而唯一的投入就是一台计算机。实现梦想从未变得如此简单。编程

    世界里每天都上演着传奇,一大批热爱编程并且满怀梦想的人正在充满

    激情地奋斗着。

    编程将会改变我们的思维,教给我们如何思考,会编程的人总想改

    变点什么。正如乔布斯所说“I think everybody in this country should learn

    how to program a computer, should learn a computer language, because it

    teaches you how to think.”

    啊哈磊

    2013年9月注:文中出现的“□”同原版纸书目 录

    修订版序

    第一版序

    第1章 编程改变思维

    第1节 为什么要学习编程

    第2节 本书是讲什么的,写给谁看的

    第2章 梦想启航

    第1节 编程的魔力

    第2节 让计算机开口说话

    第3节 多彩一点

    第4节 让计算机做加法

    第5节 数字的家——变量

    第6节 数据输出——我说咋地就咋地

    第7节 数据输入——我说算啥就算啥

    第8节 究竟有多少种小房子

    第9节 拨开云雾见月明

    第10节 逻辑挑战1:交换小房子中的数

    第11节 天啊!这怎么能看懂

    第3章 较量才刚刚开始

    第1节 大于、小于还是相等

    第2节 判断正数

    第3节 偶数判断

    第4节 神器else

    第5节 请告诉我谁大

    第6节 逻辑挑战2:3个数怎么办第7节 逻辑挑战3:我要排序

    第8节 运算符总结

    第9节 1>2究竟对不对

    第10节 讨厌的嵌套

    第11节 if-else语法总结

    第4章 重量级选手登场

    第1节 永不停止的哭声

    第2节 我说几遍就几遍

    第3节 if对while说:我对你很重要

    第4节 求和!求和!!求和!!!

    第5节 逻辑挑战4:60秒倒计时开始

    第6节 这个有点晕——循环嵌套来了

    第7节 逻辑挑战5:奔跑的字母

    第8节 究竟循环了多少次

    第9节 逻辑挑战6:奔跑的小人

    第10节 for隆重登场

    第5章 好戏在后面

    第1节 程序的3种结构

    第2节 啰嗦一下

    第3节 逻辑挑战7:判读质数很简单

    第4节 更快一点:break

    第5节 continue

    第6节 逻辑挑战8:验证哥德巴赫猜想

    第7节 逻辑挑战9:水仙花数

    第8节 逻辑挑战10:解决奥数难题

    第9节 逻辑挑战11:猜数游戏

    第10节 逻辑挑战12:你好坏,关机啦第6章 天啊!一大串数正在接近

    第1节 逆序输出

    第2节 申请100个小房子怎么办

    第3节 100个数的逆序

    第4节 逻辑挑战13:陶陶摘苹果

    第5节 逻辑挑战14:一个萝卜一个坑

    第6节 逻辑挑战15:选择排序

    第7节 二维数组

    第8节 剩下的一些东西

    第7章 有了它你能做更多的事

    第1节 字符的妙用

    第2节 多余的回车键

    第3节 字符的本质

    第4节 人名怎么存储呢

    第5节 逻辑挑战16:字母的排序

    第6节 逻辑挑战17:字典序

    第7节 多行字符

    第8节 存储一个迷宫

    第8章 游戏时间到了

    第1节 走迷宫

    第2节 推箱子

    附录A 标识符命名规则

    附录B 运算符的优先级和结合性第1章

    编程改变思维

    第1节 为什么要学习编程

    你是否还在将计算机(电脑)当作上网、聊天和玩游戏的工具?没

    错,大部分人是这样的。当你拿起本书阅读到这里的时候,太好了,你

    又多了一个更好的选择,一个独特的机会!

    在我们生活的这个时代,你会发现有这样一群人,他们对世界的影

    响越来越大,电视、报纸和网络到处都充斥着他们的身影。比尔·盖茨

    创立了微软,让计算机更容易被我们平常人所使用

    [1];乔布斯创立了

    苹果,iPhone、iPad和iPod每一样产品都在改变着我们的日常生活;谢

    尔盖·布林和拉里·佩奇两个年轻的小伙创立了Google,使得获取知识变得前所未有的容易;马克·扎克伯格创立了Facebook,正在改变人与人

    之间的关系……甚至12岁的小软件工程师托马斯·苏亚雷斯

    [2]

    都在改变

    我们的世界。他们是怎样的一群人?他们为什么会创造奇迹?巧的是他

    们都有一个共同的特点:在少年时都酷爱计算机编程。计算机编程究竟

    具有怎样的非凡魔力?计算机编程是否给他们带来与常人不同的思维或

    思考方式?是否是计算机编程为他们开启了不一样的人生道路?

    为什么他们从小就开始接触计算机,不但没有沉迷于游戏,反而改

    变了世界呢?12岁的托马斯说:“现在的孩子们不再只是爱玩游戏,他

    们还想自己制作好玩的游戏,不过孩子们大多不知道去哪里学习计算机

    编程,而懂得计算机编程的家长又很少。”

    其实每个人在童年时期都曾经有创造游戏的梦想,我们为什么不把

    这种梦想变成学习的动力呢?大部分孩子在面对计算机的时候都缺乏引

    导,因为他们不知道计算机除了上网、聊天和玩游戏外还能做什么。即

    使有人想深入地学习计算机,也不知道去哪里学,没有方向,更没有一

    本简单易懂并且有趣的入门书。计算机从被发明的那一天起,其使命就是帮助我们提高学习和工作

    的效率并且改变世界。利用计算机编程,你可以轻松解决数学难题。例

    如,□3×6528=3□×8256,在两个□内填入相同的数字使得等式成立。你

    觉得这样的题目太简单了?那么来个稍微复杂点的:□□□+□□□=□□□,请将1~9这9个阿拉伯数字分别填入9个□中使等式成立,每个数字只能

    使用一次。计算机可以轻轻松松地解决。如果再复杂一点,我想知道上

    面这个式子的所有解,通过笔算就很困难了,但如果使用计算机编程去

    解决,就易如反掌,这正是计算机所擅长的。有时你甚至可以利用计算

    机编程去验证世界性的数学难题,例如,在10 000以内去验证哥德巴赫

    猜想,也都不成问题。当解决大质数、图论等问题时,计算机编程也是

    最好的帮手。

    那么学计算机究竟是学什么呢?答案是逻辑思维和编程思维。

    早在20世纪50年代,美国教育界就开始重视计算机编程教学。20世

    纪80年代后,计算机编程教学逐渐进入中小学校,以教程序设计语言为

    主,目的是提高学生的逻辑推理、批判性思维和动手解决问题的能力。

    实践证明,学习了计算机编程的中小学生,思考问题的方式变得非常逻

    辑化,学会了严密的逻辑推理方法,并无形中把它应用到其他学科的学

    习中。学习计算机编程本质上是在学习一种思维方式——编程思维,它

    是一种思维体操。青少年本身对计算机有着浓厚的兴趣并且有超强的记

    忆力,计算机编程将有助于开发其学习潜力,提高逻辑推理能力和解决

    问题的能力。

    学习计算机编程的过程充满乐趣。如果你有一个想法,马上就可以

    通过编程来实现,并且可以立即看到效果。这种即时的反馈,会让你的

    学习兴趣变得越来越浓厚,也会让你越来越有信心。这种超强的信心,是你在其他学科中难以感受到的。我还记得我的第一个程序运行成功时的那种兴奋,真是太棒了,你一定要去感受一下,这是你一辈子都不会

    忘记的感觉。

    最后,用笔者一个武汉二中的学生吕凯风

    [3]

    学习编程时的感受来

    结束本小节。

    “记得我那时学编程全凭兴趣,兴趣引导我前进。以前做完了作业

    打游戏,如今写完了作业就编程。我觉得学会编程后最让自己激动的

    是,我能用编程来解决几乎所有遇到的数学问题。学数学最强调技巧

    性,比如7的2000次方除以3的余数是多少?21 212 157是不是质数?你

    也许可以用一些小技巧把这两个问题解决掉,但是当我们遇到更难的问

    题时,往往无能为力。比如214 125 315的123 719 857次方除以12 125

    987的余数是多少?2 147 483 647是不是质数?很多实际问题并不像数

    学中那么理想和美好,许多数学结论,尽管被证明得很巧妙,式子简

    洁,但是归根结底,如果它只解决了一个特殊问题,则不具有什么实用

    价值。所以我更喜欢信息学,它告诉我如何去解决一个一般化的问题而

    不是一个特殊的有技巧性的问题。编程最让我感慨的是它无与伦比的唯

    一性与严谨性。”

    说到这里你是不是有点心动了?第2节 本书是讲什么的,写给谁看的

    在写本书之前,我反复问了自己几个问题:这本书是讲什么的?这

    本书是写给谁看的?这本书和一般的编程入门书有什么区别?为什么要

    写这本书?选用哪一门编程语言入门呢?

    第一个问题:这本书是讲什么的?

    这是一本编程入门书。但是本书的重点并不是编程入门,而是向你

    展示逻辑思维和编程思维的魅力,让你像程序员一样思考。

    第二个问题:这本书是写给谁看的?

    编程类图书给大众的印象一直是枯燥并且难懂的。究竟什么样的人

    才能学习编程呢?大学生?高中生?初中生?……不会连小学生都可以

    吧?!没错,只要有小学四年级的水平,我想你一定可以学习编程,并

    且轻松读懂本书的全部内容。

    如果你的情况恰好符合以下一点或几点,那么本书正是为你所写

    的。

    (1)如果你想自己制作好玩的游戏,而不是沉迷于别人的游戏

    中。

    (2)如果你曾对数学感兴趣,我想你一定会喜欢这本书。其实学

    习编程并不需要精通数学,本书不会出现很复杂的数学公式。即使数学

    不太好,甚至很糟糕,也完全可以阅读。(3)如果你对逻辑感兴趣,你一定更会喜欢这本书。与计算机展

    开的逻辑较量一定会让你觉得非常有意思。因为计算机有时会显得不那

    么听话,你让它向东可它却偏偏向西,这时候就一定是你编写的程序出

    现了逻辑问题。而将你的思维清晰有条理地变成计算机程序,就如同一

    场你与计算机之间的逻辑对决。学习计算机编程能够很好地锻炼你的逻

    辑思维能力。

    (4)如果你从小喜欢拆装玩具、改装小电器或是喜欢变废为宝,我想计算机编程会给你带来更多的创造机会。

    (5)如果你正在读《高中数学必修三》的“算法”一章,那么你一

    定要阅读本书,去了解计算机编程和算法的本质。

    (6)正在学习C语言的理工科或者文科的大学生们。

    (7)准备学习编程的爱好者,或者准备以此为工作的人。

    (8)哦,对了,还有就是看了很多编程书籍但是一直没有看懂的

    人,我想你一定可以轻松读懂本书。

    (9)没有那么多原因,就是喜欢计算机。

    第三个问题:为什么要写这本书呢?

    正如前面所说,计算机是一门科学,如果你只是把它当成上网、聊

    天和玩游戏的工具,那就太可惜了,你将可能失去一个发现自己才能的

    机会。即使在计算机编程上有一些天赋,你也有可能失去这一机会。和

    其他人一样,你必须去主动发现自己的天赋和兴趣,就好比你从来没有

    吃过冰淇淋,就不可能知道自己喜欢吃冰淇淋。然而,如果学习了计算

    机编程,你就会发现计算机编程就如同玩游戏一样有趣,充满活力的思考过程就如同一场比赛令人兴奋。在感受到了计算机编程给你带来的乐

    趣后,你就再也不会沉迷于计算机游戏,计算机编程将成为你生活中不

    可缺少的一部分,成为你的一种爱好,成为你的一种学习动力。我想有

    更多人期待去了解计算机编程。

    最后一个问题:选用哪一门编程语言入门呢?

    学习编程的重点在于学习编程的逻辑和思维。本书选用较为简单的

    C语言。你可能要问为什么不选C++、C、Java或者Python之类。因为

    我觉得相比之下C语言最为单纯,没有那么多乱七八糟的东西,非常简

    洁。即使以C语言为载体,我也尽量做到重点去讲解最有用的内容,而

    不是C语言的高深语法或者我至今都没有用过的“奇怪”语句。这样就有

    更多的时间去思考如何解决问题,去关注编程的逻辑和思维。

    当然,说到底C语言仅仅是我们与计算机沟通的一门语言而已,相

    信你在阅读完本书之后,可以很轻松地上手任何一门语言,因为其本质

    都是一样的。根据TIOBE index的程序语言年度排名,2012年最流行的

    编程语言正是有着40年历史的C语言,它战胜了Java语言位居TIOBE

    index榜首,这或许也能说明C语言的重要性吧。以C语言为根本,将帮

    助你更好地去理解编程的思想,而不仅仅是学会编程。

    另外我想告诉你,编程真的是一件非常有趣的事。你就像是一个指

    挥官,让计算机毫无怨言地为你工作。通过编程,你将体会到战胜困难

    和挑战后的快乐与满足。编程的世界充满无限的可能,只有想不到,没

    有做不到。当然在编程的时候也会遇到很多问题,我在书中也为你设置

    了绊脚石,希望你能够顺利地把它找出来。尽信书,不如无书。学习不

    但要细致,还要有思辨的能力,这样才会有创新,才能总结并创造出自

    己的东西。现在开始自己动手编程,不要放弃曾经的梦想,大胆地创造你的作品。

    艾伦·凯曾经这样说道:“在自然科学中,是大自然给出一个世界,而我们去探索其中的法则。对于计算机来说,却是我们自己来构建法

    则,创造一个世界。”

    当下,我们的学习不应该再忙碌于重复的计算、记忆等技能。阅

    读、逻辑推理和主动思考等技能将成为学习的重点。我们应该使用计算

    机来增强自己的智能,同时发挥人类独有的创造天赋,让我们的思维插

    上计算机的翅膀。

    最后,我保证本书一定不是那种枯燥无味的编程入门书,并且在此

    之前你一定没有读过如此生动好玩的编程入门书。你可以在茶余饭后阅

    读本书,或许蹲在马桶上时也可以看得津津有味。现在就让我们一起走

    进计算机编程的神奇世界,探索和发现计算机编程的魔力吧!

    [1] 1985年如果乔布斯没有被迫离开苹果,那这一功劳可能将归于苹果的麦金塔计算机。

    [2] 被誉为“小乔布斯”的12岁少年托马斯是美国加利福尼亚州洛杉矶市南湾地区

    一所学校的6年级学生。当大多数孩子还处在玩计算机或手机游戏的时候,托

    马斯就已经是个能开发游戏程序的“软件工程师”了。托马斯不但为苹果公司

    的手机操作系统编写了两个游戏程序,还创办了一家软件开发公司。

    [3] 吕凯风(VFK)在14岁时以初中生身份获得NOIP(提高组)一等奖,初三

    时以全省第一名的成绩入选湖北NOIP省队,高一时获得亚洲太平洋地区信息

    学奥林匹克竞赛(APIO2013)国际金牌,高二时获得NOIP全国第二名,现被

    保送到清华大学“姚班”。此外,他还独立创作了“对对棋”和“啊哈图”软

    件。“对对棋”的启发来源于他的班级同学在课间玩的一个游戏,“啊哈图”则

    是他在学习计算几何和图论知识时,为了方便解题和调试做的一个类似于“几

    何画板”的软件。第2章

    梦想启航

    第1节 编程的魔力

    从一个神奇的数字说起——2 147 483 647。

    2 147 483 647是一个质数(也称为素数,即只能被1和其本身整除

    的数)。发现这个质数的人是伟大的数学家欧拉。1722年,他在双目失

    明的情况下,以惊人的毅力靠心算证明了2 147 483 647是一个质数,堪

    称当时已知的世界上最大的质数,他也因此获得了“数学英雄”的美名。

    现在你通过计算机只需要1秒就可以证明2 147 483 647是一个质数。

    再来看一个经典的问题——八皇后问题。

    如何能够在8×8的国际象棋棋盘上放置8个“皇后”,使得任何一

    个“皇后”都无法直接吃掉其他“皇后”?为了达到这个目的,任意两个“皇后”都不能处于同一条横行、纵行或斜线上。下面就是一种解决方

    案。没错,你可以自己拿出笔和纸画一画,看看还有没有其他方案。但

    是,如果我想知道所有的方案该怎么办?

    又轮到计算机出马了,一共有92种不同的解决方案,很棒吧!计算

    机只需要1秒,就可以算出所有的解。

    再来看一个很流行的益智游戏——数独。

    在一个9×9格的大九宫格中有9个3×3的小九宫格,默认在其中填写

    了一些数字,现在请在其他空格上填入数字1~9。每个数字在每个小九

    宫格内只能出现一次,每个数字在每行每列也只能出现一次。请看下面

    这个例子。

    我想,你一定很快就找到了一种可行解,可是你知道上面这个数独

    一共有多少种不同解吗?答案是99 410种!很难想象吧,计算机找到这些解仍然只需1秒!怎么样,计算机编程是不是很神奇,你甚至可以轻

    而易举地在一定范围内去验证“哥德巴赫猜想”。

    在接下来的内容里,你将学会如何与计算机对话,如何让计算机进

    行数学计算和判断,如何让计算机永不停止地工作,以及如何让计算机

    做一些很有意思的程序和游戏。一场有趣的逻辑思维大战即将开始,不

    要走开,赶快进入第2节——让计算机开口说话!第2节 让计算机开口说话

    为什么会有计算机的出现呢?伟大的人类发明的每一样东西都是为

    了帮助我们改善生活。计算机同样是用来帮助我们的工具。想一想,假

    如你现在希望让计算机帮助你做一件事情,你首先需要做什么?是不是

    要先与计算机进行沟通?那么沟通就需要依赖于一门语言。人与人的沟

    通,可以用肢体语言、汉语、英语、法语和德语等。你若要与计算机沟

    通,就需要使用计算机能够听懂的语言。我们学习的“C语言”便是计算

    机语言的一种,计算机语言除了C语言外,还有C++、Java、C等。C语

    言是一门比较简单的计算机语言,更加适合初学者。所有的计算机语言

    都是相通的,如果你能够熟练掌握C语言,那么再学习其他语言就会变

    得易如反掌。

    既然计算机是人类制造出来的帮助人类的工具,显然让它开口说话

    并把它所知道的东西告诉我们是非常重要的。

    下面我们就来解决第一个问题:如何让计算机开口说话?

    回想当年,我们刚刚来到这个世界的时候,说的第一句话是什么?

    应该不会是“你好!”、“吃了没?”……这样会把你爸爸妈妈吓坏的!

    伴随着“wa wa wa”的一阵哭声,我们来到了这个精彩的世界,现在

    我们也让计算机来“哭一次”。这个地方特别说一下,计算机若要

    把“它”想说的告诉我们,有两种方法:一种是显示在显示器屏幕上;另

    一种是通过喇叭发出声音。就如同我们有话想说时,一种是写在纸上,另一种是用嘴巴说出来。目前让计算机用音箱输出声音还比较麻烦,因

    此采用另外一种方法,即用屏幕输出“wa wa wa”。 printf(wa wa wa);

    这里有一个生疏单词叫作printf,不要被它吓坏了,目前不用搞清

    楚它的本质意义是什么,只要记住它和中文里面的“说”,以及英文里面

    的“say”是一个意思即可,它就是控制计算机说话的一个单词而已。在

    printf后面紧跟的( ),是不是很像一个嘴巴,把要说的内容“放在”这

    个“嘴巴”里。这里还有一处需要注意,在wa wa wa的两边还有,里

    面就是计算机需要“说”的内容,这一点是不是很像我们的汉语?最后,一句话结束时要有一个结束的符号。汉语中用句号表示一句话的结束;

    英语中用点号表示一句话的结束;计算机语言中用分号表示一个语句的

    结束。

    注:计算机的每一句话,就是一个语句。

    那么,现在如果让你写一个语句,让计算机说“ni hao”,该怎么

    办?

    printf(ni hao);现在我们让计算机来运行这个语句。这里需要说明一下,仅仅输入

    printf(ni hao);,计算机是识别不了的,需要加一个框架。完整的程

    序如下:

    include

    include

    int main

    {

    printf(ni hao);

    return 0;

    }

    这里的

    include

    include

    int main

    {

    return 0;

    }

    是所有C语言都必须要有的框架,现在你暂时不需要理解它,知道要有这个即可,以后再来详细地讲它的用途。但是有一点,我们今后写的所

    有类似printf的语句都要写在{ }里才有效。

    接下来需要让计算机运行我们刚才写的程序。

    如果让计算机运行我们写的东西(其实我们写的就是一个C语言程

    序),需要一个特殊的软件,它叫作“C语言编译器”

    [1]

    , “C语言编译

    器”有很多种,这里介绍一种比较简单的软件,叫作“啊哈C”

    [2]。

    首先你需要到www.ahalei.com页面中下载“啊哈C”。下面就要进入

    安装步骤啦,安装很简单,一共分7步(见图2-1~图2-7),每一步我都

    截取了图片,你只需一口气将这7幅图片全部看完应该就可以。

    图2-1 安装“啊哈C”图2-2 开始安装“啊哈C”

    图2-3 设置“啊哈C”安装目录图2-4 创建桌面图标和启动栏图标

    图2-5 确认安装信息

    图2-6 安装正在进行图2-7 “啊哈C”安装成功

    “啊哈C”安装完毕后,便可以看到如图2-8所示的“啊哈C”的界面,同时在你的桌面上也会多一个“啊哈C”图标。

    图2-8 “啊哈C”的界面

    “啊哈C”是一个很人性化的软件,你将会发现“啊哈C”已经帮你将C

    语言代码框架的部分写好了。只需要将

    printf(ni hao);

    这条语句在“啊哈C”中输入就好,如图2-9所示。图2-9 输入printf(ni hao)

    细心的同学可能会发现,“啊哈C”默认的C语言框架,比之前说的C

    语言框架多了一句话:

    system(pause);

    这句话是什么意思呢?稍后我们再揭晓。先将这句话删除,删除后

    的界面如图2-10所示。

    图2-10 删除system(pause)图2-12 编译成

    功的提示

    好了,同学们请注意,到了最后一步,需要让代码运行起来。现在

    只需单击“啊哈C”上的“运行”按钮 。

    接下来需要为所写的程序起一个名字,我为这个程序起的名字

    是“nihao”,当然你可以随便起名,中英文都可以。比如你可以称之

    为“abc”或“我的第一个程序”,或者叫“1”都行,但是你最好别写火星文

    或者特殊字符,也不能有英文的点号。将程序的名字输入在如图2-11所

    示的文本框中之后再单击“保存”按钮,接下来就是见证奇迹的时刻。

    图2-11 给程序起个名字

    如果代码没有写错,那你的“啊哈C”将会弹出一

    个对话框,提示“恭喜你编译成功”,如图2-12所示。

    请同学们注意,在输入代码的时候,一定不要用中

    文输入法,这里所有的符号都是英文的,一般也都

    是小写。

    下面当然就单击“确定”按钮。接下来,请注意:注视你的计算机屏

    幕,一秒也不要走开,数秒之后,你将会发现计算机的屏幕上有一

    个“黑影”闪过,如果你没有发现这个“黑影”,请重新单击“运行”按钮,并再次注视你的计算机屏幕。

    此时,你可能想问,为什么屏幕上会出现这个“黑影”?我们是要在

    屏幕上显示“ni hao”才对啊。其实刚才那个“黑影”就是“ni hao”,只不过

    计算机的运行速度太快了,在屏幕上显示之后,就立即消失了。那应该

    怎么办呢?这需要让计算机暂停一下。

    system(pause);

    上面这句话就是之前所删除的,其实它的作用就是让计算机“暂停

    一下”。将这句话放在printf(ni hao);后面,完整的代码如下:

    include

    include

    int main

    {

    printf(ni hao);

    system(pause);

    return 0;

    }

    好了,再次单击“运行”按钮吧。如果代码没有错误,你将看到如图

    2-13所示的界面。图2-13 运行成功的结果

    “请按任意键继续…”是system(pause);输出的一个提示,此时

    只需按键盘上的任意一个键,这个小黑窗口就会关闭。

    如果想让“ni hao”分两行显示,则只需要将printf(ni hao);改为

    printf(ni \n hao);这里的“\n”表示让光标“换行”。注意,这里的“\”向

    右下角斜,它在键盘上的位置,通常是在回车键的上方。好,赶快尝试

    一下吧。运行结果如图2-14所示。

    include

    include

    int main

    {

    printf(ni\nhao);

    system(pause);

    return 0;

    }

    图2-14 分行后的运行结果

    当然也可以让“请按任意键继续...”在下一行显示,只需将printf(ni\nhao);改为printf(ni \n hao\n);即可,去试一试吧。

    一起来找茬

    下面这段代码是让计算机在屏幕上输出hi。其中有3个错误,快来

    改正吧!

    include

    include

    int main( )

    {

    print(hi)

    system(pause);

    return 0;

    }

    更进一步,动手试一试

    1.尝试让计算机显示下面这些图形。

    2.如何让计算机说中文呢?让计算机像下面一样说“早上好”,应

    该怎么办?

    3.尝试让计算机显示下面这个图形。

    A

    BC

    DEF GHIJ

    KLMNO

    PQRSTU

    V

    W

    X

    Y

    Z

    这一节,你学到了什么

    如何让计算机开口说话,以及让计算机开口说话的语句是什么?第3节 多彩一点

    在本章第2节中,我们学习了让计算机开口说话应使用printf语句。

    可以发现,计算机“说”出的话都是黑底白字,其实计算机的输出可以是

    彩色的,我们一起来看看吧。

    注意,此处代码只能在Windows操作系统下编译运行。如果你使用

    的是本书推荐的C语言的软件“啊哈C”,那么你的代码肯定可以运行成

    功。下面来看看如何让颜色出现。

    请尝试输入以下代码并运行,看看会发生什么。

    include

    include

    int main

    {

    system(color 5); printf(wa wa wa);

    system(pause);

    return 0 ;

    }

    运行之后你发现了什么?底色仍然是黑色。但是,文字的颜色已经

    变为“紫色”了,奥秘就在下面这行代码中。

    system(color 5);

    在这句话中,“5”代表“紫色”,你可以尝试一下其他数字,看看分

    别是什么颜色。

    既然字的颜色可以变,那么背景色是否可以变呢?尝试下面这段代

    码:

    include

    include

    int main

    {

    system(color f5);

    printf(wa wa wa);

    system(pause);

    return 0; }

    运行成功后的界面如图2-15所示。

    图2-15 运行成功后的界面(此时背景应该为白色,文字颜色应该为紫

    色)

    上面这段代码在原来的5前面加了一个f,这里的f代表背景色是白

    色。

    那么设置背景色和文字颜色的方法是,在color后面加上两个一位数

    字,第一个数字表示背景色,第二个数字表示文字颜色。如果在color后

    面只加了一个一位数字,则表示只设置文字颜色,背景色仍然使用默认

    的颜色。

    需要说明的是这里的一位数字其实是16进制的,它只能是0、1、2、3、4、5、6、7、8、9、a、b、c、d、e、f中的某一个。

    [题外话]“不看,也无伤大雅”

    这里学习一个新知识——进制。

    在现代数学中,我们通常使用十进制,即使用数字0、1、2、3、4、5、6、7、8、9。9之后的数字便无法表示了,我们的解决方法是:

    使用“进位”来表示。例如,由于阿拉伯数字只到9,于是我们便进一

    位,当前这位用0表示,便产生了用10来表示“十”。因为是“逢十进一”,所以称为十进制。

    而十六进制是“逢十六进一”,即使用0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F来表示。0~9与在十进制时相同,但

    是“十”在十六进制时用大写字母A表示,以此类推,“十五”在十六进制

    中用大写字母F来表示。F是“十六进制”中的最后一个,因此数字“十

    六”就表示不了。于是我们又采用刚才在十进制中表示不了就进一位的

    老办法,当前应该用0表示。“十六”在十六进制中表示为10。同理,“二

    十七”在十六进制中表示为1B。

    在中国古代,很多朝代都是用十六进制作为日常计数的,例如,成

    语“半斤八两”的典故来源于十六进制;还有中国古代的算法是上面2颗

    珠子,下面5颗珠子。若上面每颗珠子代表数字5,下面每颗珠子代表数

    字1,那么每位的最大计数值是15, 15正是十六进制的最大基数。当使用

    算盘计数遇到大于15的时候,我们就需要在算盘上“进位”了。

    其实在我们现代的日常生活中,也不都是“十进制”,例如,60秒为

    1分钟,60分钟为1小时,就是用的六十进制。

    一起来找茬

    下面这段代码是让计算机在屏幕上输出绿底白字的hi。其中有4个

    错误,快来改正吧!

    include

    include

    int main( )

    { system(color f2)

    print(hi);

    system(pause);

    return 0;

    }

    更进一步,动手试一试

    1.尝试让计算机打印这个小飞机图案(绿底白字)。

    2.尝试让计算机打印这个小队旗图案(白底红字)。

    A

    I I

    I

    I

    I

    I

    I

    I

    I

    这一节,你学到了什么

    让计算机打印出来的字符有不同颜色的语句是什么?第4节 让计算机做加法

    通过之前的学习,我们了解到让计算机说话是用“printf”,运

    用“printf”就可以让计算机想说什么就说什么了。在学会了“说话”之后,我们来看如何让计算机做数学运算,首先我们先让计算机做“加法”,就

    先算1+2吧。

    回想一下小时候爸爸妈妈是如何教我们算1+2的呢?

    妈妈说:“左手给你一个苹果,右手给你两个苹果,现在一共有几

    个苹果?”我们迅速地思考了一下,脱口而出:“3个苹果”。没错!我们

    首先用大脑记住左手有几个苹果,再用大脑记住右手有几个苹果,妈妈

    问一共有几个时,我们的大脑进行了非常快速的计算,将刚才记住的两

    个数进行相加,得到结果,最后将计算出的结果说出来。仔细分析一

    下,大致分为以下5个步骤。

    (1)用大脑记住左手的苹果数量;

    (2)用大脑记住右手的苹果数量;

    (3)我们的大脑将两个数字进行相加;

    (4)得到结果;

    (5)将结果输出。

    在这期间,我们大脑一共进行了以下4个动作。

    (1)两次输入:分别是记录左手和右手中苹果的数量;(2)存储了3个值:分别是记录左手和右手中苹果的数量和相加的

    结果;

    (3)进行了一次计算:相加;

    (4)进行了一次输出:把相加的结果输出。

    如何让计算机做加法呢?同样也需要以上几个步骤。

    首先来解决如何让计算机像我们的大脑一样记住一个数字。

    其实计算机的大脑就像一个“摩天大厦”,有很多一间一间的“小房

    子”,计算机就把需要记住的数放在“小房子”里面,一个“小房子”里只

    能放一个数,这样计算机就可以记住很多数。好,我们来看一看,具体

    怎样操作。

    “=”赋值符号的作用就相当于一只手,把数字放到小房子中。

    int a, b, c;这句话就代表在计算机的“摩天大厦”中申请三间分别叫作a、b和c

    的小房子(注意:int和a之间有一个空格,a、b与c之间分别用逗号隔

    开,末尾有一个分号表示结束)。

    接下来,我们让小房子a和小房子b分别去记录两个数字1和2,具体

    如下:

    a=1;

    b=2;

    说明:此处有一个“=”,这可不是等于号,它叫作给予号(也称为

    赋值号),类似于一个箭头“←”,意思是把“=”右边的内容赋给“=”左

    边。例如,把1这个数给小房子a,这样一来计算机就知道小房子a里面

    存储的是数字1了。

    然后,把小房子a和小房子b里面的数相加,再将其结果放到小房子

    c中。

    c=a+b;

    计算机会将这个式子分两步执行:第一步先将a+b算出来,第二步

    再将a+b的值赋给“=”右边的c。至此,就差不多完成了,我们总结一下:

    int a, b, c;

    a=1;

    b=2;

    c=a+b;

    很多同学是不是以为,现在已经全部完成了?你忘记了最重要的一

    步,先别急着往下看,想一想忘记了什么?

    啊!你忘记了把答案输出。

    想一想如果妈妈问你一加二等于多少时,你说:“我算出来了,但

    是不想告诉你!”的话,估计少不了挨一顿揍了,不要啊!

    让我们回忆一下,如何让计算机把结果输出。

    对,使用printf语句。那怎么把小房子c里面存储的数输出呢?根据

    本章第2节学到的知识,只要把要输出的内容放在双引号里面就可以

    了,代码如下:

    printf(c);

    猜一猜此时计算机会输出什么?对,无情地输出了一个c。

    那怎样输出c里面的值呢?

    这时我们要让另外一个角色出场了。

    %d

    “%d”其实是一个“讨债的”,或者也可以说是“要饭的”。它的专职工

    作就是向别人“要钱”!那我们应该怎么使用它呢?

    printf(%d, c);将“%d”放在双引号之间,把小房子c放在双引号后面,并且用逗号

    隔开。

    这时printf发现双引号里面是个“讨债的”,就知道此时需要输出一个

    具体的数值,而不是符号,就会向双引号后面的小房子c索取具体的数

    值了。

    好了,最后加上C语言的代码框架,计算机进行加法运算的完整代

    码如下:

    include

    include

    int main

    {

    int a, b, c;

    a=1;

    b=2;

    c=a+b;

    printf(%d, c);

    system(pause);

    return 0;

    }

    现在赶紧去试一试吧。

    一起来找茬下面这段代码是让计算机计算321-123的结果。其中有7个错误,快

    来改正吧!

    include

    include

    int mian( )

    {

    int a, b, c;

    a=321

    b=123

    c=b-a

    print(%d, c)

    system(pause);

    return 0;

    }

    更进一步,动手试一试

    1.如果要进行3个数相加的运算,该怎样做呢?例如:5+3+1=?

    我们可以把上面的程序进行简单地改变,申请4个小房子分别叫作

    a、b、c和d。用a、b、c分别存放3个加数,用d存放它们的和。代码如

    下:

    include include

    int main

    {

    int a, b, c, d;

    a=5;

    b=3;

    c=1;

    d=a+b+c;

    printf(%d, d);

    system(pause);

    return 0;

    }

    如果要10个数相加岂不是得定义11个小房子?那也太麻烦了!对,目前我们只能这样,但是在后面的学习中,会有更为简单的方法。

    2.用计算机算出下面3个算式。

    123456789+43214321

    70788712

    321(123456+54321)

    这一节,你学到了什么1.如何申请一个小房子来存储数值?

    2.如何用printf输出小房子中的数值?第5节 数字的家——变量

    从本章第4节中,我们了解到计算机使用一个个的小房子来记住数

    字。计算机有很多不同种类的小房子。

    int a;

    代表向计算机申请一个小房子,用来存放数值,小房子的名字叫作a。

    int和a之间有一个空格,a的末尾有一个分号,表示这句话结束。

    如果要申请多个小房子,则要在a后面继续加上b和c,用逗号分

    开。例如:

    int a, b, c;

    这里有一个小问题,就是给申请的“小房子”起名字。原则上可以随

    便起:可以是单独的字母,如a、b或x;可以是多个字母的组合,如

    aaa、abc或book;也可以是字母和数字的组合,如a1或abc123。当然也

    有一些限制,如果你想知道,请看附录A。到这里,可能还有很多同学想问,int究竟是什么意思呢?

    其实,int控制小房子用来存放的数的类型,表示你目前申请的小房

    子只能存放整数。

    int是英文单词integer(整数)的缩写。

    如果要放小数该怎么办?

    我们用float来申请一个小房子,用来存放小数,形式如下:

    float a;

    这样,小房子a就可以用来存放小数了,例如: float a;

    a=1.5;

    printf(%f, a);

    就表示申请一个用来存放小数的小房子a,里面存放了小数1.5。

    注意:在C语言中,小数称作浮点数,用float表示。

    之前在用printf语句输出整数时,使用的是“%d”。此时需要输出小

    数,要用“%f”。

    好了,我们来总结一下,这里的“小房子”在我们C语言的专业术语

    中称为变量。int和float说明小房子是用来存放何种类型的数,我们这里

    将其称为“变量类型”或者“数据类型”。

    类似int a;或者float a;的形式,我们称作“定义变量”,它们的语法

    格式如下:

    【口语】 小房子的类型 小房子的名称 , 小房子的名称 ;

    【术语】 变量的类型 变量的名称 , 变量的名称 ;

    【代码】 int a , b ;

    现在我们知道,int a;表示申请一个用来存放一个整数的小房子a,即定义一个整型变量a来存放整数;而float a;则表示申请一个用来存放

    一个小数的小房子a,即定义一个浮点型(实型)变量a来存放浮点数(小数)。

    再来看另外一个有趣的问题,代码如下:

    include

    include

    int main

    {

    int a;

    a=1;

    a=2;

    printf(%d, a);

    system(pause);

    return 0;

    }

    请问计算机执行完上面的代码后,将会输出1还是2?尝试过后你会发现,计算机显示的是2,也就是说小房子a中的值最

    终为2。通过观察代码可以发现,我们首先将1放入小房子a中,紧接着

    又将2放入小房子a中,那么请问原来小房子中的1去哪里了呢?答案

    是,被新来的2给覆盖了并且已经消失了。也就是说,小房子a中有且仅

    能存放一个值,如果多次给小房子a赋值,小房子a中存放的将始终是最

    后一次赋的值。例如:

    include

    include

    int main

    {

    int a;

    a=1;

    a=2;

    a=3; a=4;

    a=5;

    a=6;

    printf(%d, a);

    system(pause);

    return 0;

    }

    计算机运行完上面这段代码后最终将输出6。也就是说小房子a中的

    值最终为6,前5次的赋值全部被覆盖了。

    一个更有意思的问题来了,请继续看下面的代码:

    include

    include

    int main

    {

    int a;

    a=7;

    a=a+1;

    printf(%d, a);

    system(pause);

    return 0; }

    计算机运行完上面这段代码后最终将输出8。也就是说小房子a中的

    值最终为8。计算机在执行完a=7这句话后,小房子a中存储的值为7,之

    后计算机又紧接着运行了a=a+1。运行完a=a+1后,小房子a中的值就变

    为8了。也就是说a=a+1的作用是把小房子a中的值在原来的基础上增加

    1,我们来分析一下这句话。

    对于a=a+1计算机分两步执行,这句话中有两个操作符,第一个

    是“+”,另一个是“=”(赋值号),因为“+”的优先级要比“=”高,因此计

    算机先执行a+1,此时小房子a中的值仍然为7,所以a+1的值为8。紧接

    着计算机就会执行赋值语句,将计算出来的值8再赋值给a,此时a的值

    就更新为8。

    好啦,猜猜下面的程序,计算机最终会输出多少?

    include

    include

    int main

    { int a;

    a=10;

    a=aa;

    printf(%d, a);

    system(pause);

    return 0;

    }

    尝试过了吗?想一想为什么a最终的值为100。

    注:所有运算符的优先级详见附录B。

    一起来找茬

    下面这段代码是让计算机计算1.2×1.5的值。其中有5个错误,快来

    改正吧!

    include

    include

    int main( )

    {

    int a, b, c

    a=1.2;

    b=1.5;

    c=ab; print(%d, c)

    system(pause);

    return 0;

    }

    更进一步,动手试一试

    1.进行两个小数的加法运算,例如:5.2+3.1=?代码如下:

    include

    include

    int main

    {

    float a, b, c;

    a=5.2;

    b=3.1;

    c=a+b;

    printf(%f, c);

    system(pause);

    return 0;

    }

    请注意,之前在printf语句中输出整型变量的值时,使用的

    是“%d”,此时需要输出的是实型变量的值,因此要用“%f”。2.通过计算机把下面3个式子算出来吧!

    1.2+2.3+3.4+4.5

    1.1100

    10.1(1010)

    这一节,你学到了什么

    1.如何定义一个用来存放小数的变量?

    2.如何让一个小房子a(变量a)中的值增加1?第6节 数据输出——我说咋地就咋地

    在本章第4节中,我们已经学会了如何让计算机做加法运算,但是

    计算机在输出的时候,只显示了一个结果,这样不够人性化。如果能将

    整个算术等式输出就好了,例如:1+2=3。那应该怎么写呢?

    新的代码:

    include

    include

    int main

    {

    int a, b, c;

    a=1;

    b=2;

    c=a+b;

    printf(%d+%d=%d, a, b, c);

    system(pause);

    return 0;

    }

    原来的代码: include

    include

    int main

    {

    int a, b, c;

    a=1;

    b=2;

    c=a+b;

    printf(%d, c);

    system(pause);

    return 0;

    }

    仔细阅读这些代码你会发现,新的代码和原来的代码只有一个

    printf语句不一样。好,我们现在来仔细分析一下printf(%d+%d=%d,a, b, c);。

    printf语句只会输出双引号里面的部分,双引号之外的部分只是对

    双引号内的部分起到补充说明的作用。

    例如,printf(%d+%d=%d, a, b, c);这行语句,双引号里面的部

    分是%d+%d=%d,那么计算机在输出的时候就严格按照%d+%d=%d来

    执行,输出的形式必然是%d+%d=%d。

    当计算机遇到第1个“%d”时,知道“讨债的”来了,于是它便向双引

    号后面的变量讨债,排在第1个的是a,那么就向a讨债。a的值是1,于是第1个“%d”得到的便是1。

    第2个是“+”,那么照样输出。

    第3个又是“%d”,同样到双引号的后面去讨债,因为排在第1个的a

    已经被讨过债了,因此向排在第2个的b讨债。b的值是2,于是这

    个“%d”得到的便是2。

    第4个是“=”,照样输出。

    第5个还是“%d”,同样到双引号的后面去讨债,因为排在第1个的a

    和排在第2个的b已经被讨过债了,因此向排在第3个的c讨债。c的值是

    3,于是最后这个“%d”得到的便是3。

    最后输出的内容是1+2=3。

    请注意,通常双引号内部“%d”的个数,和后面变量的个数是相等

    的,它们是一一对应的。如果没有一一对应,从C语言的语法角度来讲

    是没有错误的,但这不合常理,最好避免这样的情况出现。

    一起来找茬

    下面这段代码是让计算机分别计算10-5与10+5的值,并分两行显

    示,第一行显示差,第二行显示和。其中有3个错误,快来改正吧!

    inlcude

    include

    int mian( )

    { int a, b, c;

    a=10;

    b=5;

    c=a-b;

    printf(%dn, c);

    c=a+b;

    printf(%d, c);

    system(pause);

    return 0;

    }

    更进一步,动手试一试

    指定两个数,输出这两个数的和、差、积与商。例如,指定两个数

    9和3,输出9+3=12、9-3=6、9×3=27、93=3。

    include

    include

    int main

    {

    int a, b, c;

    a=9;

    b=3;

    c=a+b;

    printf(%d+%d=%d\n, a, b, c); c=a-b;

    printf(%d-%d=%d\n, a, b, c);

    c=ab;

    printf(%d%d=%d\n, a, b, c);

    c=ab;

    printf(%d%d=%d\n, a, b, c);

    system(pause);

    return 0;

    }第7节 数据输入——我说算啥就算啥

    我们已经学会了如何做一个加法计算器,但是目前的加法计算器还

    不够人性化,每次计算两个数的和时,都需要修改C语言代码,然后重

    新编译运行才能得到结果,很显然这样的加法计算器是不会有人喜欢用

    的,那如何让使用者自己任意输入两个数就可以直接得到结果呢?

    我们知道,让计算机说话用printf,那么让计算机学会听用什么

    呢?scanf将会把听到的内容告诉你的程序。

    计算机“说话”的过程,我们称为“输出”,计算机“听”的过程,我们

    则称为“读入”。好,下面来看看,计算机是如何读入的。

    scanf的语法与printf语法类似,例如,我们要从键盘读入一个数,放在小房子a中,代码如下:

    scanf(%d, a);

    你瞧,与输出小房子a的语句printf(%d, a);是差不多的,只有

    以下两处不同。

    第一处是:读入是使用scanf这个词,而输出是使用printf这个词。

    第二处是:读入比输出在a前面多了一个“”符号。

    “”符号我们称为“取地址符”,简称“取址符”。它的作用是得到小房子a的地址。

    scanf(%d, a);这句话可以理解为:我们要从外界向计算机的

    内部传送一个数值,并需要将这个值存放到指定的“编号为a”的盒子

    中。这样我们就需要知道小盒子a在计算机内部的地址。就像邮递员送

    信一样,要传送的数据就是信件,小盒子a就是信箱编号。

    那你可能要问,为什么在读入的时候要得到小房子a的地址,而输

    出的时候却不需要呢?在读入数据的时候,计算机需要把读入的值存放

    在小房子a(也就是变量a)中,此时需要知道你指定的这个小房子a的

    地址,才能把值准确地放进其中;但是在输出的时候,值已经在小房子

    a中了,因此可以直接输出到屏幕上。

    打一个比方:假如你要去一个教室上课,那么在上课之前你需要知

    道这个教室的地址,这样你才能去;但是如果下课了,你需要走出这个

    教室,因为此时你已经在教室中,所以就不再需要这个教室的地址。

    如果要从键盘读入两个数,分别给小房子a和小房子b呢?这里有以

    下两种写法。第一种:

    scanf(%d, a);

    scanf(%d, b);

    第二种:

    scanf(%d%d, a, b);

    第二种的写法较为简便,两个“%d”之间不需要空

    格,“a”和“b”之间用逗号隔开。

    从键盘读入两个数,输出这两个数的和的完整代码如下:

    include

    include

    int main

    {

    int a, b, c;

    scanf(%d%d, a, b);

    c=a+b;

    printf(%d+%d=%d, a, b, c); system(pause);

    return 0;

    }

    好了,总结一下,在C语言中printf是计算机“说出去的”,也就是计

    算机需要告诉你的;而scanf是计算机“听进来的”,也就是你需要告诉计

    算机的。

    接下来,我们要让“加法计算器”更加人性化——带有提示的读入和

    输出。

    include

    include

    int main

    {

    int a, b, c;

    printf(这是一个加法计算器,欢迎您使用\n);

    printf(--------------------------------\n);

    printf(请输入第一个数(输入完毕后请按回车)\n);

    scanf(%d, a);

    printf(请输入第二个数(输入完毕后请按回车)\n);

    scanf(%d, b);

    c=a+b;

    printf(它们的和是%d, c); system(pause);

    return 0;

    }

    一起来找茬

    下面这段代码是从键盘读入两个整数,并输出它们的和。其中有6

    个错误,快来改正吧!

    include

    include

    int main( )

    {

    int a, b, c;

    scanf(%d, a, b)

    c=a+b

    printf(%dn, c);

    system(pause);

    return 0;

    }

    更进一步,动手试一试

    从键盘读入两个数,并输出这个两个数的和、差、积与商。 include

    include

    int main

    {

    int a, b, c;

    scanf(%d%d, a, b);

    c=a+b;

    printf(%d+%d=%d\n, a, b, c);

    c=a-b;

    printf(%d-%d=%d\n, a, b, c);

    c=ab;

    printf(%d%d=%d\n, a, b, c);

    c=ab;

    printf(%d%d=%d\n, a, b, c);

    system(pause);

    return 0;

    }

    请注意除法运算。在C语言中,当除号“”左右两边都是整数时,商

    也只有整数部分。例如,53的商是1,23的商是0。

    这一节,你学到了什么

    如何从键盘读入一个数到小房子中?第8节 究竟有多少种小房子

    在之前的几节中,我们已经知道计算机如果想“记住”某个值,就必

    须在它的大脑“摩天大厦”中,申请一种小房子。例如:

    int a, b, c ;

    即申请3种小房子分别叫作a、b和c。这3种小房子只能用来存放整数

    (整型数据)。

    再例如:

    float a, b, c ;

    即申请3种小房子a、b和c。这三种小房子只能用来存放小数(浮点型数

    据)。

    也就是说在计算机中,不同类型的数据需要相应类型的小房子来存

    储。那么计算机一共有多少种类型的小房子呢?我们来列举几种最常用

    的,如表2-1所示。

    表2-1 C语言常用的数据类型

    数据类型名称 用来存放哪种数据 数据范围

    int 用来存放整数 ?2147483648~

    2147483647

    float 用来存放浮点数 ±1.18×10?38 ~

    ±3.4×1038

    double

    用来存放极大和极小

    的浮点数

    ±2.23×10?308 ~

    ±1.80×10308

    char 用来存放字符 256种字符

    double也是用来存放小数的,那float和double有什么区别呢?

    请观察下面两段代码。

    代码1:

    include

    include int main

    {

    float a;

    a=3.1415926535897932;

    printf(%.15f, a);

    system(pause);

    return 0;

    }

    代码2:

    include

    include

    int main

    {

    double a;

    a=3.1415926535897932;

    printf(%.15f, a);

    system(pause);

    return 0;

    }通过观察,我们发现代码1和代码2的不同之处只有一点。代码1中

    是用float来申请小房子a,代码2中却是用double来申请小房子a。在输出

    时,两段代码中printf里面所用的占位符都是“%f”。代码中“%”和“f”之

    间的“.15”表示保留小数点后15位(四舍五入)。这里特别说明一下,在

    用scanf读入double类型数据时所用的占位符是“%lf”(注意此处不是数字

    1而是字母l)而不是“%f”。

    它们的运行结果分别如图2-16和图2-17所示。

    图2-16 代码1运行的结果

    图2-17 代码2运行的结果

    怎么样,发现问题了吧?!代码1运行后输出的是

    3.141592741012573,显然从小数点后第7位开始就不对了,而代码2运

    行后输出的是3.141592653589793,完全正确。因此我们可以发现double

    可以比float表示得更精确。另外float和double表示的数的大小范围也不

    同,请大家自己去尝试。

    在表2-1中我们发现有一个新的数据类型char,用char申请的小房子

    是用来存放字符的。 include

    include

    int main

    {

    char a;

    scanf(%c, a);

    printf(你刚才输入的字符是%c, a);

    system(pause);

    return 0;

    }

    我们输入一个字符x后按回车键,结果如图2-18所示,当然你也可

    以尝试一下别的字符。

    图2-18 输入一个字符并输出

    想一想,对于上面这段代码,如果此时你输入的不是一个字母,而是一串字母,计算机会输出什么呢?很抱歉!计算机只会输出你输入的

    第一个字母。

    有的同学可能要问,如果想存储一大串字符该怎么办呢?不要着

    急,我们将在后续章节中介绍如何存储一个字符串。

    一起来找茬

    下面这段代码是让计算机读入一个字符并把这个字符原样输出。其

    中有3个错误,快来改正吧!

    include

    include

    int main( )

    {

    char a;

    scanf(%c, c);

    printf(%d, c);

    system(pause);

    return 0;

    }

    更进一步,动手试一试

    从键盘读入一个字符,输出这个字符后面的一个字符。例如,输入

    字符a,输出字符b。 include

    include

    int main

    {

    char a;

    scanf(%c, a);

    printf(后面的一个字符是%c, a+1);

    system(pause);

    return 0;

    }

    思考一下,为什么一个字符后面的字符就是该字符加1呢?

    这一节,你学到了什么

    1.double是什么类型?

    2.如何存储一个字符?第9节 拨开云雾见月明

    通过前面的学习,我们已经知道计算机如果想“记住”某个值,就必

    须在计算机的大脑“摩天大厦”中,申请一个小房子。例如,之前我们需

    要计算任意两个数的和,程序是这样写的:

    include

    include

    int main

    {

    int a, b, c;

    scanf(%d%d, a, b) ;

    c=a+b;

    printf(%d+%d=%d, a, b, c);

    system(pause);

    return 0;

    }

    其实这个小房子c是多余的,可以直接写成:

    printf(%d+%d=%d, a, b, a+b);代码如下:

    include

    include

    int main

    {

    int a, b;

    scanf(%d%d, a, b);

    printf(%d+%d=%d, a, b, a+b);

    system(pause);

    return 0;

    }

    当然,如果你只想计算4+5的值,可以更简单:

    include

    include

    int main

    {

    printf(%d,4+5);

    system(pause);

    return 0;

    }如果希望计算4+(6-3)×7的值,可以直接这样写:

    include

    include

    int main

    {

    printf(%d,4+(6-3)7);

    system(pause);

    return 0;

    }第10节 逻辑挑战1:交换小房子中的数

    假如在计算机中我们已经有两个小房子(变量)分别叫作a和b,并

    且它们都已经有了一个初始值,但是现在希望将变量a和变量b中的值交

    换,该怎么办呢?

    先来看一段代码:

    include

    include

    int main

    {

    int a, b;

    scanf(%d%d, a, b);

    printf(%d %d, a, b);

    system(pause);

    return 0;

    }

    上面这段代码是从键盘读入两个数,然后将这两个数输出。例如,如果你输入的是5和6,那么输出的也是5和6。可是,我们现在的需求是

    将变量a和b中的数交换后输出,也就是说如果读入的是5和6,那么输出

    的应该是6和5才对。应该怎么办呢?来看一段代码: include

    include

    int main

    {

    int a, b;

    scanf(%d%d, a, b);

    a=b;

    b=a;

    printf(%d %d, a, b);

    system(pause);

    return 0;

    }

    上面的代码企图通过a=b; b=a;语句将变量a和变量b中的值交换,如果你已经运行过上面的代码,就会发现交换并没有成功,变量b的值

    没有变化,反而是变量a的值变成了变量b的值,这是为什么呢?

    我们来模拟一下计算机运行的过程。

    int a, b;指计算机会申请两个小房子(变量),分别叫作a和b。

    scanf(%d%d, a, b);指从键盘读入两个数,分别赋值给变量

    a和变量b。假如我们从键盘读入的两个数分别是5和6,那么变量a中的

    值就是5,变量b中的值就是6。a=b;指计算机会将变量b中的值给变量a,变量a中的值也变成了

    6。变量a中原来的5被新来的6给覆盖了,也就是说原来变量a中的5丢失

    了。

    b=a;指计算机会将此时变量a中的值给变量b,此时变量a中的已经

    是6了,所以变量b的值其实还是6。

    最终,变量a和变量b中的值都为6。那我们要怎么改呢?通过上面

    我们对计算执行过程的模拟,我们发现,主要问题是:计算机在执行完

    a=b;这个语句后,原先变量a中的值被弄丢失了。那我们只要在执行

    a=b;这个语句之前,先将变量a的值保存在另外一个临时变量中就可以

    了,例如,保存在变量t中。代码如下:

    t=a;

    a=b;

    b=t;

    先将变量a中的值给变量t,变量t中的值就变为5(假如原来变量a中是5,变量b中是6),然后再将变量b中的值给变量a,变量a中的值就变

    为6,最后将变量t中的值给变量b,此时变量b中的值就变为5。成功!

    通过一个变量t作为中转站,我们已经成功地将变量a和变量b中的值进

    行了交换。

    完整的代码如下:

    include

    include

    int main

    {

    int a, b, t;

    scanf(%d%d, a, b); t=a;

    a=b;

    b=t;

    printf(%d %d, a, b);

    system(pause);

    return 0;

    }

    一起来找茬

    下面这段代码是让计算机读入两个整数,分别放到变量a和变量b

    中,并将变量a和变量b中的数交换。其中有两个错误,快来改正吧!

    include

    include

    int main( )

    {

    int a, b;

    scanf(%d%d, a, b);

    t=a;

    b=a;

    b=t;

    printf(%d %d, a, b);

    system(pause); return 0;

    }

    更进一步,动手试一试

    在本节我们介绍了如何将两个变量的值进行交换,方法是增加一个

    临时变量来作为中转。你有没有想过,在不增加任何新变量的情况下是

    否也可以完成呢?来看看下面的代码吧。

    include

    include

    int main

    {

    int a, b;

    scanf(%d%d, a, b);

    a=b-a;

    b=b-a;

    a=b+a;

    printf(%d %d, a, b);

    system(pause);

    return 0;

    }

    请思考一下,为什么通过a=b-a; b=b-a; a=b+a;也可以将变量a与变量b中的值交换呢?第11节 天啊!这怎么能看懂

    先来看一段代码:

    include include int main{ i

    nt a, b, c;

    scanf(%d%d, a, b); c=a+b; printf(%d, c); system(pause); return 0; }

    怎么样,你看懂了吗?这段代码的意思其实就是从键盘读入两个整

    数并且输出它们的和。不错,上面的这段代码从语法角度来讲没有任何

    错误,编译器也可以对其编译运行,也就是说计算机可以准确无误

    地“认识”这段代码,但是我们会看得比较吃力。一段优秀的代码,不仅

    仅要让计算机“看懂”,也要让我们可以看懂。再来看看下面这段代码是

    不是更容易让人们理解呢。

    include

    include

    int main

    {

    int a, b, c;

    scanf(%d%d, a, b);

    c=a+b; printf(%d, c);

    system(pause);

    return 0;

    }

    这里需要指出的是,这里的int a, b, c;前面与上一行相比,多了4个

    空格。其实我在输入代码的时候,并不是输入4个空格,而是输入了一

    个Tab

    [3]。使用Tab来调整你的代码格式,是一名优秀的程序员必须要

    养成的习惯。

    include

    include

    int main

    {

    int a;

    a=1; 将变量a赋初始值

    printf(%d, a);

    system(pause);

    return 0;

    }

    在上面的代码中,“”表示注释,它将告诉编译器从“”开始一直到

    本行末尾的内容都是没有用的。注释的主要作用是给程序员看的,通常用来对一行代码进行解释说明或备注。

    include

    include

    int main

    {

    int a;

    a=1; 将变量a赋初始值

    printf(%d, a);

    system(pause);

    return 0;

    }

    上面的代码有两处注释,第1处注释我们讲过,主要是用来解释说

    明本行代码的作用。第2处的注释是将本来有用的代码printf(%d,a);给注释掉,可以理解为“临时性删除”,就是告诉编译器

    printf(%d, a);没有用。你可能要问为什么不直接删除呢?因为有

    时我们并不希望真正删除,只是暂时不需要,以后说不定还要再用,如

    果删除了就找不回来了,如果我们合理地利用“”进行注释,那么计算

    机就不会运行这句话,而是理解这句话是给程序员看的。如果我们以后

    又要使用这句话,只需将这句话前面的“”去掉就可以了,这样是不是

    很方便呢。

    有效地在代码中添加注释,可以让你的程序更具可读性。

    “”只能注释到本行末尾,如果要注释多行,就要在每行上写“”。其实注释还有另外一种,以“”开始一直到“”结束,中间的内容编译

    器都不会理睬。使用“ ”的好处就是它可以跨行。

    例如,下面两段代码的效果是相同的:

    include

    include

    int main

    {

    int a;

    a=1;

    a=2;

    a=3;

    a=4;

    a=5;

    printf(%d, a);

    system(pause);

    return 0;

    }

    include

    include

    int main

    {

    int a; a=1;

    a=2;

    a=3;

    a=4;

    a=5;

    printf(%d, a);

    system(pause);

    return 0;

    }

    上面两段代码中变量a的值最后还是1。

    再来看一段代码:

    int a;

    a=1;

    上面这段代码是定义一个整型变量(小房子)a,并且给变量a赋一

    个初始值1。我们以后会经常遇到在定义一个变量(小房子)之后,给

    其赋初始值的情况,可以简写如下:

    int a=1;多个变量也类似:

    int a=1, b=2, c=3;

    浮点型和字符型也类似:

    float a=1.1;

    char c='x';

    需要注意的是,在给浮点型变量赋初始值的时候必须是一个小数,也就是说必须有小数点。在给字符型变量赋初始值的时候,字符两边需

    要加单引号,记住是单引号,不是双引号。在上面的代码中我们希望把

    字符x赋值给字符变量c,所以我们在字符x的左右两边加上了单引号。

    编程也是一门艺术,需要追求简洁、高效而且优美的代码,一名优

    秀的程序员往往也是一名艺术家。

    [1] “C语言编译器”的作用是把我们写的程序“变”成一个“exe”,即可以让计算机

    直接运行的程序。这个“变”的专业术语称为“编译”。当你的程序“变”成一

    个“exe”后,你就可以脱离“C语言编译器”直接运行你的程序。此时你就可以

    把你写的“exe”发给你的朋友和同学,让他们一起来使用你编写的程序。这里

    的程序从某种意义上来讲也可以称为“软件”。[2] “啊哈C”是一款非常容易上手的C语言编程软件,使用的是GCC内核。界面

    简洁可爱,支持语法高亮、代码折叠、编译错误提示等。操作方便,上手

    快,特别适合C语言入门的初学者使用。

    [3] Tab表示一个制表符,在编程中用Tab来代替空格是一个很好的习惯,可以让

    你的代码看起来更美。Tab键在字母Q键的左边,赶快试一试吧。第3章

    较量才刚刚开始

    第1节 大于、小于还是相等

    和我们一样,计算机也可以判断大小。假如你告诉计算机有a和b两

    个数,计算机除了可以告诉你这两个数的和、差、积和商,还可以告诉

    你谁大、谁小。现在我们就来瞧瞧计算机是如何判断谁大谁小的。

    在此之前,我们需要先说明一下在计算机中用来判断两个数的关系

    的符号,即关系运算符,一共有如下6个:

    == 相等

    > 大于

    < 小于 >= 大于等于

    <= 小于等于!= 不等于

    需要特别注意的是,在计算机中,一个等于号“=”表示赋值,两个

    等于号“==”表示判断是否相等,同学们在编写代码的时候千万不要写

    错。一个感叹号加一个等于号“!=”表示“不等于”。此外计算机只有大于

    等于号“>=”和小于等于号“<=”,没有等于大于号和等于小于号,即不存

    在“=>”和“=<”,这一点请一定要注意。

    例如,以下写法是正确的:

    5>=4

    7! =8

    a
    c==d

    以下写法是错误的:

    4=<7

    8=>3第2节 判断正数

    假如你现在想让计算机判断一个整数是否为正数,如果是则显示

    yes,不是则什么都不显示,应该怎么办呢?

    下面方框中的内容,就是让计算机判断一个数是否为正数的“算

    法”。

    首先,计算机需要有一个小房子(即变量)来存储这个数。

    然后,你需要告诉计算机这个数是什么?

    接下来,计算机需要判断这个数是否为正数。

    最后输出计算机的判断结果。

    算法其实就是解决问题的方法(千万要被这个专业名词给吓住

    了)。

    我们每遇到一个问题,首先需要思考的是解决这个问题的算法,也

    就是解决这个问题的方法和步骤。像上面一样一步一步地列出来,然后

    再将算法的每一步通过C语言来实现。

    下面,我们就用C语言来实现上面的算法。

    首先,计算机需要有一个小房子(即变量)来存储这个数。可以用int a;来申请一个名字叫作a的小房子(即变量),来存

    储需要判断的数。

    然后,需要告诉计算机这个数是什么?

    可以用scanf(%d, a);来读入一个数并将这个数存储在小房

    子a中。

    接下来,计算机需要判断这个数是否为正数。

    这可怎么办?不要紧,待会儿再来分析。

    最后输出计算机的判断结果。

    如果是正数则显示yes,使用printf(yes);。

    好,现在我们集中精力来解决刚才的第3步——判断存放在小房子a

    中的数是否为正数。

    想一想,我们是如何判断一个数是否为正数的?要从正数的定义出发,如果一个数大于0,就是正数。好,计算机也是这么想的,哈哈。

    如果a大于0,则显示yes。

    接下来,尝试用C语言来实现。

    其中“如果”在C语言中用if来表示。代码如下:

    if (a>0) { printf(yes); }

    因为当a>0成立时候,这里只需要执行一条语句,此时{ }也可以省

    略不写,如下:

    if (a>0) printf(yes);

    要注意的是,当且仅当条件成立时 只需要执行一条语句 ? ? ? ? ? ? ? ? ?

    才能省略{

    }。 为什么这么说?不要着急,等你看完本章的第七节就知道了。

    当然,如果你觉得写在同一行很不爽,写成两行也是可以的:

    if (a>0)

    printf(yes);更好的写法应该是在printf(yes);前面空4个空格或者空1个

    Tab,表示printf(yes);是if (a>0)的一部分,当a>0条件成立时才

    执行printf(yes);这条语句。

    if (a>0)

    printf(yes);

    完整的代码如下:

    include

    include

    int main( )

    {

    int a;

    scanf(%d, a); if (a>0) printf(yes);

    system(pause);

    return 0;

    }

    好了,赶快试一试吧。

    假如我希望输入正数时显示yes,输入负数或0时显示no,应该怎么

    办呢?

    若要实现上述要求,第3部分应改为:

    如果(a大于0)显示yes

    如果(a小于等于0)显示no

    对应的C语言代码是:

    if (a>0) printf(yes);

    if (a<=0) printf(no);

    完整的代码如下: include

    include

    int main( )

    {

    int a;

    scanf(%d, a) ;

    if (a>0) printf(yes);

    if (a<=0) printf(no);

    system(pause);

    return 0;

    }

    此外,if (a>0) printf(yes);

    这句话更加完美的写法是:

    if (a>0)

    {

    printf(yes);

    }所以判断正数的代码更好的写法是:

    include

    include

    int main( )

    {

    int a;

    scanf(%d, a) ;

    if (a>0)

    {

    printf(yes);

    }

    if (a<=0)

    {

    printf(no);

    }

    system(pause);

    return 0;

    }

    最后,需要注意的是if ( )后面是没有分号的,像下面这些写法都

    是不对的!

    if (a>0) ; printf(yes); if (a>0);

    printf(yes);

    if (a>0);

    {

    printf(yes);

    }

    至于为什么呢?这句话的意思是“如果什么成立,就做什么”,很明

    显“如果什么成立”这句话只说了一半,所以if ( )后面不能加分号,需

    要特别注意!

    if语句的语法格式为:

    if (条件)

    {

    语句1;

    语句2;

    语句 ……

    }

    if后面一对圆括号中的内容是一个关系表达式,当表达式成立时执

    行后面花括号中的语句。好了,赶快试一试吧。

    一起来找茬

    下面这段代码用来判断一个数是否小于或等于100,如果是则输出

    yes。其中有3个错误,快来改正吧!

    include

    include

    int main( )

    {

    int a;

    scanf(%d, a) ;

    if (a<100) ; printf(yes);

    system(pause);

    return 0;

    }

    更进一步,动手试一试

    假如我希望输入正数时显示yes,输入负数时显示no,输入0时显示

    0,应该怎么办呢?

    这一节,你学到了什么

    if语句的基本格式是什么?第3节 偶数判断

    通过对本章第2节内容的学习,我们知道计算机是通过if语句来进行

    判断的。现在来尝试一下判断一个数是否为偶数。首先,先写出算法。

    (1)计算机需要有一个小房子(即变量)来存储这个数。

    (2)你需要告诉计算机这个数是什么?

    (3)计算机需要判断这个数是否为偶数。

    (4)计算机输出判断结果。

    其中,在第3步你可能遇到一点小麻烦。我们想一下,什么是偶数

    呢?偶数就是能够被2整除的数,也就是说如果一个数除以2的余数为

    0,那么这个数就是偶数。

    那么我们现在只需要判断这个数除以2的余数是不是0,即:

    如果a除以2的余数与0相等,则输出yes;

    如果a除以2的余数与0不相等,则输出no。

    C语言中求余数的运算符号是“%”,所以判断一个数是否为偶数的C

    语言代码就是:完整的C语言代码如下:

    include

    include

    int main( )

    {

    int a;

    scanf(%d, a) ;

    if (a%2==0)

    {

    printf(yes);

    }

    if (a%2! =0)

    {

    printf(no);

    }

    system(pause);

    return 0;

    }

    好了,应该尝试一下了。 一起来找茬

    下面这段代码用来判断一个数是否是7的倍数。其中有4个错误,快

    来改正吧!

    include

    include

    int main

    {

    int a;

    scanf(%d%d, a) ;

    if a%7=0

    {

    printf(yes);

    }

    system(pause);

    return 0;

    }

    更进一步,动手试一试

    如何判断一个数的末尾是不是0呢?如果是则输出yes(例如

    120),不是则输出no(例如1 234)。第4节 神器else

    在本章第3节中,我们使用了两个if语句让计算机判断一个数是否为

    偶数,不出意外的话,我想你已经成功了。本节我们将学习另外一个语

    句来简化之前的代码,那就是神奇的else。

    else表示否则,只能和if配合使用。

    现在回到如何让计算机判断一个数是否为偶数这个问题上,回顾一

    下本章第3节的算法:

    如果a除以2的余数与0相等,则输出yes;

    如果a除以2的余数与0不相等,则输出no。

    其实上面第2个“如果”中的条件“a除以2的余数和0不相等”正好就是

    第1个“如果”中的条件,即“a除以2的余数和0相等”的相反情况,因此我

    们用“否则”来代替,从而简化我们的代码。

    如果a除以2的余数与0相等,则输出yes;

    否则,输出no。这里的“如果”在C语言中仍然用if来表示,这里的“否则”就用else来

    表示。好,转换为如下代码:

    if (a % 2==0) printf(yes);

    else printf(no);

    其实,更漂亮的写法是下面这样的:

    if (a % 2==0)

    {

    printf(yes);

    }

    else

    {

    printf(no);

    }从键盘读入一个整数判断它是否为偶数的完整代码如下:

    include

    include

    int main

    {

    int a;

    scanf(%d, a);

    if(a%2==0)

    {

    printf(yes);

    }

    else

    {

    printf(no);

    }

    system(pause);

    return 0;

    }

    if-else语句的语法格式为:

    if (条件)

    { 语句1;

    语句2;

    语句 ……;

    }

    else

    {

    语句1;

    语句2;

    语句 ……;

    }

    当条件为真的时候执行if后面的语句;当条件为假的时候执行else后

    面的语句。

    一起来找茬

    下面这段代码用来判断一个数的末尾是否为7,例如:7、17、127……如果是则打印yes,不是则打印no。其中有6个错误,快来改正

    吧。

    include

    include

    int main

    {

    int a;

    scanf(%d, a); if (a%10=7);

    {

    printf(yes)

    }

    else;

    {

    prinf(no)

    }

    system(pause);

    return 0;

    }

    更进一步,动手试一试

    从键盘输入一个正整数,让计算机判断这个数是否为一位数(1~

    9)。如果是则输出yes,否则输出no。

    这一节,你学到了什么

    if-else语句的基本格式是什么?第5节 请告诉我谁大

    在本章第4节中,我们学习了使用if-else语句来判断一个整数是否为

    偶数的方法。本节我们将学习如何从键盘输入两个整数,让计算机来判

    断哪一个整数较大,并把较大的那个整数输出来。例如,如果我们输入

    的是5和8,那么计算机输出8。

    在学习“如何让计算机判断两个数中,谁更大”这个问题之前,先回

    顾一下第2章中如何从键盘读入两个整数并且算出它们的和的问题。

    include

    include

    int main

    {

    int a, b, c;

    scanf(%d%d, a, b);

    c=a+b;

    printf(%d+%d=%d, a, b, c);

    }

    在上面这段代码中,我们输出的是“和”。那如何让计算机输出较大

    的一个数呢?我们仍然使用“如果”的方法。

    首先还是定义3个变量:a和b用来存放输入的两个数,c用来存放a

    和b中较大的那个。 int a, b, c;

    然后读入从键盘输入的两个数,分别存放到变量a和b中。

    scanf(%d%d, a, b);

    接下来要注意了,我们将通过之前学过的“如果”和“否则”的方法,来分情况讨论并判断谁更大。

    如果(a>b) c=a;

    上面这两行代码是说明在a>b条件成立的情况下,我们将a的值赋给

    c。但是a>b条件并不一定成立,所以我们还要告诉计算机在条件不成立的情况下,应该怎么办。

    所以还要写:

    否则 c=b;

    那么完整的代码如下:

    如果(a>b) c=a;

    否则 c=b;

    总结一下,如果a>b成立,就将a的值赋给c,执行c=a。如果不成

    立,就执行“否则”部分,将b的值赋给c,执行c=b。

    计算机通过“如果”和“否则”方法来分情况讨论。当a>b成立时,给

    出一种解决方案即执行某一个语句,这里是c=a;。当假设不成立的时

    候,给出另外一种解决方案即执行另外一个语句,这里是c=b;。

    完整代码如下,赶快尝试一下吧。

    include

    include

    int main

    { int a, b, c;

    scanf(%d%d, a, b);

    if(a>b)

    {

    c=a;

    }

    else

    {

    c=b;

    }

    printf(%d, c);

    system(pause);

    return 0;

    }

    一起来找茬

    下面程序的功能是从键盘读入两个整数,判断它们是否相等,如果

    相等则输出yes,不相等则输出no。其中有6个错误,快来改正吧!

    include

    include

    int main

    {

    int a; scanf(%d, a, b) ;

    if (a=b) ;

    {

    printf(yes) ;

    }

    else ;

    {

    prinf(no) ;

    }

    system(pause);

    return 0;

    }

    更进一步,动手试一试

    从键盘输入两个正整数,让计算机判断第2个数是不是第1个数的约

    数。如果是则输出yes,不是则输出no。第6节 逻辑挑战2:3个数怎么办

    在本章第5节中,我们学习了如何从两个数中找出较大的一个数,那么3个数该怎么办呢?

    在解决这个问题之前,先回忆一下,我们是如何在任意3个数中找

    出最大一个数的呢?例如,1322、4534、1201这3个数中哪个数最大?

    怎么样,想出来了没有?千万不要告诉我,你是“一眼”就看出来

    的,如果是这样的话,请你在下列各数中“一眼”找出最大的那个来并告

    诉我。怎么样,你“一眼”就看出来了吗?最大的数是多少?如果你可以在

    1秒内看出来,那你一定不是地球人,最大的数是1232。

    现在回归正题,我们从一个数列中寻找最大的一个数的时候,大致

    是从左到右、从上到下快速地扫描(当然,古代的中国人可能是从上到

    下、从右到左),在快速扫描的过程中,我们首先会记住第1个数,然

    后继续往下看,一直看到一个数比之前记住的最大的数还要大时,就转

    为记住这个更大的数,然后一直快速扫描完毕,找出最大的一个。下面

    来模拟这个过程。同理(我上学的时候最怕看到这个词语,没有办法,这里我也借用

    一下,因为我一时半会儿也想不到更好的词语了),我们来找出3个数

    中最大的数也是相同的原理。

    计算机要想找出3个数中最大的数,其实就是模仿我们的思维过

    程。

    首先,用3个变量a、b、c分别存放从键盘读入的3个数。

    然后,先比较变量a和b的值,将较大的值赋给变量d。

    再比较变量d和c的值,如果变量c的值大于变量d的值,则把变量

    c的值赋给变量d。

    最后输出变量d的值。

    完整的代码如下:

    include

    include

    int main

    {

    int a, b, c, d;

    scanf(%d %d %d, a, b, c); if(a>b)

    {

    d=a;

    }

    else

    {

    d=b;

    }

    if(d
    {

    d=c;

    }

    printf(%d, d);

    system(pause);

    return 0;

    }

    当然还有另外一种方法,就是分别比较变量a和b,以及变量a和c的

    关系……思路如下:

    如果a>=b并且a>=c,则输出a;如果b>a并且b>=c,则输出b;

    如果c>a并且c>b,则输出c。

    其中“并且”在C语言中用“”来表示,顺便说一下在C语言

    中“或”用“||”表示。“||”这个符号可能在键盘上不太好找,它通常

    在“Enter”键的上面。在英文输入法状态下,按住“Shift”键不要松手,再

    按下“Enter”键上方的那个键,就会出现1个“|”,重复两次就可以啦。

    “”表示逻辑“并且”

    “||”表示逻辑“或”

    想一想为什么不能像下面这样写?这样写会有什么问题?自己去探

    索吧!

    [1]

    如果a>=b并且a>=c,输出a;

    如果b>=a并且b>=c,输出b;

    如果c>=a并且c>=b,输出c。

    完整的代码如下: include

    include

    int main( )

    {

    int a, b, c;

    scanf(%d %d %d, a, b, c);

    if (a>=b a>=c) printf(%d, a);

    if (b>a b>=c) printf(%d, b);

    if (c>a c>b) printf(%d, c);

    system(pause);

    return 0;

    }

    使用这种方法虽然代码比较简洁,但是在10个数中找出最大的数就

    很麻烦了。而从介绍的第1种方法则可以很容易地扩展出在10个数中找

    出最大的数的方法。

    一起来找茬

    下面这个程序的功能是从键盘读入一个整数,判断这个数是否为7

    的倍数或者为末尾含7的数,例如:7、14、17、21、27、28……如果是

    则输出yes,不是则输出no。其中有5个错误,快来改正吧。

    include include

    int main

    {

    int a;

    scanf(%d, a) ;

    if (a%7=0 | a%10=7) ;

    printf(yes) ;

    else

    printf(no)

    system(pause);

    return 0;

    }

    更进一步,动手试一试

    1.从键盘任意读入3个整数,如何从中找出最小的一个?

    2.从键盘任意读入4个整数,如何从中找出最大的一个?

    3.从键盘输入一个年份(整数),判断这个年份是否为闰年,是

    则输出yes,不是则输出no。第7节 逻辑挑战3:我要排序

    在本章第6节中,我们学习了如何从3个数中找出最大的一个,现在

    有一个新的问题:如何从键盘输入任意3个数,并将这3个数从大到小排

    序呢?例如,无论你输入2 1 3、3 2 1、1 2 3还是3 1 2,计算机都能够输

    出3 2 1,这该怎么办呢?此时你先不要急着往下看,思考一下,通过我

    们之前学习的内容,你应该可以独立完成,赶快打开“啊哈C”去尝试一

    下吧!

    怎么样?我想你应该已经做出来了,即使不是完全正确也应该有了

    大概的思路。如果你还没有尝试过,请赶快再去尝试一下吧,这样会让

    你更容易理解下面的内容,同时也可以比较一下你想的和我所讲的是否

    一样。顺便说一下,要想学好编程,最重要的就是要多尝试。

    要想把3个数从大到小排序,其实有很多种方法,这里我们主要讲

    解两种方法。

    下面来讲第1种方法,这是一种最直接的方法。

    如果a>=b并且b>=c,打印a b c;

    如果a>=c并且c>b,打印a c b;

    如果b>a并且a>=c,打印b a c;

    如果b>=c并且c>a,打印b c a;如果c>a并且a>=b,打印c a b;

    如果c>b并且b>a,打印c b a。

    完整的代码如下:

    include

    include

    int main( )

    {

    int a, b, c;

    scanf(%d %d %d, a, b, c);

    if (a>=b b>=c) printf(%d %d %d, a, b, c);

    if (a>=c c>b) printf(%d %d %d, a, c, b);

    if (b>a a>=c) printf(%d %d %d, b, a, c);

    if (b>=c c>a) printf(%d %d %d, b, c, a);

    if (c>a a>=b) printf(%d %d %d, c, a, b);

    if (c>b b>a) printf(%d %d %d, c, b, a);

    system(pause);

    return 0;

    }

    第2种方法,我称之为“换位法”。一共有3个变量,也就是说分别有

    3个小房子a、b和c。我们的目标是在小房子a中存储最大的变量,在小房子b中存储次大的变量,在小房子c中存储最小的变量。

    首先,我们先将小房子a中的数与小房子b中的数做比较,如果小房

    子a中的数小于小房子b中的数,则将小房子a和小房子b中的数交换。这

    样我们就可以确定,在小房子a和小房子b中,一定是小房子a中存的是

    比较大的数。关于如何交换两个变量的值,我们在第2章的第10节已经

    讨论过了,需要借助另外一个小房子t作为中转,代码如下:

    if (a
    此时上面的这行语句不能简写为:

    if (a
    因为,当a
    将这3条语句放在一对{ }括号中形成一个语句块,这样当条件a
    时,计算机才会依次执行t=a; a=b; b=t;这3条语句。如果不加{ },当条

    件a
    如何都会执行。因为if语句后面只能跟随一条语句或者一个语句块,使

    得a=b;和b=t;与if(a
    易让你理解:

    if (a
    b=t;

    所以当需要在if语句后面执行多条语句的时候,就必须要用{ }把所

    有需要执行的语句括起来,形成一个语句块,这样,计算机就知道它们

    是一起的了,要执行就一起执行,要么就都不执行。

    接下来,需要再次比较小房子a和小房子c中的数。如果小房子a中

    的数小于小房子c中的数,则将小房子a和小房子c中的数交换。这样就

    可以确定,在小房子a和小房子c中,一定是小房子a中存的数的值比较

    大。

    if (a
    经过将小房子a中的数分别与小房子b、小房子c中的数进行比较和

    交换,我们可以确定小房子a中存储的数一定是3个数中最大的。至于目

    前小房子b和小房子c中存的是什么值不重要,因为我们待会儿还要继续

    比较小房子b和小房子c中的值。重要的是已经确定小房子a中存储的已

    经是最大的数了。下面继续比较小房子b和小房子c中的值,将较大的值放在小房子b

    中。

    if (b
    下面是完整的代码,赶快来试一试吧。

    include

    include

    int main( )

    {

    int a, b, c, t;

    scanf(%d %d %d, a, b, c);

    if (a
    if (a
    if (b
    printf(%d %d %d, a, b, c);

    system(pause);

    return 0;

    }

    在第6章,我们将会学习选择排序,它就是基于这种方法的扩展。

    题外话:有时像这样的写法,显得过于紧凑。

    if (a
    if (a
    {

    t=a;

    a=b;

    b=t;

    }

    其完整的代码如下:

    include

    include

    int main( )

    {

    int a, b, c, t;

    scanf(%d %d %d, a, b, c);

    if (a
    {

    t=a;

    a=b;

    b=t;

    }

    if (a
    t=a;

    a=c;

    c=t;

    }

    if (b
    {

    t=b;

    b=c;

    c=t;

    }

    printf(%d %d %d, a, b, c);

    system(pause);

    return 0;

    }

    一起来找茬

    下面程序的功能是从键盘读入1个整数,如果这个数是奇数就输出

    这个数后面的3个数,如果这个数是偶数,就输出这个数前面的3个数。

    例如,如果输入的整数是5,就输出678;如果输入的整数是4,就输出

    321。其中有两个错误,快来改正吧。

    include

    include int main

    {

    int a;

    scanf(%d, a) ;

    if (a%2==1)

    printf(%d , a+1) ;

    printf(%d , a+2) ;

    printf(%d , a+3) ;

    else

    printf(%d , a-1) ;

    printf(%d , a-2) ;

    printf(%d , a-3) ;

    system(pause);

    return 0;

    }

    更进一步,动手试一试

    从键盘读入任意4个整数,将其从小到大输出。第8节 运算符总结

    通过前面的学习,我们了解了C语言中的许多运算符,有算术运算

    符“+”、关系运算符“==”和逻辑运算符“”、“||”。下面我们来总结一

    下,如表3-1所示。

    表3-1 运算符总结

    名称 作用

    + 加

    减

    乘

    除

    > 大于

    < 小于

    == 等于

    >= 大于等于

    <= 小于等于!= 不等于

    与

    || 或! 非第9节 1>2究竟对不对

    幼儿园的小朋友大概都知道1>2这个关系表达式是不成立的。对C

    语言来讲,1>2这个关系表达的写法并没有任何错误,只不过它是假的

    关系表达式。如果喜欢,你也可以写11<10,相信你还可以写出很多这

    样假的关系表达式。可是你千万不要以为类似于11<10这样的假的表达

    式没有任何意义,在第4章你会发现它大有用途。

    此外,2>=2这个关系表达式是真的,因为它表示的是2大于2或者2

    等于2,只需满足其中任意一个条件就是真的关系表达式。类似于1<=2

    这样的表达式也是真的。

    请看下面这段代码:

    if (1>2)

    {

    printf(yes);

    }

    else

    {

    printf(no);

    }

    上面这段代码表示,如果1>2成立,也就是说如果1>2这个关系表达

    式是真的,则输出yes,否则输出no。很显然1>2是假的,计算机会输出no。这个应该很容易理解。但是看到下面这段代码你肯定会晕:

    if (1)

    {

    printf(yes);

    }

    else

    {

    printf(no);

    }

    你猜计算机会输出什么?去试一试!

    如果是下面这样呢?

    if (-5)

    {

    printf(yes);

    }

    else

    {

    printf(no);

    }你猜计算机输出了什么,去试一试吧。

    如果是这样呢?代码如下:

    if (0)

    {

    printf(yes);

    }

    else

    {

    printf(no);

    }

    计算机又输出了什么呢?

    如果上面的3段代码你都尝试过,你会发现前两段代码都是输出

    yes,也就是说,计算机认为前两个代码中if后面圆括号内的关系表达式

    都是成立的,是真的。第3段代码输出的是no,即认为第3段if后面一对

    圆括号内的关系表达式不成立,是假的。

    这时你可能会觉得奇怪了,关系表达式不应该是一个式子吗,至少

    也应该有一个“>”、“<”或“==”之类的运算符才对啊。为什么单独一个数

    字也有真假呢?

    这个确实很奇怪,计算机就是认为1和-5是真的,0是假的。其实在

    C语言中,对于某一个数讨论真假时,只有0是假的,其余都被认为是真

    的。很显然,如下3个程序都是打印yes: if (8)

    {

    printf(yes);

    }

    else

    {

    printf(no);

    }

    if (1000)

    {

    printf(yes);

    }

    else

    {

    printf(no);

    }

    if (-123)

    {

    printf(yes);

    } else

    {

    printf(no);

    }

    只有下面这个程序才会打印no:

    if (0)

    {

    printf(yes);

    }

    else

    {

    printf(no);

    }第10节 讨厌的嵌套

    if-else语句的“嵌套”就是在一个if-else语句中再“嵌套”另外一个if-

    else语句。在讲“嵌套”之前我们先回忆一下本章第6节中的一个例子:如

    何在三个数中找出最大的一个数。

    include

    include

    int main( )

    {

    int a, b, c;

    scanf(%d %d %d, a, b, c);

    if (a>=b a>=c) printf(%d, a);

    if (b>a b>=c) printf(%d, b);

    if (c>a c>b) printf(%d, c);

    system(pause);

    return 0;

    }

    在上面的代码中,我们使用了“”这个逻辑关系运算符号来解决

    两个条件同时“满足”的需求。其实还有另外一种方法来解决这个问题。 if(a>=b a>=c)

    printf(%d, a);

    例如,上面这段代码,可以用“嵌套”的方式写成:

    if(a>=b)

    {

    if(a>=c)

    {

    printf(%d, a);

    }

    }

    其意思是:当a>=b条件满足时,再进一步讨论a与c的关系(如果

    a>=c也成立的话,就打印a)。

    接着往下想,如果此时a>=b已经成立,但是a>=c不成立的话,是不

    是就意味着在a、b、c中,c是最大值呢?答案是肯定的。代码如下:

    if(a>=b)

    {

    if(a>=c)

    { printf(%d, a);

    }

    else

    {

    printf(%d, c);

    }

    }

    那如果第一个条件a>=b不成立呢?完整的代码如下:

    include

    include

    int main

    {

    int a, b, c;

    scanf(%d %d %d, a, b, c);

    if(a>=b) a>=b成立的情况

    {

    if(a>=c) 进一步讨论a与c的关系

    {

    printf(%d, a);

    }

    else

    {

    printf(%d, c); }

    }

    else a>=b不成立的情况

    {

    if(b>=c) 进一步讨论b与c的关系

    {

    printf(%d, b);

    }

    else

    {

    printf(%d, c);

    }

    }

    system(pause);

    return 0;

    }

    在上面的代码中所有的if-else语句都加了{ },这样看起来很臃肿,我们之前说过如果if和else后面只有一条语句的话,是可以省略{ }的。

    代码如下:

    include

    include

    int main {

    int a, b, c;

    scanf(%d %d %d, a, b, c);

    if(a>=b)

    {

    if(a>=c)

    printf(%d, a);

    else

    printf(%d, c);

    }

    else

    {

    if(b>=c)

    printf(%d, b);

    else

    printf(%d, c);

    }

    system(pause);

    return 0;

    }

    上面的代码其实还可以更简洁,如下:

    include include

    int main

    {

    int a, b, c;

    scanf(%d %d %d, a, b, c);

    if(a>=b)

    if(a>=c)

    printf(%d, a);

    else

    printf(%d, c);

    else

    if(b>=c)

    printf(%d, b);

    else

    printf(%d, c);

    system(pause);

    return 0;

    }

    你发现没有,在上面的代码中,我们把最外层if-else语句的{ }也去

    掉了。有的同学可能就有问题要问了。我们先来解决问题2。问题2比较简单,else的匹配采用就近原则,离上方哪个if最近,就属于哪个if。所以问题2所指向的那个else是属于

    if(b>=c)这个if。这样你就可以把if和else分别一一配对了吧,是不是

    有点连连看的感觉。

    问题1说起来比较麻烦,但是原理很简单,请听我慢慢道来。其实

    上面虚线框中的代码是一个if-else语句,并且是一个很完整的if-else语

    句,因为它不但有if部分还有else部分。只不过很特别的是,if部分和

    else部分都分别有自己的子语句printf部分,所以看起来就显得很多了。

    其本质上就是一条if-else语句,一个“复合语句”。不过在外层的

    if(a>=b)看来,它就是一条if-else语句,至于这条语句内部长什么样

    子,if(a>=b)并不关心,其实就像大盒子里面套小盒子一样,if(a>=b)是搞不清楚if(a>=c)里面是什么样子的。第11节 if-else语法总结

    其实说起来很简单,当if( )括号内的关系表达式成立的时候,就

    执行if( )后面的{ }中的内容,不成立的时候则执行else后面{ }中的内

    容。当{ }内的语句只有一条的时候,{ }可以省略。

    if(关系表达式)

    {

    语句;

    语句;……

    }

    else

    {

    语句;

    语句;……

    }

    当{ }内的语句只有一条的时候,可以省略{ }。

    if(关系表达式)

    语句; else

    语句;

    [1] 在写本书草稿的时候,我也没有注意到这个问题,感谢@滚雪球snow的提

    醒。第4章

    重量级选手登场

    第1节 永不停止的哭声

    通过第2章的学习,我们知道如果让计算机开口说话要使用printf语

    句。例如,让计算机说“wa”,则使用printf(wa);。那如果让计算机

    说10遍“wa”呢?你可以尝试这样写:

    printf(wa wa wa wa wa wa wa wa wa wa);

    或者你也可以这样写:

    printf(wa);

    printf(wa);

    printf(wa);

    printf(wa);

    printf(wa);

    printf(wa);

    printf(wa);

    printf(wa);

    printf(wa); printf(wa);

    如果让计算机说10000遍“wa”呢?该怎么办呢?我想你肯定要疯了

    吧。在本节我们就要学习如何让计算机做重复的事情。

    好,首先我们学习如何让计算机“永无止境”地说“wa”。这很简单,代码如下:

    while(1>0)

    {

    printf(wa);

    }

    赶快尝试一下,你是不是发现计算机开始无止境地说“wa”了呢。

    完整的代码如下:

    include

    include

    int main

    {

    while(1>0)

    {

    printf(wa); }

    system(pause);

    return 0;

    }

    一定要尝试啊,尝试后再往下看。

    当然,你也可以让计算机无止境地说任何内容。例如:

    while(1>0)

    {

    printf(bie wa);

    }

    回到正题。上面的代码中由两部分组成,一部分是while( )中的

    内容,另一部分是{ }中的内容。它表示的意思是,当while后面( )中

    的关系表达式为真时,即关系表达式成立时才执行{ }中的内容。

    那么很显然,1>0这个关系是永远成立的,所以计算机会一直执行{

    }中的内容,而上面的例子{ }中只是输出wa,所以计算机就会不停地输

    出wa。这里顺便说一下,如果{ }中只有一条语句,那么{ }便可以省略。

    也就是说可以简写成:

    while(1>0)

    printf(wa);

    这时你可能要问了:while后面( )中的1>0是否可以写成2>1或者

    3>0等?

    当然可以,如果想让计算机永不停止地如此执行,你可以写任何一

    个关系表达式为真的式子。甚至,你可以写while(1)。还记得吗,我

    们在第3章说过,如果对某个数字判断真假,只要这个数不为0就是真

    的。例如,下面这段代码也可以永不停止地在屏幕上打印wa:

    while(1)

    printf(wa);下面我来实现一个很炫的效果,“黑客帝国”来啦!

    include

    include

    int main

    {

    while(1>0)

    {

    printf(0 1);

    }

    system(pause);

    return 0;

    }

    执行上面的代码后计算机就会不停地在屏幕上打印0和1。

    当然,你可以改变一下打印的背景与字的颜色,例如,改为黑色的

    背景,绿色的字。

    还记得吗?是使用system(color 0a);这个语句。 include

    include

    int main

    {

    system(color 0a);

    while(1>0)

    {

    printf(0 1);

    }

    system(pause);

    return 0;

    }

    是不是很像黑客帝国?

    猜一猜,运行下面这段代码,计算机会有什么反应?

    include

    include

    int main

    {

    while(1<0)

    {

    printf(wa);

    } system(pause);

    return 0;

    }

    我想你应该猜到了,计算机一句“wa”都没有说,这是为什么呢?因

    为1<0这个关系表达式不成立,所以计算机没有执行后面{ }中的内容。

    此时你会发现计算机要么打印无数遍都不停止,要么就一次都不打

    印。如果想打印指定的次数该怎么办?例如,我们之前遗留下来的问

    题:打印10000遍wa,一次也不多、一次也不少该怎么办?不要着急,让我们一起进入本章第2节。

    一起来找茬

    下面这段代码是让计算机“永无止境”地打印hello。其中有两个错

    误,快来改正吧!

    include

    include

    int main( )

    {

    while(1>0);

    print(hello);

    system(pause);

    return 0;

    } 更进一步,动手试一试

    让计算机“永无止境”地在屏幕上显示中文汉字“你好”。

    这一节,你学到了什么

    在C语言中我们用什么语句来实现循环的功能?第2节 我说几遍就几遍

    在本章第1节,我们学习了如何使用while循环来让计算机做重复的

    事情,本节将揭晓如何让计算机重复指定的次数。

    我们知道如果while后面( )中的关系表达式成立,计算机就会运

    行{ }中的内容。如果( )中的关系表达式永远成立,那么计算机会“永

    无止境”地去重复执行{ }中的内容。

    假如让计算机打印100次“wa”,我们需要解决的就是如何让while中的关系表达式在前100次是成立的,然后在第101次的时候就不成立

    了。想一想,根据我们之前学过的知识,你有没有什么方法?

    很显然while后面的( )中的关系表达式,像2>1或者1<=100等都是

    不适合的,因为像这样用固定的数字组合的关系表达式,一旦被写出,那么这个式子是否成立就已经是板上钉钉啦,非真即假,而且永远不会

    改变。例如,1<=100这个关系表达式是永远成立的,这样并不符合我们

    的要求。我们需要创造怎样一个新的关系表达式,才能让这个式子有时

    成立,有时不成立?该怎么办呢?我猜你已经想到了!那就是——伟大的“变量”。

    我们可以尝试一下带有变量的关系表达式,例如,a<=100。因为a

    是一个变量,a这个小房子里面所装的数是可以变化的。当小房子a中的

    数是1的时候,a<=100是成立的;当小房子a中的数是101时,a<=100就

    不成立了,这正好满足了对于表达式a<=100有时成立有时不成立的要

    求。对于a<=100这个关系表达式是否成立的关键就在于a这个变量所装

    的数是多少,也就是变量a的值。

    如果想让a<=100在前100次成立,在第101次不成立的话,只需将变

    量a的值从1变化到101就可以了。那么如何让变量a的值从1变化到101

    呢?我们只需在最开始的时候将变量a的值赋为1,然后while循环每循环

    一次,就将变量a的值在原来的基础上再加1就可以了。当变量a的值加

    到101时,a<=100就不成立了,就会结束循环。代码如下:

    int a;

    a=1;

    while(a<=100)

    {

    printf(wa);

    a=a+1;

    }

    再来分析一下上面的代码,a=a+1;这条语句的作用是把小房子a中

    的值在原本的基础上增加1(在第2章第5节有详细解释,如果还没有搞

    懂还是回去看看吧)。变量a最开始时值为1,每执行一次while循环,变量a的值就会在原来的基础上增加1,依次变成2、3、4、5、6、7、8、9,…,100、101。直到变量a的值为101时,a<=100的条件不成立,退出循

    环。

    完整的代码如下:

    include

    include

    int main

    {

    int a;

    a=1;

    while(a<=100)

    {

    printf(wa);

    a=a+1;

    } system(pause);

    return 0;

    }

    赶快尝试一下吧。如果输出10000个wa该怎么办?或者输出10个

    hello呢?赶快去尝试一下吧。

    接下来一个问题:如果要打印1~100该怎么办?

    include

    include

    int main

    {

    int a;

    a=1;

    while(a<=100)

    {

    printf(wa);

    a=a+1;

    }

    system(pause);

    return 0;

    }

    在这段代码中,我们打印了100个wa,那么打印1~100也很简单,只需修改printf语句就可以了。该如何修改printf语句呢?之前printf语句

    的作用是输出wa,现在需要输出1~100,正巧变量a的值就是从1一点点

    增加到100的。我们只需在每次循环时把a的值输出即可,即把

    printf(wa);改为printf(%d , a);。完整的代码如下:

    include

    include

    int main

    {

    int a;

    a=1;

    while(a<=100)

    {

    printf(%d , a);

    a=a+1;

    }

    system(pause);

    return 0;

    }

    赶快尝试一下吧。

    如果我们想倒序输出呢,就是让计算机先输出100再输出99接着输

    出98、97、96、95、…、1,该怎么办?

    我们刚刚学过的“让计算机输出1~100”,就是让变量a从1开始,通过while循环把变量a的值每次都输出来,并且每次循环的时候将变量a的

    值增加1,这样就会打印出1~100。而此时的要求是从100打印到1。很

    显然我们需要让变量a从100开始,通过while循环把变量a的值每次都输

    出来,不过每次需要递减1,一直递减到1为止。代码如下:

    include

    include

    int main

    {

    int a;

    a=100; 初始值从100开始

    while(a>=1) 请注意这里的循环条件变为a>=1

    {

    printf(%d , a);

    a=a-1; 每循环一次将a的值递减1

    }

    system(pause);

    return 0;

    }

    问题又来啦,如果希望打印的是1~100中的偶数呢?自己想一想

    吧。

    怎么样,有没有思路?其实要输出1~100中的偶数,有很多种方

    法。比如之前变量a是从1开始的,之后每次在原有的基础上增加1,那么a就会从1到2再到3再到4……一直到101,当变量a的值增加到101时,不满足条件a<=100,就会退出while循环。现在我们可以改变一下思

    路,让变量a的值从2开始,每次增加2,这样变量a就会从2增加到4再增

    加到6……以此类推。代码如下:

    include

    include

    int main

    {

    int a;

    a=2;

    while(a<=100)

    {

    printf(%d , a);

    a=a+2;

    }

    system(pause);

    return 0;

    }

    好了,又到了尝试的时候了。

    如何让计算机打印1~100中能被3整除的数,你应该也会了,就是

    先将变量a的初始值赋为3,然后每次增加3。赶快再尝试一下吧。

    上面的写法虽然好,却不是万能的,假如不是输出1~100中能被3整除的数,而是输出1~100中所有不能被3整除的数呢?例如:1、2、4、5、7、8、10, …, 97、98、100,又该怎么办呢?不要着急,我们将

    在本章第3节彻底解决这个问题。

    一起来找茬

    下面这段代码是让计算机从100打印到200。其中有3个错误,快来

    改正吧!

    include

    include

    int main

    {

    int a;

    a=100;

    while(a<200) ;

    {

    printf(%d , a);

    }

    system(pause);

    return 0;

    }

    更进一步,动手试一试

    让计算机从1打印到100再打印到1,例如:1 2 3 …… 98 99 100 9998 …… 3 2 1。第3节 if对while说:我对你很重要

    在本章第2节中,我们学习了while循环的基本使用方法,但是遗留

    了一个问题,即如何让计算机输出1~100中所有不能被3整除的数,例

    如:1、2、4、5、7, …, 97、98、100。

    通过本章第2节的学习,我们可以很容易地让计算机打印1、2、3,…,100,只需让变量a从1开始每次增加1就可以了。如果想每次遇到3的

    倍数就不打印的话,我们只需在每次打印之前对变量a的值进行判断就

    好了,即当变量a的值是3的倍数时就不输出,否则就输出。那怎么判断

    变量a的值是否是为3的倍数呢?这就需要我们在第3章学习的if语句。我

    们只需要通过if语句来判断变量a的值除以3的余数是否为0就可以了。如

    果余数不为0,说明变量a中的值不是3的倍数,就将变量a中的值打印出

    来;否则就说明变量a中的值是3的倍数,不能打印。

    那么怎么判断变量a中的值除以3的余数是否为0呢?需要使用“%”这

    个运算符。在第3章中我们介绍过,“%”读作mod,也可以称之为“取

    模”,作用就是获取余数。另外说一下“%”这个运算符的左右两边必须为

    整数。而“”这个符号表示除号,作用是获取商,“”运算符的左右两边

    既可以是整数也可以是小数。代码如下:

    include

    include

    int main

    { int a;

    a=1;

    while(a<=100)

    {

    if(a%3! =0)

    printf(%d , a);

    a=a+1;

    }

    system(pause);

    return 0;

    }

    赶快尝试一下吧。如果要输出1~100中能被3整除但是不能被5整除的所有数,又该怎

    么办?

    这个数是3的倍数但不是5的倍数,也就是需要变量a除以3的余数为

    0并且除以5的余数不为0。这里的逻辑关系“并且”在C语言中的表示方法

    我们在第3章已经学习过,用“”表示,代码如下:

    include

    include

    int main

    {

    int a;

    a=1;

    while(a<=100)

    {

    if(a%3==0 a%5! =0)

    printf(%d , a);

    a=a+1;

    }

    system(pause);

    return 0;

    }

    更复杂的来啦!

    你有没有和同学玩过一个游戏——大家围成一圈,从1开始报数,但是每逢遇到7的倍数或者末尾含7的数,例如7、14、17、21、27、28

    等,就要拍手并且不能报出,谁出错了,谁就要受到惩罚。

    现在我想知道1~100中有多少这样的数,请你写这样一个程序,输

    出1~100中所有7的倍数和末尾含7的数。

    很简单,我们先参照以往的程序,利用while循环,让变量a从1递增

    到100,不过我们每次在输出变量a的值之前需要对变量a进行判断。根

    据题目的要求,如果变量a的值是7的倍数或者末尾含有7就打印出来。

    判断一个变量是否为7的倍数我们已经很熟悉了,只需要判断变量a除以

    7的余数是否为0就可以,即如果a%7==0这个关系表达式成立就输出。

    那怎么判断变量a的值末尾是否含7呢?我们仔细想一想就会发现,末尾

    含7的数其实就是这个数的个位为7,也就是这个数除以10的余数为7。

    发现这个规律就好办了,即在a%10==7这个关系表达式成立时输出就可

    以啦。

    好了,现在有两个关系表达式a%7==0和a%10==7,分别表示这个

    数是否为7的倍数以及末尾是否含7。这两个式子是“或者”的关系,即只

    要有一个成立,就将这个数输出。这里的逻辑关系“或者”在C语言中的

    表示方法我们在第3章也学习过,用“||”表示,代码如下:

    include

    include

    int main

    {

    int a;

    a=1; while(a<=100)

    {

    if(a%7==0 || a%10==7)

    printf(%d , a);

    a=a+1;

    }

    system(pause);

    return 0;

    }第4节 求和!求和!!求和!!!

    在本章第2节中,我们已经学习了如何让计算机打印1~100,那如

    何让计算机求1~100中所有数的和呢?

    你可能会说,首项加尾项的和乘以项数然后再除以2,就可以了。

    没错,你可以这样做,但是如果求1~100中所有7的倍数或者末尾含7的

    数的总和,又该怎么办呢?

    在求1~100的和之前,我们先来解决如何求1+2+3的值。

    没错,你可以这样写:

    include

    include

    int main

    {

    int a;

    a=1+2+3;

    printf(%d, a);

    system(pause);

    return 0;

    }

    但是如果计算1~100中所有数的和也这样写的话,是不是太麻烦了呢?我们可以尝试另一种写法,代码如下:

    include

    include

    int main

    {

    int a;

    a=0; 想一想为什么a的初始值要为0呢?

    a=a+1;

    a=a+2;

    a=a+3;

    printf(%d, a);

    system(pause);

    return 0;

    }

    你可能会说这样写岂不是更麻烦……但是我们发现在上面的这段代

    码中,a=a+1;a=a+2; a=a+3;这三句话,基本思想是相同的,第一次加

    1,第二次加2,第三次加3。我们可以把这三个语句用a=a+i;来表示。

    然后让变量i从1到3循环就可以了。代码如下:

    include

    include

    int main {

    int a, i;

    a=0;

    i=1;

    while(i<=3)

    {

    a=a+i;

    i=i+1;

    }

    printf(%d, a);

    system(pause);

    return 0;

    }

    如果需要计算1~100的和,我们只需将上面代码中i<=3修改为

    i<=100就可以了,赶快去尝试一下吧。

    如果求1~100中所有7的倍数或者末尾含7的数的总和,又该怎么办

    呢?先来回顾一下刚刚才学会的求1~100中所有数的和的方法,代码如

    下:

    include

    include

    int main

    { int a, i;

    a=0;

    i=1;

    while(i<=100)

    {

    a=a+i;

    i=i+1;

    }

    printf(%d, a);

    system(pause);

    return 0;

    }

    在上面的代码中,变量i会从1到100每次递增1,然后每次将变量i的

    值累加到变量a上。这个变量i就像是一个搬运苹果的工人,刚开始只拿

    1个苹果,之后拿2个苹果,再之后又拿3个苹果……最后一次一下拿了

    100个苹果。

    变量a就像是一个很大很大的水果篮子,用来装这些苹果。每次拿

    来的苹果统统被装进篮子里面,第一次放1个苹果进去,第二次放2个苹

    果,第三次放3个苹果进去……最后一次放100个苹果进去。最后篮子a

    中苹果的总数就是1~100的和。所以我们最后输出了变量a的值,这就

    是答案。那么求1 ......

您现在查看是摘要介绍页, 详见PDF附件(6134KB,378页)