1感性认识计算机程序
本次课也许是计算机程序设计部分“最重要”的一次课程,在这次课程中,我们将通过一个例子,感受一个结论——“计算机程序 其实是对 人们思维过程的一个描述”;在此基础上,我们将立刻把自己放置于一个“计算机程序设计语言”的设计者的角度,去思考“如果让我们设计一门程序设计语言,我们将如何设计?” 进而,在我们给出关于这个问题的“抽象回答”的基础上,我们迅速地带领大家“快步走进C程序”,迅速了解在C程序设计语言中,都有哪些成分。在这次课的最后,我们通过一个例子,以“感性的方式”让大家感受了一下“什么样的程序是好程序”。 下面就让我们开始这次“最重要”的课程吧
在开始学程序设计语言之前呢, 我觉得有几件特别重要的事情, 想要当面告诉大家。第一件事情, 程序设计语言的学习,跟其他普通知识的学习, 有一点不同。你除了要学习关于这门语言的 知识以外,你还要学习如何使用这一门语言。 那么前者呢,属于knowledge, 后者呢,属于skill. Knowledge呢, 你可以通过听课,或者是看书的方法去获得。 但是skill只有通过训练才能够获得。
所以说, 在这个过程中,我希望大家能够不断地练习。那么,至少呢,要follow我们的作业。 那么其实呢,我们在coursera上所布置的作业的数量, 大概只有校内的作业数量的百分之三十到百分之四十。 所以说呢,我希望大家除了作业,还能够自己主动地找一些练习来做。 这是第一点。这是第一点,要注意练习。第二点, 在学习一门编程语言的开始阶段,一定要注意,抓大放小。
什么意思呢?要抓住那些我们感兴趣,对于推进我们的编程水平 真正有用的东西,而要放掉那些可能会不断纠缠住我们的细节。 那么,特别是在起始的这个阶段,这些细节呢, 会损耗我们的时间,抵消我们的学习兴趣,影响我们的学习热情。 那么关于这些细节的学习呢,我们完全可以放到后面去,到相应的章节里面, 我们去作专门的探讨。在初始的这个阶段呢,我希望大家能够放过它们。 抓住西瓜,放掉芝麻。抓大,放小。这是第二点。
第三点,那么在学习一门编程语言的起始阶段, 大家一定不要急于求成。一定要先从简单的东西 开始练习。先从模仿开始练习。 这就像一个孩子,他去学一门语言的时候,他甚至不知道那个字是怎么写的, 也不知道那个语法是什么,但是他可以把这个语言用得挺好。 那么在这个过程中呢,模仿起到了非常关键的作用。比方说,我们最开始阶段的作业, 不是让大家去写程序,而是让大家去抄程序。 我会呢,以图片的形式,提供一些程序给大家, 让大家把它抄写下来,pass了以后呢,通过我们的课程网站提交上来。
所以,在这个阶段,我希望大家沉住气, 多去练习那些简单的题目。 到后面你会感受到,其实,对于简单题目反复练习, 更有助于迅速提高我们的编程能力。 这是第三点。第四点,关于参考书。 由于版权等等的问题呢,我们在这里也不可能提供一个电子版的参考书给大家。 那么,怎么样选择参考书呢? 我有一个这样的原则。同学们呢,还比较认可。
那么,我们学习,由于接下来我们学习程序设计语言的时间是比较短的, 所以说,我们学习的东西并不复杂。那么,我们就不需要一个特别特别厚的参考书。 有的同学可能一上来就买来一本特别厚的参考书。 那么可能把这书读完就已经花了太多太多的时间。 所以我建议大家可以到书店里面或者图书馆里面 找一本最薄的,自己觉得它写得比较好的书, 拿来作参考。
Ok, 那么总结一下我想要告诉大家的四点。 第一点,学习一门编程语言, 不仅仅是要学习knowledge, 更重要的, 是要训练如何使用它。也就是训练你的skill. 第二点,在初始学习的过程,我希望大家能够抓大放小。 抓住主要问题,忽略那些有可能会纠缠住我们的细节。 第三点,我希望在这个过程里头,大家尽量多地去做简单的练习, 而不是难的练习。第四点,我希望大家能选一本比较薄的, 实用的参考书。 Ok,我希望我的这些建议呢,对大家来说是有用的。 而且呢,我也希望大家在这个过程里头能够学得开心,学得快乐。 Ok, 那就让我们开始吧!
2程序是你告诉计算机的话
这次课呢,对那些以前没有接触过写程序的同学比较关键,但是这次课并不难。 需要你掌握,或者必须 得记住的东西也没多少,因为它是一个感性认识。 所谓感性认识,就是说,我们知道程序是怎么回事, 大体它是怎么来的,就可以了。 不要一开始,别背上那么个负担,就是说,大家尽量的 尽量的follow 我,就可以了。 感性认识C++程序。我这写C++,其实每次写,写C++的时候,我心里都有点不对劲, 实际上是C++里头的C, 我这准确的写的话,应该是,准确感性认识C程序,可是呢,因为我们是整个是在C++的环境底下, 所以说,我们就写了一个这样一个名字,感性认识C++程序,也可以,因为C本身就是C++的一部分。
ok,什么是程序呢? 既然我们要认识C++程序,我们就必须知道什么是程序。 其实我觉得,通过前两次课,大家对什么是程序基本上有一个,有一个概念。 特别是,我们讲到了一个机器,就是ENIAK,还记得ENIAK吗?啊,就是J. Presper Eckert 和John Mauchly ,那两个人,他们构造出来的那个ENIAK,很大,特别特别大,对吧。 每次这个计算机运转之前,他们都需要干一个什么事儿来着?插线。 那插线的目的是什么来着?通过上一次课,我们知道了,电路 可以完成很基本的逻辑运算,不同的逻辑运算的组合可以完成复杂的运算, 对不对?
或者这句话反过来, 无论你这个运算多复杂,我都可以转换成基本的逻辑运算。 而且,每一个逻辑运算,我都可以用电路去实现。 所以我可以用不同的逻辑电路之间的这种连接去进行运算。 是吧,对不对,这是基本的一个,一个方式,ENIAK就是这样的。 它在你这个计算机运转之前,我必须得通过连线的方式,把不同的逻辑电路,给它连在一起; 设置好输入,所谓的输入就是是高电压低电压。 嗯,这边儿准备迎接输出。 最后把电一推,咣,那个机器,嗒、嗒、嗒,嗒,嗒,一段时间之后,就可以算出一个什么东西来。
啊,基本的这种运算。所以说,在这个概念里头,这台计算机算不算一个通用计算机啊? 就是,它它不是为了某种特定的运算,才去制造的。 确实,它是一个通用的计算机,对不对? 我通过组合这个逻辑电路,我就可以完成不同的运算, OK?ENIAK通过插线的方式,去编程。 实际上,这个编程的过程,就是对ENIAK去,去,去插线那么一个过程,对不对? 我必须得事、事先设计好,然后,当然,这、这个东西有点实在是太原始,不过, 它已经对编程作出了一个非常好的解释。
什么叫编程序啊?就是,给计算机设置好,它要运行的那些步骤。 把这些计算机,要你准备让它怎么去运行, 你把这个步骤给它设定好,这就叫编程了。 ok,那么现在的计算机,都是存储程序式计算机,又叫冯·诺依曼式计算机。 啊,那么存储程序式计算机比以前这个要先进很多了。 它怎么运算的?把程序存在某个地方 对不对,然后,你通过编程序的方式,干原来插线的那个事儿
对不对,这要方便的多嘛?所以说啊,总而言之 一句话,编程序无非就是告诉计算机,它应该干些什么。 所以说,程序, 什么叫程序?我们给它一个理解,人们用来告诉计算机应该做什么的那些东西,就叫程序。 我们写程序,无非就是要告诉计算机,它应该干些什么。 那么接下来问题来了,问题来了,要告诉计算机它应该干什么, 或者是,应该怎么做,那又有两个问题了 第一个,告诉计算机些什么东西,它才能运行呢? 我应该告诉,告诉它一些什么东西?就是内容是什么? 我应该告诉计算机的那些内容应该是什么?
对吧,我…我要,你比方说,计算机是智能体,我要对它说一段话, 它就会去、会去做的话,那么,这句话的内容是什么?应该包含哪些东西?这是第一个问题。 第二个问题,以什么形式告诉它呢? 它是懂汉语?英语?日语?德语? 到底懂哪个语言呀?对吧,我得确定好告诉它的形式。 我,我们要学编程,无非就是两种东西:一个,我们允许使用哪些内容来告诉它, 或者是说,我们要使用哪些内容。 除此之外,可能,它听不懂。使用哪些词汇。 再一个以什么形式告诉它?无非就是这样的,OK,现在,我们就来着力回答这两个问题 告诉一些什么样的东西,它才能够运行呢?现在我们做这么一件事情,把你自己的大脑当一台计算机。
什么叫当一台计算机呀?就是干一件事情: 接受一个输入,进行一段处理,最后给一段输出。OK,现在大家都把脑子清一下存啊, 内存清空,干一件事儿。 给你一个数列,请你,请你迅速的从这个数列里头找出 其中最大的数。 哪个? OK,你们怎么算的?噢,印象不深?再来一遍,再来一遍 请你找出 最小的数 确信了吗?给我一个确定的答案,计算机 计算机,啊,计算机运行的时候有这样的吗? 当运行一段程序,嗯,大概输出是什么? 稍等,我确认……有这样的吗?没有吧! 必须得确认,必须得确定无疑,才能告诉我,ok? 最大的是多少来着?84,对吧,嗯,然后最小的大概应该是,28,ok? 你觉得你在整个这个过程里头你是怎么去想的?
你先想想你怎么去想的,咱先别,别考虑什么编程的事,那些远着呢。 你怎么去干的这个事? 最简单的方法,想想我们干了些什么呢? 我要是把它说的稍微详细一点,我觉得,可能做了这么一些事儿, 首先把某一个数字取出来,当作临时的特别的数字。 特别的就是最大的或最小的,对吧? 我就把它当作最大的或最小的。然后呢,假设这个数字是最大或最小,然后呢, 拿这个临时的数字与其他的数字相,逐一相比较,对不对?逐一相比较,然后如果有比这个临时的数更大的, 我就把这个特别的数,这个,我认为是最大的数换成这个更大的数。 重复上述的过程,直到所有的数字全部都比较完毕。 最后剩下的,我脑子里面记下的临时的数字,就是那个最大的数。 对不对?
对吧,啊,这个过程很简单,我们,我们稍作回顾,你看啊,我假设: 我是,反正这些数我都要输入到脑子里头去,都要输入,你,你,你在运行这个程序的过程中,是不是每个数都,都看过,至少,对吧? 然后现在我假设78最大, 然后我就往下比,56、67、得得得,往后比,一比,比比比比。哎,到82了,82 比78大,ok,换,把这个数82,82然后再往下走,走走。 哎哟,就84了,对吧?ok,把它换成84,哎,这就是我们脑子里面干的。 是不是这么干的?对吧,至少这是其中的一种方法,对不对? 我没要求你想更复杂的方法,也许它更快也许它更慢,至少这个方法我们可以实现。
记住,记住,在我们这个课上,在咱们这个班上 写程序的效率不是第一位的,永远记住,我们不,第一位的 不要求程序的效率,除非有些特定的算法,它可以提高效率,我,我要求你记住这些算法就OK了。 当你写一个程序的时候,千万千万不要上来就想, 我应该怎么把这个程序写的更快,那不是第一位要解决的问题。 第一位要解决的问题是什么?我怎么样把这个程序写出来,把这个问题解掉, 无论你的程序多复杂,多少行,我从来不以程序的行数论英雄。 啊,程序的行数是没有、没有什么的,它的运行时间,只要你在有限的时间之内,能把它算出来,OK。
所以说,我们先不要管它的效率,我们就找一个办法去解决。 刚才那个办法就很好,我们就干了那些事儿,是这样的 你做了些什么呢?在脑子里边使用了一片存储空间 存入一个数字,存入数字,我之所以强调这个事儿 就是说,这件事情,通常大家都感觉不到,但对计算机而言 你不,你不告诉它,它就干不了这事儿,使用了另一个存储空间,存放那些特别的数字, 一片放输入的数字, 无论是一个,还是一堆,一个放临时的数字,就是两个存储空间, 按照某种规律,反复地选定存储空间中的数字,与特别的数字相比较,每次比较的时候判定, 选定的数字是否大于那个特别的数字? 如果大于特别数字的话,就把这个特别数字刷新一下。 那么,如果这个特别的数字与所有其他的数字都进行了比较,
OK,把它说出来。 你看你最后告诉我,那个数字是多少,ok。我把这个成,我把刚才这些事儿,换一种写法,首先,只要在有限时间算出来,不要一上来就追求效率,先解决它,再学算法把效率提上来。稍微的规整规整一下,规整一下,在你的大脑里开辟一片存储空间,存入输入的数字。 假设说,那些数字我们都能记住,开辟一片存储空间把它们放进去。 第二个,开辟另一片存储空间来存放的特别的数字。 这个时候,你实际上脑子干了一件事儿,向大脑皮层发一个信号,申请一片空白的 对吧,开辟一片存储空间,从存储空间中的,那片大的存储空间的第一个数字开始, 直到最后一个数字,反复进行以下操作,什么操作呢?比较存储空间的 数字与特别的数字,如果存储空间的数字大于特别的数字, 那么,就把这个特别的数字转化成存储空间中的找出来的那个数字。
最后 最后反复进行以下操作,我问你 这个操作完了之后,到这,是不是已经能够找出那个临时空间里的数字是不是就是 那个最大的了,对不对?经过这个逻辑之后,经过这个 逻辑之后,那个存储里一定是最大的。ok,说出那个特别的数字 这就是我们干的事,这就是我们干的事。有输入 有输出,有判断,有循环, 看了没?那个程序里头,有判断,判断大小, 有循环,还有什么吗?
赋值,什么叫赋值呢?就是把一个数给 另外一个数,我如果发现一个数字更大,我就把它给,赋值给,让那个特别数等于它 我就干了这么一件事儿,对不对? 如果要给我们一台计算机,我们要写一段程序 给它的话,无非也是这样干。 对不对?无非也是这样干,只不过我换一种语言就是了,对不对? 只不过我换一种描述 语言就是了,我现在直接就把这个程序给你,你看你能看得懂多少,你看你看得懂多少,基本上就算 看不懂它是什么意思,我能猜个八、九不离十, 我先把它看一边,从头到尾看一遍,然后我们再来说,再来解释一下。
OK,咱们来看一下这个程序啊。 首先,这个写程序是一个特别特别有意思的事,有些东西你闭着眼就 开始写就行 例如,前四行,前四行你只要开始写个程序,先把前四行抄上,我 建议你把最后一行也写上,在程序里头,这个大括号的对应关系 是很重要的,所以说你在写了前面的那个大括号的时候,你就立刻 跟上一个后面的大括号,然后在它的中间,它俩中间再开始写,要养成这个 习惯,我现在程序的主要的部分,反正前四行所有的程序都一样,这是 为了引导程序去执行的,说明我这个程序 从这个地方,这个大括号这,从这个地方开始执行,就是 你把东西准备好,
我要从这开始执行,第一个,int number[45] 这句话,实际上是干了一件什么事,告诉计算机,你给我 一片存储空间,我要把这些数字给你 是不是啊?在计算机里头开辟一片存储空间,来存储 这些数据,然后定义了一个临时的数字, max,max是一个临时的数字,最开始的时候,我默认max 是零,然后接下来我做的一件事情就是,反复地拿一个数 跟max比,对不对?反复地拿max比,那一共反复 多少次呢?有多少个数,就比多少次?有45个数,所以说下面有一段程序 看这个啊,用这两个大括括着的,for,用for开头 实际上这是一个什么?
大家可以猜一下,这肯定是一个反复进行的,这是一段循环,我不要求 你记住啊,不要求你记住,你只要记住这是一个循环,就OK了,不要求你知道每一句话是什么含义,然后呢,它这里边有一个 零到45,从0一直循环到小于45, 也就是44,对于这个区间里面的每一个数字 所代表的一次循环,我都干一件事,叫if (number[i] > max)的话,我就把max换成我找到的 这个数,这是不是,刚才我们说的那个过程啊 对不对?等这个循环全部进行完的时候,我就可以输出,c.out,这是输出的用法,等一会 我们会讲它,“The Maximal Number is ”,什么,这段程序结束了,最后return 0 表示程序结束,
其实这个程序里边固定的一共有 6行,因为return 0也基本上可以固定,其他的东西是你自己写的, 大体能看明白了吧?OK,这是我们要 看的这段程序,有,有几个小问题,我希望这个问题先不要困扰大家,一个小问题就是说,有的同学说 哎,你不是说从1到45嘛?你干嘛从0到45,先数数个数,从0到44和从1到45,是不是一样的? 啊,只不过有一个界定,就是,number,它是个数组,这个数组里头呢,不能出现最大的数 你比方说,我在这写,if ( number [45]〉) ,那就错了,这是程序里面约定的,我们不去管它,小问题,不要被这个 小问题所困扰着,现在我提两个大问题,提两个大问题。
3如果你的大脑是台计算机
现在我们做这么一件事情,把你自己的大脑当一台计算机 什么叫当一台计算机啊,就是干一件事儿 接受一个输入,进行一段处理,最后给一段输出 ok,大家现在都把脑子清一下存啊,内存清空,干一件事,给你一个数列 请你,请你,迅速的从这个数列里头找出 其中最大的数 哪个啊?OK 你们怎么算的?噢,噢,印象不深再来一遍 再来一遍,请你找出最小的数 。
哈哈 确信了吗?给我一个确定的答案 计算机,计算机,啊,计算机运行的时候 有这样的嘛?当,运行一段程序,唉,大概 输出是什么,稍等,我确认,有这样的吗? 没有吧?必须得确认,必须得确定无疑才能告诉 我,OK,最大的是多少来着,84,对吧?恩,最小的大概应该是 28,你觉得你在整个这个过程里头 你是怎么去想的,你先想想你怎么去想的,咱别,别考虑 什么编程的事儿,那些远着呢,你怎么去干的这个事儿,最简单的办法 想想我们干了些什么呢?
我要是把它说得稍微详细一点,我觉得可能做了这么一些事儿 首先,把某一个数字取出来,当作临时的 特别的数字,特别的就是最大的或者最小的 对吧?我就把它当作最大的或着最小的,然后呢,奥,假设这个数是最大或最小的,然后呢 拿这个临时的数字与其它的数字相,逐一相比较,对不对,逐一相比较,然后如果有比这个临时的数更 大的,我就把这个最大的,我认为最大的数换成更大的数,啊,重复上述 所有的过程,直到整个所有的数字全都比较完毕,那么最后剩下 的,我脑子里面记下的这个临时的数字,就是那个最 大的数,对不对?
对吧,啊,这个过程很简单,我们,我们稍作回顾,你看啊,我假设 我是,反正这些数我都要输入到脑子里头去,都要输入到,你,你,你在运行这个程序的过程中,是不是每一个数都,都看过,至少都看过,对吧? 然后,我现在假设78最大,然后我就 假设78最大,然后我就往下比,56,67,的、的、的,。。往后比,一比,比,比,比,哎,到82了 82比78大,ok,换,把这个数82,82然后再往下走,的、的、的。
哎呦,就84了,对吧,ok,把它换成84,哎,这就是我们脑子里面 这么干的,是不是就这么干的,对吧?至少这是其中的一种方法 对不对,我没有要求你想更复杂的方法,也许它更快也许它更慢,至少这个方法我们可以实现 记住,记住,在我们这个课上,在咱们这个 班上,写程序的 效率不是第一位的,永远记住,我们不,第一位的不要求 程序的效率,除非有些特定的算法,它可以提高效率,我,我要求你记住这些算法就OK了。
当你写 一个程序的时候,千万,千万不要上来就想,我应该 怎么把这个程序写得更快,那不是第一位要解决的问题,第一 位要解决的问题是什么?我怎么样把这个程序给写出来,把这个问题 解掉,无论你的程序多复杂,多少行,我从来不以程序的行数 论英雄,啊,程序的行数,是没有、没有、没有什么的,它的运行时间,只要你在有限的时间之内能把 它算出来,OK,所以说我们先不要管它地效率,我们就 找一个办法去解决,刚才的那个办法就很好,我们就干了那些事儿,啊,是这样的,你做了些什么呢?
在脑子里边使用了一片存储空间,存入一个数字 存入数字,我之所以强调这个事儿,就是说, 这件事情,通常大家都感觉不到,但是对计算机而言,如果你不告诉它 不告诉它,它就干不了这事儿,使用了另一个存储空间存放那些特别 的数字,一片放 输入的数字,无论是一个,还是一堆,一个放临时的数字,就是两个存储空间 按照某种规律反复的选定存储空间中的数字,与特别的数字相比较
每次比较的 时候,判定,选定的数字是否大于那个特别的数字,如果 大于特别的数字的话,就把这个特别的数字刷新一下,那么 如果这个特别的数字与所有其他的数字都进行了比较,ok,把它说出来,你看你最后告诉 我,那个数字是多少,ok,我把这个成,我把刚才这些事换一种 写法,稍 微的归整、归整一下、归整一下,在你的大脑里开辟一片存储空间,存入输 入的数字
假设说,那些数字我们都能记得住的,开辟一片存储空间把它放进去,第二个 开辟另 一片存储空间,来存放特别的数字,这个时候,你实际上,你脑子干了一件特别的 事,向大脑皮层发一个信号,申请一片空白的,对吧? 开辟一片存储空间,从存储空间中的,那片大的存储空间中的第一个数字开始, 直到最后一个数字,反复进行以下操作,什么操作呢?比较存储空间的数字与 特别数字,如果存储空间的数字大于特别的数字,那么 就把这个特别的数字转换成存储空间中的找出来的那个数字 最后
最后反复进行以下操作,我问你,这个操作 完了之后到这,是不是已经能够找出那个临时空间里的数字,是不是就 是那个最大的了,对不对? 经过这个逻辑之后, 经过这个逻辑之后,那个存储空间的数字一定是最大的,ok,说出那个特别的数字,这就是 我们干的事儿,我们干的事儿,有输入,有输出 有判断,有循环 看了没,这个程序里头,对吧,有判断,判断大小,有循环, 还有什么?
有赋值,什么叫赋值呢,就是把一个数 给另外一个数,我如果发现一个数字更大,我就把它给,赋值给 让那个特别数等于它,我就干了这么一些事 对不对?如果要给我们一台计算机,我们要写一段程序给它的话, 无非也是这样干,对不对? 无非也是这样干,只不过我换一种语言就是了 对不对?只不过,我换一种 描述语言就是了,我现在直接就把这个程序给你,你看你能看得懂多少,你看你能看得懂多少,基本上 就算看不懂它是什么意思,我能猜个八九不离十,我先把它看一遍,从头到尾看一遍, 然后我们再来说,再来解释一下
ok,ok,咱们来看一下这个程序啊 首先,这个写程序是一个特别特别有意思的事,有些东西你闭着眼 就开始写就行,例如 前四行,啧,前四行,你只要开始写一个程序,先把前四行抄上 我建议你把最后一行也写上,在程序里头,这个大括号的对应 关系是很重要的,所以说,你在写了前面那个大括号的时候,你就立刻 跟上一个后面的大括号,然后在它的中间,它俩的中间,最开始写程序 要养成这个习惯
我现在程序的主要的部分,反正前四行所有的程序都一样 这是为了引导程序去执行的。说明我这个程序 从这个地方,这个大括号这,啊,从这个地方,开始执行 就是你把东西准备好,我要从这开始执行,第一个Int number[45] 这句话实际上是干了一件什么事儿,告诉计算机,你给我一片存储空间 我要把这些数字给你,是不是? 在计算机里头,开辟一片存储空间, 来存放这些数字,然后,定义了一个临时的数字 max,max是一个临时的数字,最开始的时候默认, max是0,然后接下来我做的一件事情就是,反复的 拿一个数跟max比,对不对?
反复地拿max比,那一共反复多少次呢? 有多少个数,就比多少次,有45个数,所以说,下面有一段程序, 看这个,用这两个大括号括着的,for,用for 开头的,实际上这是一个 什么?大家可以猜一下,这,这肯定是一个反复进行的,这是一段循环 我不要你求记住啊,不要求你记住,你只要知道,这是一个循环,就OK了,不要求你知道每一句话是什么含义,然后呢,它这里边有一个0 到45,唉,从0一直循环到小于45,也就是 44,对于这个区间里面儿的每一个,每一个数字, 所代表的一次循环,我都干一件事儿,叫if (number[i]>max)的话,我就把max换成我 找到的这个数儿,这是不是刚才我们说的那个过程啊?
对不对?等这个循环全部进行完的时候,我就可以输出,cout,这是输出的 用,用法,待会我们会讲它,the maximal number is 什么,这段程序结束了,最后return 0,表示程序结束,其实这个程序里边固定的,一共有 6行,因为是return 0,也基本上被固定 啊,其他的东西是你自己写的,大体上能看明白了吧,ok,这是我们要看的这段 程序,有,有几个小问题,我希望这个问题先不要困扰大家,我们,一个小问题就是说,有的同学说,哎, 你不说,从1到45吗?你干嘛从0到45,先数数个数,从0到44和从1到45, 是不是一样的?啊,只不过有一个界定,就是这个number是一个数组,这个数组里头呢,不能出现最大的 数,你比方说,我在这写if( number[45] >),那这就错了,这是程序里面约定的,我们 不去管它,小问题 不要被这个小问题所困扰着,现在我提两个大问题,提两个大问题
4如果你来设计一门编程语言
Ok, 那接下来呢,就让我们来考虑几个大问题。 那在考虑这几个大问题之前呢,我想给大家提个要求。 我现在啊,希望大家不要站在一个学习 程序设计语言的这么一个角度。 也不要站在一个使用程序设计语言的这么一个角度。我希望大家能 把自己啊,当作一个程序设计语言的设计者。 也就是说,如果你想要创造一门程序设计语言的话, 你应该怎么去思考底下的这几个问题。 好,我们来看第一个问题。第一个问题呢,是说 既然在程序里面有各种各样的 “词”,那是不是无论我们在程序里边写什么样的“词”, 或者是写什么样的 “单词”,计算机都能明白呢?看我们刚才的这个程序, 这个程序里头有各种各样的 “词”,
比方说, “int”, 比方说,“for”, 比方说,“if”, 比方说 “return”,这是这个程序里边出现的 “词”。 那,是不是写什么“词”,这个计算机都能明白呢? 这是第一个问题。我们先看问题,待会儿再给大家答案。 第二个问题。 那是不是无论我们在程序里边写什么“数”, 和 “计算符号”,计算机都能明白呢? 比方说在刚才我们的程序里头,出现了很多 “数”, 那很幸运,在这个程序里头,出现的都是整数,而且都是两位的十进制整数。 那,这个程序里边能写 “小数“ 吗?能写"分数“ 吗? 能写 “负数“ 吗? 那是不是写,写这些 “数” 计算机能明白吗? 哪些 “数” 是能明白呢? 同时,在这个程式里头也出现了很多的运算符号,比方说,“等号”, “小于号”,“大于号”, “加加号”,等等等等。 那是不是写什么运算符号,计算机都能明白啊? 这是第二个问题。
第三个问题更重要。 是这样的,在这个世界上啊, 我们想要用程序来表达的这种逻辑, 千千万万,纷繁复杂, 我们想让计算机去做一些事情,那么我们就要向计算机去描述,怎么去做。 你可能要让它做这件事情,你也可能要让它做那件事情。 不同的事情可能要用不同的逻辑去描述。 那比方说在这个程序里头,如果我们想表达,轮流不断的去做一件事情,我们用的是 “for”, 这样的一个 “句式” 。如果我们想表达,“如果” ,某个条件成立的话, 我们要做一件事情,我们用的是 “if" 的 “句式”。这些呢, 都是用来告诉计算机的 “句式”。 它们表达的都是某种逻辑。 那么这个世界上可能要用程序来表达的逻辑,纷繁复杂。 那程序设计语言里面得有多少种这种 “句式” 才是足够的呢?
总结一下,这个问题就是说,这个世界上呢可能要用程序 来描述的那种逻辑啊,纷繁复杂, 那程序设计语言里面得设计多少种的“句式” 才足够让我来用它们描述各种各样纷繁复杂的逻辑? 哇,这是一个很大的问题。很坦诚的跟大家说,这个问题啊, 是我刚刚开始学程序设计语言的时候啊, 心里面特别大的一个问题。疑惑了好久,后来才找到答案。 那么这三个问题呢,就是我想让大家站在一个程序语言设计者的角度, 来考虑的三个问题。 那么下面呢,我们就来逐一的作一个分析。 Ok, 我们先来看第一个问题。 是不是无论我们在程序里面写什么单词,计算机都能明白?按照常理来想一下我们就知道, 肯定是 “No"。肯定不是说我们写什么东西,都能够明白的。
那如果是你的话,你来设计一门程序设计语言的话,你会怎么做呢? 我估计每个人都会想到这个。我肯定是要定义一些单词啰。 其实呢,如你想象,程序设计语言里头,就是这么做的。 那么程序设计语言定义了一些有特定含义的 “关键字”。 计算机呢,最初的时候只能明白这些简单的 “关键字”。 那紧接着有一个问题了。那多少个关键字呢? 那是不是要定义很多很多 “关键字” 才可以呢? Ok, 我现在就告诉大家,其实不多,非常不多。
计算机最初能够认识的单词啊, 也就是这么三十几个。 这三十几个词啊,在C++程序设计语言里头,都有某种确定的含义。 被保留使用,不能随便用。比方说,这里面出现了我们知道的 “if", “for”, “return”, 都出现在这个里头了。这都是我们刚才看到的。 这是计算机最初能明白的这些词。 那有的同学又可能问了,老师,不对啊。刚才的程序里头我看到了很多词啊。 哪些词是怎么回事啊?我说那个程序啊,可能还不够多。我们看这个程序。 啊,这个程序里面所有红色的词,都没有出现在刚才这个列表里头。 都没有出现在这个里头。那是怎么回事呢?
我可以告诉你。 所有这些红色的词都是用刚才的那些词给定义出来的。 也就是说,我们用刚才的那些词来解释这些红色的词是什么含义。 也就是说,我们可以用一个,通过一个少量的词来定义一个多的词。 这就是程序设计语言的做法。Ok, 再来看第二个问题。 那是不是无论我们在程序里边写什么 “数” 和 “计算符号”,计算机都能明白呢? 啊,我们想象一下,也就知道,这个答案也是肯定是不能随便写的。 那应该怎么办呢?如果让我们设计程序语言的话,我们也会 去定义一些计算机能认识的 “数“ ,和 “符号”。 比方程序设计语言里头就是这么做的,让计算机啊只能看懂某些类型的数据, 那么这些数据的 “类型” 和相应的 “操作符号”啊 也是被事先定义好的。
你看, 它跟我们的想象的是一样的。所以啊,我非常喜欢一句话, 就是说,只要你客观的观察这个世界,你会发觉它是如此的简单, 以至于,像我们所想象的那个。正因为如此,我们的思考才有价值。 Ok, 回到这个问题。那既然我们定义了某些数据类型和操作符号,那哪些数据类型呢? 是不是要定义很多啊?其实不然。计算机里头啊, 能够看懂的数据类型也就这么多。一共有十几种吧。 不多。
我们来看一下,比方说,有布尔型,字符型,整型, 浮点型或者叫实型,就是小数,它又分了单精度型,双精度型, 这就是数组型,指针型,结构体型,联合体型,枚举型。 当然,在每个对现的部分,也可以定义 “类”。 那么除了这个之外呢,还有一种类型叫“空类型“。一共就这么十几种。 大家不需要记,只需要有一个感性的认识就可以了。 这是数据的类型。那操作符呢?运算符号呢? 计算机在C++语言里头能够使用的运算符号,也就这么多。
一共有三十几个吧。C语言中的运算符啊, 已经是,相比其他语言来说啊,已经是非常强大的了, 但它也只有三十几个。这是第二个问题。我们再来看,那个难度最大的,第三个问题。世界上要用程序语言来表达的逻辑纷繁复杂, 那程序设计语言里面得设计多少种 “句式” 才能够用呢? 那这个问题啊,困扰了我好久。 那现在呢,我就先给大家作一个解答。 其实啊,在程序设计语言里面,你用来表达逻辑的 “句式” 啊, 一点也不多,三种而已。 哇!怎么这么少啊,有的同学说。对,只有三种。哪三种呢?
看这个图。“顺序”,“分支”, “循环”。就这三种语句。 刚才我们在程序里头看到的那个 “if” 语句,它就属于 “分支” 语句。 看到的那个 “for” 语句,那就属于 “循环“ 语句。 那些顺着写的语句统统属于 “顺序" 语句。 “顺序”,“分支”,"循环”。有的同学可能就问了, 这三种语句这么简单, 它们能表达得了那么多纷繁复杂的逻辑吗? 它够用吗? 我曾经跟你说过,我也有一样的问题。 那后来呢,随着学习的深入,我找到了答案。 其实,这个问题在1966年的时候,有两个学者, 在 Communications of the ACM, 这是一个非常著名的期刊。在这个期刊上,发表了一篇 Paper。 这个 Paper 呢,已经证明了,这三种语句是足够的。
Ok, 那么后面呢,我们还会讲到这个问题。 所以说, 在这儿,你只要有一个印象就可以了。 Ok, 我们现在解答了这三个问题以后呢,我们再来看一下我们要学的这门语言, 其实呢,我们要学的这门语言还蛮简单的。 它无非就是包含了30几个关键字,十几种基本数据类型, 30几个运算符号,加上三种最基本的 逻辑语句。就这些东西。 是不是很简单啊?如果你觉得简单,那就好了。 我们很快就可以开始写程序了。
5快步走进C程序之一
Okay,经过刚才这个介绍啊,我相信大家体会到写程序啊,并不是一件特别困难的事情, 那么我希望大家能有这种感觉,那么为了尽快的让大家开始能写一些程序, 那我呀在这先把一些最关键的事情告诉你,那么我们先来看一个 最简单的程序。有的同学说hello world不是最简单的程序吗, 这个程序比hello world还要简单。
这个程序里头呢一共包含了6句话, 其实呢,这个程序,其实呢这6句话是在我们这个课上 所有写的程序里面必不可少的6句话。也就是说啊 当你想编写一个程序的时候,你可以先把这6句话 COPY到你的编程的环境里头,然后接下来 在这个地方,这块区域里头,当然你可以很大了。 再去写你自己的那些程序。它是必不可少的。 那前面的这4句话呢,其实是用来引导执行你的程序的。 那么后面的这句话呢,是表示程序执行完毕了。这是最简单的程序。
这样的一个最简单的程序也是可以运行的。那你可以把这个程序COPY下来, 放到你的编程工具里头去编译,然后呢运行。 那关于编程工具的安装和编译运行呢, 我们的助教已经做过一个视频了。我在这儿就不赘述了。那这样的一个程序运行的结果呢 就是这么一个黑框框,因为它没有任何的输出。所以说它输出来是没有东西的。 那在这个最简单的程序的基础上呢我们还可以添加语句, 比方说在这儿,我们在刚才的这六句话的基础上啊,又 添加了两句话,这两句话。
那么第一句呢叫做 int a = 0。那这句话是什么意思呢?这句话啊,定义了一个 变量。这个变量的名字呢,叫a。定义了一个名称为a的变量。 那什么叫变量呢,其实变量啊,就相当于我们以前做的数学应用题里面 设的未知数一样。像我们以前的应用题里头我们都是设x为什么什么什么, y为什么什么什么,对吧,这里的x 和y呢就相当于我们所说的变量了。这就是变量的基本的含义。 那么变量呢是有类型的。这儿定义的变量是什么类型呢?int型, 就是整数型。那么在定义这个变量的时候我还让它等于0,也就是说啊, 我希望我所定义的这个变量最开始的时候,最初的时候有一个初始值, 这个初始值呢,是0,这是这句话的基本的含义。 那通过这句话呢我们就可以知道定义一个变量怎么去定义啊, 就是把变量的类型写在前面。
那通过这句话呢,我们就可以知道了 那定义一个变量的时候怎么去定义啊,就是把变量的类型 写在前面,把变量的名称写在后面,然后呢给它一个初始值。 给它一个初始值,这就是定义变量。那在这儿呢我们要插一句。有的同学可能要问了, 那我定义变量的时候啊,我能不能不去写这个等于0,也就是说不给它赋初始值。 可以吗?在语法上讲是可以的。但是在定义变量的时候并且赋予初始值是一个 非常好的习惯。我们要尽量的养成这样的习惯。 我们以后每次定义变量的时候都赋予一个初始值。那么底下这句话是什么意思呢? cout<<a<<endl;这是什么意思呢?我们来解释一下。
这句话的意思啊,是要把这个变量的值输出到屏幕上, cout表示一个输出的命令,你可以这么理解, <<你可以把它当做分隔符,后面呢,就可以写上你要输出的这个变量了。 再给一个分隔号,最后写一个endl,这个endl的意思是表示 换行,也就是我们输出完了 a以后啊,换到下一行,便于我们输出其他东西。 这就是这句话的含义。那么它的执行结果呢,就是这样一个结果。 既然我们定义了一个变量a=0,然后又把a打印出来当然我们会打印0出来。 然后呢打印完了之后光标换到下一行,光标在这儿闪烁,那 有的同学问了,我能不能使用cout语句用来输出文字,而不是只是输出变量呢? 当然可以。我们来看底下这个程序。
仍然定义了a,仍然初始化为0,然后cout我 在这儿写,我想输出a的值,然后呢把a的值放在这,这些呢都用分隔号 给它分隔开,那么这样的话,程序的执行结果就变成了这个了。我想输出a的值,0 变成这样一个结果。这里呢特别需要大家注意的, 你想输出的这些文字必须要以双引号 给它引起来才可以。否则的话就要出错。
而且这个双引号必须是英文字符。 那有的同学说你这是输出,我能不能输入呢, 当然可以。我们再来看一个程序。这个程序在刚才的那个程序的 基础上又多增加了一句话。又多增加了几句话。 第一个我们仍然定义了一个变量,最后呢仍然采用了这个办法,把这个变量输出出来。 所不同的是呢,中间增加了两句,第一句cout请输入一个数,我相信同学们都知道这句话- 的意思了, 打印出来。那底下紧接着cin a,而且是 >> a,这个是做什么呢?
这就做了一个 输入的操作。输入。也就是说我们要从键盘上输一个数, 然后呢这个程序会把这个数给a,底下cout我刚刚输出的数是a, 把a再打印出来。那么我们可以想象一下这个程序的执行结果它应该是这样的。 那么第一行请输入一个数,对应的这,请输入一个数。我输入的数是 1,2,3,我就在键盘上敲1,2,3回车,然后呢执行到这一句,我刚刚输入的数a是 1,2,3,这就是这样一个结果了。那这个程序呢就告诉我们 当你想输入一个数的时候你可以用这样一个命令,你可以暂时理解为命令, 那么你可以用这样一个命令,然后加一个>>,然后如果要输入到哪个变量里头你就把哪个变- 量的名字写在这里。 这就是这个程序的含义。那有的同学说,哎呀你这一个一个的输入,我想一次输入多个数, 可以吗?
当然可以。我们看这个程序。在这个程序里头呢我一下定义了3个变量, a,b,和result。这个是可以的。中间呢,注意要用逗号分隔开。 一次定义多个变量的时候中间用逗号分隔开。每一个变量呢我们都给它赋予一个初始值。 然后输出一个提示,please input two numbers,然后呢我们cin两个数, 先输入一个数给变量a,然后再输入一个数给b,可以连着写。 一次输入多个数。然后接下来呢我们做了一个运算。 result=3a-2b+1,这是一个算式了,我们就直接把它写在这里。 那么最后cout result is把result输出出来,然后endl换行。 这是这个程序。
通过这个程序我们可以知道,我们可以一次输入多个数。 当然我们在定义变量的时候我们也可以在一条语句里面写多个变量的定义, 而且呢,我们可以通过这种方式来进行计算。 也就说,这些像我们写一个普通的式子一样,我们可以通过这种方式啊 让它来帮我们算数。Okay,那这个程序的执行结果呢 就是这样的。先输出一个提示,please input two numbers, 然后呢这个时候你就可以在键盘上输入两个数,我输入的呢是 3,2,1和1,2,3.注意,中间用空格给它隔开, 这表示是两个数。那么只要你一敲回车,程序呢就可以读到这两个数, 然后把3,2,1送给变量a,把1,2,3送给变量b。 那么最终运算的结果呢是718,把它输出出来,这就是result的这个结果。 这是这样的一个程序。
那有的同学说了,林老师在你的程序里头定义的都是int型的变量。 那我能不能定义其他类型的变量呢?当然可以。我们来看这个程序。这个程序呢,第一句 float a=0,b=0,temp=0,在这句里头呢我们一下定义了3个变量。 a,b,和temp,初始值都是0,我们定义它的类型为float型, float型是实型,它意味着呀a,b,和temp可以是 实数。也就是说,a,b,和temp可以用来存储小数。 然后呢我们提示一下请输入两个数a和b, 然后从键盘上读入两个数a和b,然后输出一下,确认一下这两个数,然后接下来 做了一个操作,这个操作是这样的,先把a给了temp,然后呢又把b给了a。 然后呢再把刚才保存下来的这个temp给b,这是做了一件什么事情啊,
a,b,temp,三个变量,先把a给了 temp,然后呢把b给了a,然后呢又把temp给了b,这是 做了一件什么事情啊,是不是把a和b借助于 temp进行了一个互换啊,把这两个变量的值 进行了一个互换。那换完了以后呢打印出来cout,a=a,b=b, 看看是不是互换完毕了。Okay,我们来看一下这个程序的运行结果。首先提示这儿, 提示输入a和b,那我输入的是3.14159 空格,然后2.71828, 这是我的输入。那么经过这个输入以后呢程序就把 3.14159给了a,把2.71828给了b, 然后接下来呢a、b通过temp进行互换, a就等于了2.71828,b就等于了3.14159,这是这个程序的执行结果。 那么我们可以看到这个程序里头没有用到任何的 复杂的逻辑,那所有的语句呢,都是顺序书写的, 每一个语句呢都是以一个分号来结尾,它们之间都是顺序来书写的。 所以说我们把它称为顺序结构。
6快步走进C程序之二
Okay,接下来我们再看一个不太 一样的程序,啊,看这个程序,那么我们阅读一个程序呢,总是从上往下开始这样顺序 来阅读的,我们来读一下这个程序,首先定义了两个变量,int型的变量 x 和y,然后呢,我们从键盘上输入x和y 然后接下来有个语句,叫做if ( x > y),cout max number is x,else cout max Number is y 猜猜它是什么意思,
如果x大于y的话,那么大的数就是 x, 否则的话,这个大的数就是y,这就是这个程序的含义,在这儿呢我们用了一个非常简单的 判断语句,判断,恩,判断句呢,属于一种 分支语句,它是属于分支语句的一种,大家如果想写判断语句的话呢,可以 仿照这个来写,那么if是一个关键字,这后面呢有一个 括号,写入 一个条件,那么if满足这个条件的话,就执行if 后面 的这句话,一直执行到分号else ,否则的话,如果不满足这个条件,那么我就执行这一句 一直执行到分号。
这是这样的一个结果,我们来看一下这个程序的执行 结果,首先,在键盘上读入两个数,一个x,那我输入 是123,一个呢,是y,是321,恩,那这样中间以空格隔开 执行完了以后呢,123就给了x,321就给了y,然后 继续执行,if ( x>y), 那x大于y吗,这个时候 因为x等于123,y等于321,所以这句是不 成立的,嗯,所以我不执行它,执行哪个呢,else 否则的话,恩,那我就是执行这句了,cout max Number is y
所以说,这个max number is y,就是 321 啊,这样打印出来,这是这个分支语句,这就是简单的分支语句 那有的同学说,这个程序太枯燥了,那我们来看一个有意思的 分支语句,那ok,我们来看一下这个程序,那这个程序呢,是一个非常简单的小游戏 一个什么游戏呢,
我在这个程序里呀,隐藏了一个字母,比方说是:G 啊,这个字母,那么我就想让你呢从键盘上输入一个字母,来猜一下,我隐藏的到底是哪个字母 为了让大家更清楚这个程序的功能呢,我们就来,先来看一下它的输出结果,那,这个程序运行起来以后呢,首先,会打印出来一行字 猜猜我是哪个字母,然后呢,你就可以输入一个字母,比方说,我输入的是 a,它就反馈,啊,你猜错了,如果我输入的是 大写字母G的话,它就会说,被你猜中了,恩,就是这样的 恩,在清楚了这个程序的功能以后呢,我们就来看一下这个程序是 怎么写的,首先啊,我们定义了一个 变量,这个变量呢,叫a,跟以前的变量不同的是呢?这个变量的类型啊,是 char类型,所谓char类型啊,就是字符型
字符型,那字符型的特点呢,就是说,它可以用于存储 一个字符,一个字符,啊,不能存储多了,它只能存储 一个,比方说,在这个程序里头,在刚刚定义了a之后呢,我们就给它做了一个初始 化,赋予了一个最初的值,大写字母A,需要注意的就是,大写字母A呢,要以 单引号把它引起来,啊,这就是给一个字符变量赋值的时候呢,这个值必须要以单引号把它引起来。
大家要注意 然后呢,输出一行提示,啊,猜猜我是哪个字母 然后呢,我们要求从键盘上读入一个字母进来,把它赋给 a,恩,还是用cin,一样的格式,那么cin 呢,读入一个字符给a,接下来,我们就要用if语句来做一个 判定,如果a不等于 G的话,那么就输出:你猜错了,那么中间的 这个符号呢,啊也就是一个英文的!,加一个=,它表示不等于, 所以这句话的意思是说,如果你输入的这个数,它不等于G的话,那么你就猜错了 elseif,啊,这跟刚才的else有点不同的就是,else里面我们又 写了一个if,这是可以的,啊,elseif a等于 那么注意,注意,如果你想在判断语句里面表示等于的话 那么你一定要记得写两个=,啊,连着写,因为两个等号的含义,是完全不同于 一个等号的,
一个等号呢,表示赋值,就是把一个值 给另外一个变量,两个等号呢表示判断是否相等,啊,这是一定一定要区分清楚 否则话,程序就会发生错误了,接着往下看 那如果a等于G的话,ok,我就输出:被你猜中了 啊,这就这个,通过这个程序呢,我们可以看到,如果我们想定义一个字符类型的变量的话,我们可以参照 这种方式来进行,如果我们想写一个分支语句的话,我们可以参照这种方式来写 那如果想在分支语句里头,啊,表达不等于的话,可以这样来写,等于的话 可以这样来写,所以说,大家可以模仿这个程序,写一些你自己喜欢的小程序了 啊,那除了分支语句,还有什么常用的语句啊,我们再来看一个 循环,那这个程序呢,就是一个比较简单的 循环的程序了,那这个程序做了一些什么事情呢,就是要从小到大输出20以内的 奇数,啊,就是做这样一件事情,那,怎么做的呢?
首先呢,定义一个变量i,这个变量i的类型呢,是int型 初始值呢,是0,在这儿呢,我们做一个小的说明啊,在写程序的时候呢, 人们习惯使用这样一些变量,像i呀,j呀,k呀 等等,恩,这样一些变量呢,来表示一些临时用来计数的 临时变量,当然,这只是一个习惯啊,那么在这个程序里头,我们也定义了一个i,恩,它的作用呢,也是用来做循环 计数的,啊,我们接着看这个程序,首先输出一个提示,啊,20以内的奇数 那接下来呢,是一个for语句,for语句是一个非常典型的循环结构。
所谓循环结构呢,就是不断地、反复地去做一件事情 象在这呢,就是不断地,反复地去做大括号之内的 这一件事情,也就意味着,在这个for循环里面,大括号里面 的这些程序呢,就要被反复地去执行,那么,要执行多少遍呢? 我们用i来进行循环 计数,那么从i等于0开始,反复地做下面的这些 事情,那么每做一次呢,i都增加1,i++的含义呢? 等效于i等于i加1 也就是说,每做一次,i都给自己增加1,直到 i不再小于20,
也就说,只要i小于20 我就要反复的去做这些事情,清楚了这个循环的作用以后呢,我们来看循环里面的 内容,如果代表着循环次数的这个i,模2 不等于0,啊,这个模,百分号,表示模运算 也就是,取余运算,取余数的运算 啊,那么如果i 对于2取余数的值不等于 0的话,那也就意味着i是一个奇数,
于是呢,我们就把i输出 出来,啊,这就这个程序的 基本的含义,那我们来看一下这个程序的输出结果,先输出一行提示 20以内的奇数,然后接下来,从1开始,一直输出到 19,啊,通过这个程序呢,我们就可以知道,如果你想写一个循环语句的话 那么你可以,模仿这样的一个格式 来写一个for语句,okay,这个呢,是从 小到达输出20以内的奇数,
那有的同学问了,我能不能从大到小输出呢? 也可以,我们来看这个程序,这个程序跟刚才那个程序基本一样,只是这有所不同 for循环的时候啊,i从20开始不断的去反复执行大括号里面的 程序,每次执行完毕呢,i都减减,i–的含义呢,就相当于i等于i减一 也就是说,每次i都自减一 直到i不再大于等于0,啊,也就是说只要i大于等于 0,那我就要继续执行这个循环里头的程序,i继续减一 所以这个程序的执行结果呢,也很明显,从19一直打印到1,啊,这样的一个结果 奥,这是这个程序,那么接下来呢,我们再看一个不太一样的程序
7快步走进C程序之三
那么接下来呢,我们再看一个不太一样的程序。看这个程序, 这个的程序做了一件什么事情呢?要求啊,你用循环来打印字母表中 序号为奇数的前五个字母。也就是说啊,这是一个字母表的话, 我们就需要须要把序号为奇数的前五个字母,全都打印出来。比方说,a, c, e, g, i, 噢, 把这一些字母打印出来。那当然啦,如果单纯是为了实现 这个功能的话,我们能完全可以写五句Cout的程序。 但是在这儿呢,哦,我们要求用循环来实现一个自动的打印。
那么我们来看怎么做。 那既然要实现一个自动的按照某种顺序 和规律,来打印字母,那么我们知道可能要用到循环。 啊,那么这个程序里头确实出现了循环。但现在我们碰到的问题是什么呢? 我们并不知道如何在循环里面自动的去变换字母。 那有没有其它的办法呢?在这一个程序里头,我们就用了这样一个办法。 虽然我没办法自动的去变换,但是我可以把这些字母啊, 事先存储到内层空间里头来, 然后想办法把它们逐个打印出来。
那在这儿呢,我们就写了这样一句程序来 把所有这些字母啊,事先摆放到内存里头。 然后呢,想办法逐个打印出来。那这句程序做了 一个什么事情呢?这句程序啊,定义了一个数组。 所谓的数组啊,就是把一堆数有序的排列起来, 放进一个连续的存储空间中。然后呢,给这个存储空间起一个名字, 这就定义了一个数组。
那比方说,我们来分析一下这些程序。 那么这些程序呢,定义了一个名字为a的数组。 这个数组里面呢,有十个元素。 每个元素的数据类型呢,是char型,也就是每个元素都是一个字符。 这就完成了这个数组 的一个定义。那么在定义数组的时候呢,我们同样可以对它进行初始化。 也就是,也就是设置数组里面最初所包含的元素。 怎么设置呢?我们可以用一个大弧号, 啊,把这些元素都括起来。我们在这大弧号里头呢, 把这些元素逐个的列出来。 注意呢,元素之间用豆号分隔开。
通过这种方式,我们就定义并且初始化好了一个数组。 那这样呢, 我们就在内存里边得到了一篇连续的存储空间,把这些元素都放进去。 那么为了便于大家的理解呢,在这儿我特别画了一个图。啊,也就是说当我们执行完这句程序以后, 那么在内存里边就形成了一篇连续的存储空间,每个里面呢,都放了一个字符。 在这儿特别需要须要说明的就是, 那么数组定义好之后呢,里面所有的元素都有相应的一个 编号。噢,比方说, 第一个元素的编号就是数组名加一个方符号再加一个零,就是a[0]。
第二个元素呢,就是a[1]。啊,第三个元素,a[2], 一直到最后的一个元素。在这儿呢,最后一个元素呢,是a[9]。 那么这个编号呢,就是相当于这个元素的一个名字。 比方说,我们想给这个数组里边的第三个元素重新附一个值, 那我们就可以用第三个元素的这个名字来完成。比如说我们可以这样来写。 a方符号2,让它等于一个新的值,比方说让它等于大G。 啊,这样呢我们就可以把编号为a[2]的,这个元素的值换成G。 啊,这就是编号的这个含义。还有一点特别须要注意的就是, 如果你定义一个包含十个元素的一个数组的话, 那么这个数组元素的编号是从零开始的。 也就意味着从零一直到九啊, 它不会出现十。
那么数组元素的编号呢,就是这样来使用的。所以说请大家注意, 当你定一个包含十个元素的一个数组的时候,不要写出来a[10]。 因为a[10]这个元素是不存在的。因为元素的最大编号就到了九,这是关于数组。 那么回到我们的这个程序,定义好了这个数组以后呢, 我们就得到了一篇内存空间, 把这些字母啊,都摆放好了。 那接下来呢,我们就可以用数组元素的编号来打印相应的字母了。 由于这个打印的过程呢,是按照某种规律在反复的做同一件事情,所以我们肯定要用到 for循环。 那么这个for循环呢,我们仍然用我们刚才所定义的这个i来计数。i 从零, 一直到i 小于十。因为它要求打印的是前五个字母,所以说我们让i 小于十。然后呢, 每次做的事情就是要把a[i] 打印出来。
打印完a[i]之后呢,i 要自己给自己加二。 这样呢,打印完第一个元素,我就紧接着去打印第三个元素,然后再打印第五个元素, 再打印第七个元素,再打印第九个元素。Okay, 那这个程序就执行完毕了。 那么程序的执行结果呢,打印输出的字母呢,分别是a, c, e, g, i,啊, 这个结果是正确的。 那么通过这个程序啊,我们可以了解到这样几点重要的东西。 第一个,当你想定义一个数组的时候,你可以模仿这种方式来定义。 啊,当然你除了可以定义一个字符型的,你也可以定义其它类型的数组。 那么定义完一个数组以后呢,可以通过这种方式,来引用数组里的元素, 那是第二点。 那么第三点呢,在一个循环里面,我们不一定 要每次对循环进行加一的操作。我们可以灵活的去控制。
啊,就是这样的一个程序。Okay,在看过了刚才的这些小程序以后呢, 哦,大家就可以模仿着这些程序,写一些自己感兴趣的小程序了。 那么现在大家看到的这个程序呢,就是在刚才猜字母的那个小程序的基础上,做了一个小的改进。 我们先来了解一下,它的基本功能。首先呢,它认为藏起来一个字母G。 但这次不同的是,你不只是能猜一次,你最多可以猜 五次。好,我们来看一下它的运行结果,以便于更好了解程序的功能。 哦,先输出一番提示,猜猜我是哪一个字母啊?最多猜五次噢! 哦,那么你就,接下来你可以输入a,当然是错的。接着猜吧,d,错的,接着猜, f,接着猜,小写字母g,也接着猜, 最后输入大写字母G,okay,它输出被你猜中了。
我相信啊,大家应该能够了解,这个程序执行的过程了。 Okay,那我们回过头来分析一下这个程序。头一眼看一下这个程序,我们就会发现跟刚才我们给出的 程序呢,有一点很大的不同。就是在这个程序里面,出现了很多绿色的汉字。 那,每一行的汉字呢,都是以双斜线开头的。 啊,我们看得到都是以双斜线开头的。那这种东西是什么呢? 这个是程序的注释。 也就是对程序的语句进行说明的文字。 注释呢,跟程序不同。在你定义这个程序的时候, 编译器完全就会忽略掉这些注释的存在。
啊,它们就会当它不存在。那,注释的作用是什么呢?就如这个名字所言, 注释是用来对程序语句或者程序块的功能,或者相关的 信息进行说明的文字。因为这是第一次大家遇到注释, 我在这儿呢,做一个特别的强调。 写程序有一个非常重要的目的。那我们在实现一个程序的时候, 除了你要实现这个程序的基本功能之外, 还有一个非常重要的目的。那就是一定要保证这个程序的可读性。
也就是说啊,我们要尽力的使这个程序容易被别人读懂。 这是衡量一个程序是否优秀的重要因素。 所以说,在我们的程序里头我特别强调大家一定要注意添加相应的注释, 这是第一点。同时为了保证程序的可读性, 大家一定要注意程序的排版和缩进。比方说这样一个程序,啊,for循环进去, if语句再进去,出来,一层,再一层, 再一层。那么这样的一个缩进呢,就会使得程序的结构非常的清晰。 啊,大家一定要注意这两点。 Okay,在调量了这两点以后呢,我们来看一下这个程序的基本的功能。 首先, 我们定义了一个字符类型的变量a,用于存放用户输入的字母。 然后呢输出一行提示。
第一个i用来记录循环次数。那么记录循环以后呢, 每次从键盘上读入一个字符,送给a。如果字符a 等于大G,也就是说被猜中了。这时后呢,打印输出cout“被你猜中了!” 同时呢,根据程序的要求,既然被猜中了,就不须要在继续循环。 比方说你一共可以猜五次,但你在第三次猜中了,那么后两次的循环就不须要再做了。 那这个时候呢,我们竲加了一个新的程序语句,叫做break。 Break,break的含义呢,就是要终止 外层循环。比方说,它在这个for循环的范围之内,那么如果执行到break了, 那么这循环就不要再被执行了。无论这个循环被执行过了多少次。 如果没有猜中,那么打印输出,“你猜错了!接着猜吧!” 循环继续执行。
啊,这是这个程序的一个运行的情况。那么哦, 下面我们总结一下,通过这个程序我们学到了一些什么。首先,在共同语句方面, 我们知道if语句的下面呢,可以使用一个大符号, 来把多句程序放进if语句的里面来。 因此就是说,当这个条件成立的时候,这一些语句, 都会被执行一次。这是第一点。第二点,我们学到 可以用break来终止当前的外层循环,这是在程序语句方面。 除此之外呢,还有两点非常重要的东西。第一个,也是最重要的一点, 程序里面一定要注意写注释,特别是对于那些复杂的程序。 对于复杂的程序而言呢,写注释不但对于别人读懂程序是有帮助的。 对于你自己尽快写出一个正确的程序也是有帮助的, 这是第一点。第二点,程序一定要注意相应的格式上的缩进排怖。 噢,一定要注意这个缩进排怖,一增强它的,
8什么样的程序是好程序
在了解了这个关于新程序设计,基础的知识以后啊, 我希望大家能通过模仿的办法去尝试着写一些 自己感兴趣的程序。或者是呢,去尝试抄写一些已有的程序。 那么在大家动手写程序之前,有一个问题想跟大家在这儿探讨一下。 那就是在我们这一个课程,什么样的程序是一个好程序? 那在我们这个课程呢,对于同学们所编写的程序呀,有一些方面, 是我们所重视的。有一些方面呢,是我们所不重视的。 下面呢,我们就来讨论一下。 我们重视那些方面呢?
首先,我们当然要重视程序的正确性。 也就是说你的这个程序,运行结果是不是正确的? 是不是解决了问题,这当然是我们所重视的一个方面。 谨次于这个方面,我们非常重视, 你所书写的程序,是否容易被别人看懂。 因为只有那些易于被别人 读懂的程序才能够更长久的维护下去。 这个程序才具有生命力。所以我们非常重视这个方面。 除此之外,我们非常重视程序的结构是否清楚。 因为我们所学习的程序设计语言, 是一门结构化程序设计语言。正如我们跟大家所讲过的,我们是在C++的环境中, 学习C程序语言。那么C程序设计语言呢,就是一个结构化程序设计语言。
所以在这个课上,我们想要培养的就是一种结构化程序设计的思想。 因此我们非常重视你的程序,结构是否清楚。 那么表现出来呢,有一个很重要的方面就是这个程序,是不是足够的美。 噢,这是很重要的一个方面。那么这几个方面,就是我们所重视的方面。 那么有一些方面呢,是我们所不重视的。比方说, 你在程序里面,是否多使用了,或者少使用了几个变量。 你的程序行数比别人多一点,或者少一点。 再比如,你的程序运行起来,比别人快一点,或者慢一点。 这些都不是我们所重视的。 Okay, 我再总结一下,我们所重视的特性。第一个, 我们当然要重视程序的真确性。第二个, 我们要重视程序的,我们要重视程序的可读性。 第三个,我们非常重视程序结构的清晰程度。
我希望呢, 大家能够写出漂亮的,美的程序。最后呢,我以荀子的一句话来鼓励大家。 不积跬步,无以至千里。不积小流,无以至成江海。 之所以把这句话放在这里,是因为我们刚刚开始我们的写程序的旅程。 在这里我特别想提醒大家,一定要沉住气,多从简单的东西,开始做起。 那么我们课程的进度呢,也稍微的放慢一点。给大家一个适应和缓冲的时间。 我相信,这个环节会给我们后面的学习,带来很大的帮助。 那么今天的课程就到这里,谢谢大家!
编程作业: 感性接触计算机程序
编程题#1:实现冒泡排序来源: POJ (Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)注意: 总时间限制: 1000ms 内存限制: 65536kB描述请根据自己的理解编写冒泡排序算法,数组大小1000以内输入第一行是n,表示数组的大小接着n行是数组的n个元素输出排序之后的结果一个元素一行请完全按照如下的程序书写代码,并在书写的过程中体会优秀的代码风格:#include <iostream> using namespace std; int main() { int n, a[1000]; // 一共n个数,n不超过1000。a用来保存这些数 cin >> n; // 输入n个数 for (int i = 0; i < n; i++) { cin >> a[i]; } // 冒泡,不断比较相邻的两个数,如果顺序错了,那么就交换 for (int i = 0; i < n - 1; i++) { for (int j = 1; j < n - i; j++) { if (a[j - 1] > a[j]) { int temp = a[j]; a[j] = a[j - 1]; a[j - 1] = temp; } } } // 依次输出 for (int i = 0; i < n; i++) { cout << a[i] << endl; } return 0;}
冒泡排序的原理
样例输入
5071 899 272 694 697 296 722 12 726 899 374 541 923 904 83 462 981 929 304 550 59 860 963 516 647 607 590 157 351 753 455 349 79 634 368 992 401 357 478 601 239 365 453 283 432 223 739 487 714 391
样例输出
1259717983157223239272283296304349351357365368374391401432453455462478487516541550590601607634647694697714722726739753860899899904923929963981992
编程题#2:奇偶排序(一)
来源: POJ (Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
注意: 总时间限制: 1000ms 内存限制: 65536kB
描述
输入十个整数,将十个整数按升序排列输出,并且奇数在前,偶数在后。
输入
输入十个整数
输出
按照奇偶排序好的十个整数
请完全按照如下的程序书写代码,并在书写的过程中体会优秀的代码风格:
#include <iostream> using namespace std; int main() { int a[10]; for (int i = 0; i < 10; i++) { cin >> a[i]; } // 首先,我们把奇数放到数组左边,偶数放到数组右边 int l = 0, r = 9; //用左手和右手分别指向数组两端 while (l <= r) { bool leftIsOdd = a[l] % 2 == 1; bool rightIsEven = a[r] % 2 == 0; if (leftIsOdd) { l++; } else if (rightIsEven) { r--; } else if (!leftIsOdd && !rightIsEven) { int temp = a[l]; a[l] = a[r]; a[r] = temp; } } // 对l左边(奇数部分)冒泡,不断比较相邻的两个数,如果顺序错了,那么就交换 int start = 0, end = l; for (int i = start; i < end - 1; i++) { for (int j = start + 1; j < start + end - i; j++) { if (a[j - 1] > a[j]) { int temp = a[j]; a[j] = a[j - 1]; a[j - 1] = temp; } } } // 对l右边(偶数部分)冒泡,不断比较相邻的两个数,如果顺序错了,那么就交换 start = l, end = 10; for (int i = start; i < end - 1; i++) { for (int j = start + 1; j < start + end - i; j++) { if (a[j - 1] > a[j]) { int temp = a[j]; a[j] = a[j - 1]; a[j - 1] = temp; } } } for (int i = 0; i < 10; i++) { cout << a[i] << ' '; } return 0; }
样例输入
10 9 8 7 6 5 4 3 2 1
样例输出
1 3 5 7 9 2 4 6 8 10
编程题#3:奇偶排序(二)
来源: POJ (Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
注意: 总时间限制: 1000ms 内存限制: 65536kB
描述
和上题一样,但是要求用第二种解法
输入
输入十个整数
输出
按照奇偶排序好的十个整数
请完全按照如下的程序书写代码,并在书写的过程中体会优秀的代码风格:
#include <iostream> using namespace std; int main() { int a[10]; for (int i = 0; i < 10; i++) { cin >> a[i]; } // 冒泡,不断比较相邻的两个数,如果顺序错了,那么就交换 for (int i = 0; i < 9; i++) { for (int j = 1; j < 10 - i; j++) { // 与刚才的冒泡排序不同,我们不只是通过较数字的大小决定顺序 // 如果左边的为偶数,右边的为奇数,那么顺序也需要颠倒 bool leftIsEven = a[j - 1] % 2 == 0; bool rightIsEven = a[j] % 2 == 0; if ((leftIsEven && !rightIsEven) || (leftIsEven == rightIsEven && a[j - 1] > a[j])) { int temp = a[j]; a[j] = a[j - 1]; a[j - 1] = temp; } } } for (int i = 0; i < 10; i++) { cout << a[i] << ' '; } return 0;}
样例输入
10 9 8 7 6 5 4 3 2 1
样例输出
1 3 5 7 9 2 4 6 8 10
提示
先排序,再分别输出奇数、偶数
**
下载、安装和使用IDE
**
今天我给大家讲一下在 Windows 的环境下,比较常用的几种c++的IDE下载安装和基本的使用方法。 首先我想说一下的是最常用的visual studio。然后我选择的是express版本, 因为express版本是免费的。也就是说任何人都可以下载。 恩,如果你是大学生的话你也可以在dreamspark上, 在这个网站上,在这个网站上面下载,恩, 一个高级的visual studio的版本,但是我们, 由于我们的课程比较简单,是一个入门级的,所以express的版本就已经比较好用了。 好的我们打开它的下载页面。
下载页面里面 会有很多种选项,我们会选择我们所需要的那一项。Visual Studio Express RC。 RC是release candidate的意思。然后选择 Windows desktop。我们开发桌面应用程序,然后这里可以选择你要的语言, 然后我们可以点安装。那它会连接到另一个网站上。这时候它会要求你有一个, Microsoft的账号。这个账号可以免费地去申请一个。我已经有一个了,所以我就直- 接登录了。
好现在我们有就有两个选择了,一个是,嗯, 恩,Express版本,还有一个是Ultimate版本,Ultimate版本是收费- 的,我们选择Express版本。 好现在我们就可以去保存。它是一个网络安装, 然后双击这个安装包,我们就可以开始安装了。由于我已经安装过了, 所以这个安装包可能显示的结果会跟大家显示的不太一样。 你看现在就是有一个repair和一个uninstall的选项 。所以那如果是大家的话,应该是有一个安装的选项。
大家按照它的说明进行安装就可以了,我在这里退出,然后我打开我安装好的, 我安装好的visual studio。当大家安装好visual studio的时候,它应该是这个界面。 然后我们选择在这里新建工程,new project或者在文件新建工程都是可以的。 然后在左边这一栏选择Visual C++里面的Win32应用程序,然后选Win32 控制台应用程序。 然后这里它会有一个location,默认的情况下是在我的文档里面的路径。 那个路径其实并不好用,所以我选择了一个自定义的路径。大家也可以 选择一个自定义的路径。然后这个路径,恩,之后就会变成大家储存,恩, 自己编写的程序和代码的地方。 那这时候可以给我们的程序取一个名字,我们就叫test2吧 。
然后我们选择控制台应用程序,空项目,finish。 这时候我们就有一个叫做test2的一个,嗯, 应用程序了。然后在这个程序里面它是由于是一个空的项目,所以里面什么东西都没有。 这时候我们右键点击source files,然后添加一个新的项目, 然后这里什么东西都没有,这其实是 Visual Studio Express 2013 的一个bug,你有可能会遇见这个bug,也有可能不会遇见。 然而我比较不幸运,所以遇见了。这个它有一个解决方案,解决方案我会放在课程的一个- WIKI page上。 到时候我会有一个链接,然后指向它,大家可以在Coursera上去找到这个解决方案。 好的我回来了,刚才我剪辑了一下,我把这个问题给修复了。
这时候我们点击,如果你已经修复了这个问题的话,你点击C++ files,然后我们添加一个新的文件, 我们可以叫做main,添加。 这时候它就是一个新的一个源文件了,所谓的源文件就是储存 程序源代码的地方。然后我们这里面写入我们的代码。 好的,我们写完代码了,这时候我们保存, 然后运行。这其实是调试。 好我们看见这个程序直接一闪而过了,怎么办?其实很简单。 我们在return 0地方加一个断点。 断点就是让程序停下来的地方。 好的,然后我们找到,我们的刚才那个程序,我们就可以看见,哦,hello,world。 这是我们写的第一个程序。
好的,我们接下来让它继续运行, continue,好,它就退出了。这就是Visual Studio Express 2013的基本用法。 接下来我会教给大家Eclipse的用法。 Eclipse是一个跨平台的IDE,它可以,它支持非常多的语言,比如说java,比- 如说C++,比如说Python, 等各种各样的语言,但是CDT得需要更多的配置, 不像是Visual Studio那么简单,但是我也会教大家怎么弄。首先我们选择它下载。 我们选择最新的这个版本。 在右边选择符合你现在操作系统的一个 版本。我是64位的操作系统,所以我点Windows64。
然后我们点保存,这个下载应该很快。 大家可以看到我每秒有2.5兆,2.6兆。好的,我已经下载完成了。 这时候我们选择我们的下载,下载的压缩包,选择解压。 解压的过程应该很快。这时我们就有Eclipse了。但是 别着急,现在先不要打开它,我们还需要另一个东西来辅助它 编译我们的C++程序。那个东西叫做MinGW。
MinGW是给windows使用的一个,恩, GNU环境。 我们点这里下载安装包。 点保存, 双击它,打开,install,然后我们选择默认配置就好了。 如果你c盘空间不够大,你可以去换别的地方,因为MinGW安装完之后还是有一定 空间需求的。 它是个联网的安装,所以大家不要断网。 好安装完了我们continue,这时候我们选择两个包,一个是base包, 右键,mark for installation。然后g++包是C++ Compiler。 Apply changes。Apply。 这个下载要花一定时间, 待会儿下载完了我再给大家继续演示。 好的,当程序运行到这一步的时候,就说明整个下载安装的过程已经完全结束了,我们可以把- 它给全部关掉。
然后我们找到刚才下载的Eclipse。 恩,错了,现在先不要打开,我们还需要一个,最后一个配置。 打开你的系统属性,高级系统设置,环境变量,PATH。 PATH是我们的,PATH变量,PATH变量是Windows 的,就是查找一个文件的时候,如果你不加任何 开头的路径,它会默认在PATH中 去寻找你想搜索的东西。比如说我们在命令行里面, 去找一个GCC这么一个应用程序。 这时候这个输出就代表它已经找到一个GCC,但是由于没有输入文件,所以它退出了。 然后这个GCC在哪里呢?它就在我们刚才安装的MinGW的这个 bin目录下,如果刚才你安装在c盘,像我一样,那么你像这样去写就可以了。
如果你没有安装在c盘,你在别的地方的话就相应地作出修改也可以。如果我们没有这一行, 我们重新打开这个命令行窗口,我们打出GCC。 哦不好意思我觉得我应该先点这个确定。啊。 好,这时候我们就发现GCC它已经, windows已经找不到GCC这个程序了,这说明这个环境变量的作用就是用来去寻找这- 么一个, 恩,路径,提供一个路径,用来寻找程序。我们再把刚才这个加上。 大小写其实是没有关系的。 但是,啊,ok,确定,确定。我们这时候再执行, g++,好的,这时候g++程序又被重新找到了。 如果你到了这一步那么就可以打开Eclipse了。 第一次运行Eclipse的时候它会问你,恩, 你要用哪一个工作空间? 所谓的工作空间就跟Visual Studio的那个项目空间一样, 是储存你程序和代码的地方。
然后我们还是 老习惯不要用默认,我们自己找个地方, 恩,就叫做Eclipse workspace吧。 然后底下可以把它当做默认,我的习惯是 把它勾选。好, 这时候会有一个欢迎界面,我们不用管它,关掉它。 新建C++工程,C++工程这时候如果一切安装正确的话,就会有一个 MinGW GCC的选项,如果你MinGW没有安装正确的话,那么就没有这个选项。 所以大家可以知道哪一步自己出错了。然后项目的名称我们可以选择一个就叫test吧。 这时候应该不会有重名的。finish。 好这是一个空项目我们大家可以看到它有一个incudes这是什么东西我们不用管它我们- 先新建一个源文件, 源文件的名字我们还是老习惯就叫main.cpp.
finish 然后这时候我们再把刚才的代码给敲进去。 好这个时候我们的程序已经写完了。 然后我们可以看出它有几个错误啊。这个其实啊现在没有了。就是一个它会有一个延时。 我们选择build all。 全部去build一下。然后这时候我们就可以去run了。run完之后我们可以在底下这里看到console里面就会显示hello world, 它相比visual studio有一个好处就是它出来的程序不会一闪而过, 它会有一个专门一个窗口来保存你的输出。这是挺方便的一点。但如果你就加一个断点的话也- 没有关系。 然后在elipse里面我们加断点的方法我们跟在visual studio里面差不多。就是在代码前面双击一下。
在visual studio里面是单击一下,然后在elipse里面是双击一下。 elipse有一个非常好的优点是visual studio代替不了的,就是它是跨平台的。 也就是说如果你是一个苹果电脑或者说你在linux环境下使用 开发环境的话elipse会是一个非常好的选择。 当然你也有别的选择。 好,我们这时候就可以退出它了。最后一个ide我要介绍的是netbeans。 netbeans也是一个很常用的ide我们这3种ide的好处 都有一个好处就是它们都是免费的。注意你要下载 visual studio的express版。如果是别的版本的话它还是要收费的。 除非你是学生。我们在这个C++的这一栏里面选择download, 然后它会自动开始我们点保存。 好这时候我们就已经下载完成了我们双击它进行安装。
安装到以下位置。 然后它需要一个JAVA的运行环境,不用管它。
好这时候我们就安装完了netbeans了。 点完成我们就可以在 开始菜单中找到netbeans或者在你刚才安装的目录里 之后我们就可以 在这里有一些演示和教程大家可以看一下。但是其实也没有关系。 我们新建一个项目。C++的项目。我们可以选择一个C++应用程序, 下一步。然后这里一样我们会需要应用到项目的位置然后我来 看一下。嗯,netbeans。 然后项目的名称就还是老样子就叫test。 点完成就可以了。netbeans也是需要mingw的也就是 说也是需要像刚才一样你需要去安装一下mingw的。 选择base包和gcc的包。然后在源文件立面它会自动给我们生成一个MAIN.CPP。
main.cpp这里面它是一个模板,但是我们 其实也可以不用它的模板。 好的现在我们写完代码了,然后我们点击构建项目。 这时候会告诉你们成功,然后我们点运行,我们就会显示一个hello world了。 如果你现在完全按照我们的步骤来做的时候你点构建的时候应该会出现一个错误,它会告诉你 mix dil这一个命令是不存在的。这是怎么一回事呢?因为你没有 安装一个mingw的一个包,那个包的名字叫做msys。 我们把这个包就像刚才一样去勾选上,mark for installation project是底下这个,我已经安装好了 所以是这个样子。然后installation apply changes.然后这个安装需要比较长的时间, 所以我就不把它卸载了重新安装一下给大家演示了。大家明白就好。 当安装完了之后在我们的C盘的,或者你mingw的安装盘 安装目录底下就会多出msys的一个文件夹。
里面1.0然后bin,把这个目录打开,我们把这个目录拷贝一下。 因为我们还是要把它给加入到我们的系统变量中。系统变量path中。 就像现在这样。注意这个系统变量path 是你大家可以看见,是像可以用分号去分割不同的 路径的。像刚才我们加入的mingw的bin目录,然后现在我把它给 复制过来,点确定,再点确定,再点确定,然后当这一切弄完了之后我们把 netbeans关掉然后再重新打开它,注意一定要重新打开一遍。 这样的话程序才会正确的加载系统的路径。 改了之后我们可以看见我们左边已经有 项目了,然后打开我们的源文件,这时候如果你再去 构造,然后再去运行,那么你的结果应该跟我一样了。 好了这就是我们常用的三种 ide环境的下载安装和基本的使用方法。
使用IDE进行调试
这次我给大家讲一下调试的一些技巧。 这次演示我以visual studio为主, 因为别的IDK比如说eclipse,netbeans等等 它的使用方法跟visual studio其实是差不多的。 只是可能快捷键会有所变化但是基本功能都是一样的。 所以我主要用visual studio来讲解。 那么什么叫调试呢?所谓的调试叫debug, 就这个。debug是把bug去掉的过程,所以叫debug。 比如说我们这一段程序。这一段程序我们它是不是有bug的呢,其实它是没有bug的,这- 是一段什么程序啊, 它是之前大家做过的一个整数求和的程序。输入5个数然后输入1个n,然后输出这5个数里- 面小于n的数的和。 这么一道题其实是没有bug的,但是呢我们可以用debug的方式来观察这个程序是怎么- 运行的。
当你的程序有bug的时候你用这种方法去跟踪你的程序, 看看你的程序是怎么运行的,会对你寻找你出问题的代码很有帮助。 首先我说第一种debug的方式。就是非常简单的我们叫做log法。 这个log法就是在屏幕上会输出一些调试的信息, 然后通过那些信息来判断。比如说这道题。 我们可以把中间的一些过程给输出出来,比如说这里每一次c in一个数, 循环5次每次cin一个数我们就可以把这个数给输出出来。 那输出出来之后, 然后这里每一次小于n,然后return把它加上 这个数。然后我们再把这个return也给输出出来。 为了区别这个temp和这个return我们可以在前面加一点字符串用来区分它。
比如叫temp=底下是一个 ret等于。 像这样的技巧我相信大家都是会的。好, 我们来输入5个数,我们在这里直接拷贝它吧。 回车。我们可以看到第一次循环输入一个1,输入一个2,结果是3,输入一个3,结果是6, 一切正常。输入一个4,然后结果是10,输入一个11,然后判断它大于10,结果是10. 中间的运行过程一切正常。这就是一个简单的输出的调试方式。 你可以在程序关键的位置上把你想看的一些变量的值给这样输出出来。 好接下来我讲另外一种调试方式也就是所谓的 用ide去调试,去跟踪这个程序的运行。 首先你要在你觉得程序可疑的地方点一下左边,设置一个断点, 如果是eclipse的话是双击,到时候会讲到。
然后我们点这里,local windows debugger。 去开启我们的调试器。注意这次 我们填的是调试,是F5,而不是ctrl f5. 运行了之后我们可以把刚才的值输出进来。 回车。然后这时候我们看一下程序就会在这个地方停住。 停的地方正好是我们的断点,这个断点卡的是哪一句呢,是CIN这一句。 我们可以看到现在temp的值把鼠标放在temp上就可以看到,temp的值是-585- 89等等等等。 这个值明显是一个没有被初始化的值,所以说首先我要告诉大家 你没有初始化的变量的值你是无法确定的。在visual studio底下 它是这个值,但是如果你换一个编译器它就不是这个值了。所以一定要注意。
我们看现在我们的程序有一个黄色的箭头来标识 我们现在这个程序执行的行数是第10行,然后这个断点红色的被这个黄色箭头给盖住了, 这是表明,程序下一步将要执行这条语句,cin temp语句,我们看之前cin的值是n,n是10,再看一下我们的输入,输入第一个n- 是10,cin 这个输入的结果完全正确,然后我们可以用有几个按钮,在这里, 有step into, step over然后还有 step out三个命令,这三个命令分别是什么作用呢? 我们来仔细看一下。先说step over。step over是最常用的一个命令。 我们点一下。它的作用就是 把这一行执行完我们跳到下一行上。 step over, 这样的话我们一步一步点,我们就可以看出来这个程序是怎么执行的。 然后每一次执行的过程中我们可以在左下角看见有一个locals的一个窗口。
这个窗口代表是局部变量,局部变量我们现在有temp,有r,有return和n 这4个变量,我们不断的点step over我们就可以看见程序在执行每一步的时候这个变量的值是怎么变化的。 当然有一个变量不在作用域的时候比如说在这一句,temp是不在作用域内的, 那么它就不会显示在这个locals的这个界面里。 我们可以看到左下角除了一个locals窗口以外还有一个watch窗口。 watch窗口就是监视的意思。我们可以用这个监视的窗口来监视一些非局部变量,比如说 全局变量,我们现在把程序停掉,在这里,有个stop debugging的 一个按钮,一个红色的方块,点它可以停掉它。 我们在这里定义一个全局变量,比如说我们把这个n设为全局变量, 我们再开启调试器, 再把刚才的值输进去,回车。
这时候我们继续step over,step over在visual studio下它的快捷键是F10, 就像这样。 这时候如果我们切回locals窗口,我们会发现n 不见了,因为它是一个全局变量。当我们把鼠标移到n上面的时候我们还是能显示n的值。 那我们怎么在左下角这里看呢?很简单在watch这里输入一个n, 那么它就可以被watch窗口所显示了。 我把刚才那一段程序给 稍微改了一下。像现在这个样子。我加了一个函数叫funk。 这个funk函数会有一个参数是t,如果t小于n的话那么返回t否则返回0.那样的话我- 们只用写 每次把funk temp的结果加回来,那么就可以获得我想要的结果。 我们来试着运行一下。把刚才的值 输进去。 然后切回我们的visual studio。这时候我们就可以看到, 我们的程序进入我们预期的一样进入了断点。
然后 我们按step over到这一句。到这一句以后我们接下来按一下 step into。它就到这个函数里了。 如果我们再按step over的话,它就还是会像刚才一样跳到这个循环的开始。 step over这个命令的意思就是执行完当前这一行语句之后到下一行上。 而step into的意思就是说如果这一行上就是调用了什么函数的话,那么就进入到那个函数体里。 step into可以在一句话上用好几次,如果你那一句话上有好几个 函数调用的话。它会依照函数调用的顺序依次的进入函数。 我们可以按F10往下走。return。 然后这时候一步一步,接下来往下再输入一个temp,然后这时候我如果我们现在按 step over的话,就会进入下一行。
然后再进入,这时候还有一个命令叫step out,step out的意思就是说 让当前的函数执行完并返回,我们点一下step out, 好立刻回到刚才那一行了。如果我们再按step into的话,是没有效果了。因为刚才这个函数已经执行完了。 这就是step into和step out它是用于进入和跳出函数时所用的。 右下角有一个窗口叫cross stack,叫调用堆栈的意思。 调用堆栈显示的是你程序当前执行的这一行在 程序执行的过程中所在的位置。它是用函数来表示的。 比如说这里我们可以看见我们在main函数的第17行。 如果我们进入到我们funk函数里的话,就可以看见这里 在调用堆栈里面多了一行,是在funk函数。
它现在告诉你,我们在funk函数的第5行。 我们step over。就可以到第6行。这是调用堆栈。调用堆栈还有一个用法是你双击 你想跳转的位置它可以显示那个函数被调用的位置。 并且如果你点开locals窗口的话,你可以看到所有的变量都会 显示为当前你双击的这个位置的值。 而不是在这个函数体里。因为在这个funk的函数体里我们是没有temp i 和return的,我们可以双击回去 看一下。我们只有一个t,这么一个参数作为一个局部变量。 但如果我们双击到main函数里的话我们就可以看见在main函数这个作用域内 当前的变量值。叫做立即窗口,immediate window。 这个窗口可以用来立刻执行一些语句。它在有些编译器中实现了,有些编译器中没有实现。 比如说我们在这里可以直接给t赋一个新的值比如说t=10, 然后我们就可以看见左下角locals里面t的值就已经发生变化了。
然后如果我们再按- step over 继续往下走,直到这个函数跳出我们可以看出,现在return是0, 当我们这一行语句执行完之后return就变成10了。也就是说刚才我们对t所进行的修- 改确确实实影响到了程序的执行。 这就是立即窗口,它可以立即执行一些语句并且看它的结果。比如说我们在这里还可以写re- turn = = 10,像做这种判断也是可以的。我们可以在这里面写各种各样的,只要是符合 C++语法的语句。并且让它立刻执行。 接下来我给大家演示一下netbeans底下应该怎样调试程序。 跟visual studio底下一样,我们首先在程序的行数前面点一下 它就会出现这么一个红色的断点,然后我们在这里设置一下, 选运行,设置项目配置,定制, 然后我们在这里运行这里把控制台类型 选成外部终端,因为在没有装iii的情况下 没法使用内部终端进行调试。
所以我们在这里选择外部终端 然后点确定。点确定之后我们就可以进行调试了。点调试项目。这时候它就像visual studio一样它会 弹出一个黑色的命令行窗口,然后在窗口里面我们就可以输入我们想要的东西。 我们把输入的文字复制一下。 哎。命令行窗口有一个小技巧。对于windows用户来说 我们在标题这里点右键,点属性打开快速编辑模式, 点确定,这时候我们按右键就可以把刚才复制的东西给粘贴过来了。如果想在命令行 窗口里面复制别的东西的话我们可以直接选中然后点右键,这时候我们刚才 被选中的这些东西就会被复制到剪贴板里,这就是快速编辑模式的好处。 在输入数据时,快速编辑模式非常好用。我们可以不用每次打开命令行窗口都 要iii,我们可以直接打开默认值把快速编辑模式勾选上,点确定就可以了。 然后点回车。
这时候我们发现我们的程序就在这里停住了。由于我们这个断点设置在一个变量- 声明上,这个变量声明并没有 什么实际的实际需要执行的语句,所以它最后程序停在了它的下一句。 输入这个temp。这个temp在初始化之前它是一个随机的数。我们往下走。 然后我们像之前一样,这里有步入,步出,步过, 步过这个step over,步入就step in,步出就step out, 然后我们点步过就可以看到我们的temp变量就被赋值成了 1.然后接下来进行各种各样的判断。使用方法跟visual studio差不多。 然后我们可以看到,局部变量在这里,变量这一栏。调用堆栈在这一栏。
然后我们的输出就是在这个黑色的窗口里。 跟visual studio很像。netbeans里面并没有立即窗口。 最后我们来看eclipse。 elipse的用法跟之前是一样的。但跟之前不同的是 这里需要双击它才可以增加一个断点。这个蓝色的小点。 然后我们点这个虫子,上面写的是debug。
然后它会问你是否是打开调试的视图, 我们点是就行了。在调试视图里我们可以看见我们的变量。 然后我们可以看见我们的调用堆栈是在这里。然后我们的命令行窗口是在这里。 在elipse里监视窗口默认是关闭的我们需要在window这里打开 window show view里面有个expressions表达式,这么一项,我们点开它。 这个实际上就是监视窗口。但它跟监视窗口不一样的地方它是可以计算 一个值的。比如说在这里,比如我们现在输入了n 然后我们可以看到n的值是10,我们可以在这里输入表达式n== 10,回车,我们可以看到它的计算结果是true。 虽然我们可以用它来计算表达式但是我们并不能把它当做立即窗口来用。 比如说我们在这里输入n=20,回车虽然返回的结果是20,但是如果 把鼠标移到n这里的时候我们会发现它的值依然是10,并没有更改。 然后点这个红色的方块就可以终止这个程序。
版权声明:内容来源于互联网和用户投稿 如有侵权请联系删除