☰
Python基础第2章程序题拆解:从阅读到编写的完整解题路径
2026/10/14 3:30:24 网站建设 项目流程

很多同学拿到《Python语言程序设计基础》第2章“程序部分”的练习题时,第一反应往往是到处搜答案。我接触过的初学者里,十个有八个都是这样。可实际情况通常是:就算把别人写好的代码拿过来,复制到自己机器上一运行,报错信息看不懂;或者代码能跑通了,题目稍微改一下输入,又不会写了。出现这种情况,不是因为动手少,而是在解题的“思路链”上断了链条——答案本身只是最末端的一环。

这篇文章想做的事情,不是简单丢几段代码给你,而是把第2章程序部分练习题背后的通用解题路径完整拆开。我会先讲清楚这个部分到底在考什么,再把“程序阅读题”和“程序编写题”分门别类地拆解,每个典型方向都给出完整的参考写法、运行结果和易错点分析,最后提供一个能真正用来核对自己答案的自查清单。适合正在学这本书、正在上Python基础课、拿到题没思路或者写完不敢确定对不对的同学。看完之后,你不需要靠现成答案,也能独立把练习题做出来,并且能解释清楚每一行代码为什么这么写。

1. 先搞清楚教材第2章的“程序部分”到底在考什么

1.1 程序阅读:读得懂代码,比写得出来更基础

第2章的“程序部分”,几乎每套练习都会包含程序阅读题。这类题的典型形式是:给你一段完整的Python代码,让你写出运行结果,或者从几个选项中选出正确输出。很多初学者觉得这种题比编程题简单,其实恰恰相反——读题一旦出错,整道题就废了。

程序阅读题真正考察的,往往不是你会不会写代码,而是你能否准确判断“变量在每一行的值发生了什么变化”。具体来说,考点集中在四个方面:

  • 赋值语句的语义:a = a + 1到底是怎么发生的?
  • 分支条件的判定:if和else的配对关系,条件真假怎么算?
  • 循环的次数与范围:range(1, 5)到底包含不包含5?
  • print的位置:是放在循环里面还是循环外面?在循环里会被打印几次?

我以前见过很多同学,代码看得挺热闹,但问“第5行执行后a的值是多少”就答不上来。根子在于没有“逐行执行”的习惯。程序阅读题最大的技巧,恰恰是最笨的方法:拿一张纸,把每一行执行后每个变量的值记下来,一行一行地“手算”程序。一旦你把这套动作练出来,阅读题基本不会丢分。

1.2 程序编写:从“题目要求”到“可运行程序”的四步跳跃

程序编写题就是大家说的“编程大题”,给一段文字描述或者输入输出示例,让你写出能实现功能的代码。这类题在第2章不会太难,它考的不是复杂算法,而是三种基本结构——顺序、分支、循环——的组合使用。

结合这套教材的教学思路,程序编写题本质上要求你完成四次跳跃:

  1. 从“题目描述”跳到“输入输出”:看清楚题目需要接收什么类型的数据、输出什么格式的内容。
  2. 从“输入输出”跳到“变量设计”:围绕输入数据定义变量,想清楚中间是否需要额外变量来保存计算结果。
  3. 从“变量设计”跳到“流程组织”:把整个计算过程拆成顺序结构、分支结构或循环结构。
  4. 从“流程组织”跳到“Python代码”:把流程翻译成符合语法的语句,写完运行测试。

很多同学写不出来,是因为第一步就跳错了。题目没看完,就开始写代码,写了一堆才发现输入格式理解错了。所以第2章的程序编写题,答案的代码通常只有几行,但前提是你把题目条件吃透了。后面我会用“五步作答法”专门讲怎么组织这个过程。

2. 程序阅读题的拆解方法:不是靠猜,是逐行“翻译”

2.1 先看结构,再看细节:缩进、分支、循环的边界

程序阅读题最忌讳“整体扫一眼”然后凭印象下结论。正确顺序是先看代码的整体结构,再去抠细节。

所谓“看结构”,就是先回答三个问题:

  • 这段代码是顺序结构,还是有分支?
  • 有没有循环?循环从哪一行开始,到哪一行结束?
  • print语句究竟在哪个结构体内部?

就拿一个很常见的嵌套循环示例来说:

i = 1 while i <= 3: j = 1 while j <= i: print("*", end="") j += 1 print() i += 1

先看结构,外层是while i <= 3,它里面又套了一个while j <= i。内层循环负责连续打印星号,外层循环的倒数第二行print()负责换行,外层循环的最后一行i += 1是计数器的自增。如果漏掉任何一个缩进,或者看错print("*", end="")和print()的分工,输出就会完全不对。

这类嵌套循环题,在第2章程序阅读里不算难,但信息量很大:它同时考了循环嵌套、计数变量、格式化输出的end参数。写答案时手快嘴快不行,必须按结构一层一层拆:

  • 外层循环第一次执行时i = 1,进入内层,此时j = 1,满足j <= i,打印一个星号,j变2,内层结束;执行print()换行;i变2。
  • 外层循环第二次,i = 2,内层从j = 1开始,打印两个星号,换行。
  • 外层循环第三次,打印三个星号,换行。

所以输出结果是三行星号,第一行1个,第二行2个,第三行3个。这样逐层推,才不会漏掉换行。

2.2 一个完整的程序阅读示范:从代码到运行结果的推演

再看一道综合性强一点的阅读题,它混入了continue和累加:

total = 0 for k in range(1, 6): if k % 2 == 0: continue total = total + k print(total)

如果你只看“把1到5加起来”,那结果就是15。但这里有一个continue,它的作用是:当k是偶数时,跳过本次循环后面所有的语句,直接进入下一次循环。所以偶数2和4根本不会参与total = total + k这条语句。

逐行推理一遍:

k的值条件k % 2 == 0是否执行累加total累加后的值
1False是1
2True否(continue)1
3False是4
4True否(continue)4
5False是9

最终输出是9,不是15。这就是阅读题的价值:它在检查你是否真的理解continue的语义,而不是靠“题目大概是在求和”这种模糊直觉。

还有一类特别容易错的阅读题,考赋值语句的“绑定”特性。比如:

a = 2 b = a * a a = 5 print(b)

很多人一看a最后变成了5,就顺手写成25。但正确答案是4。因为b = a * a在它执行的那一刻,就已经把计算结果4存进了b,之后a再变成什么,都影响不到b了。Python里变量是“先绑定后引用”,这条规则在程序阅读题里反复出现,值得单独记下来。

2.3 阅读题的三种“送命题”错误

我把这几年在作业里看到的高频错误归纳成三类,几乎每一类都能在一道精心设计的阅读题里让人丢分。

第一种,把赋值语句当方程式。看到x = x + 1就理解为“两边约掉x”,完全不知道赋值号右边先计算、左边再接收结果。应对方法很简单:把它读成“把旧的x加1,再存回新的x”。

第二种,range边界混淆。range(1, 5)生成的是1、2、3、4;range(5)生成的是0、1、2、3、4;range(1, 5, 2)生成的是1、3。这三个例子必须背清楚,程序阅读和编写都会用到。

第三种,print位置判断失误。print如果写在循环体内部(缩进跟循环体一致),那每循环一次就打印一次;写在循环外面,则只打印最终结果。很多同学默认“程序的最后一行输出最终值”,但题目可能故意把print放在循环里,让你输出一串过程值。判断标准只有一条:看缩进,不听感觉。

3. 程序编写题的“五步作答法”与典型题完整示范

3.1 五步作答法:审题、定变量、画流程、写代码、验边界

程序编写题看似变化多端,其实有一个非常通用的作答流程。我把它总结为五步,按顺序执行能避免大多数低级错误。

第一步,审题。把题目读三遍,第一遍看输入,第二遍看输出,第三遍看边界要求。重点回答:输入是整数还是浮点数?输出保留几位小数?特殊输入(负数、0)有没有规定?

第二步,定变量。明确需要几个变量,每个变量叫什么、是什么类型。命名要见名知义,不要用a、b、c走天下。

第三步,画流程。把计算过程描述成文字步骤,比如“先读半径”“再算面积”“最后输出”,判断中间有没有分支,要不要循环。这个阶段不写代码,只写步骤。

第四步,写代码。把文字步骤翻译成Python语法,注意缩进一致、括号匹配、输入输出格式正确。

第五步,验边界。用几个特殊数据在脑子里跑一遍:0、负数、极大值、刚好卡在分支边界上的值。跑通了再提交。

为什么强调这五步的顺序?因为初学者最容易犯的错误是“看了题目就开始敲键盘”。一次我在答疑时遇到一个姑娘,题目要求输入两个整数输出较大的那个,她上来就写if a > b: print(a),却忘了第一步读入。结果代码根本不完整,程序一运行就报错。这不是语法问题,是审题步骤被跳过了。

3.2 经典题一:输入半径计算圆面积

这类题在第2章非常常见,它把输入输出、算术运算、格式化输出全考了一遍。下面给出一个带边界校验的参考写法:

import math r = float(input("请输入圆的半径:")) if r < 0: print("半径不能为负数") else: area = math.pi * r * r print("圆的面积为:{:.2f}".format(area))

运行示例:

请输入圆的半径:2 圆的面积为:12.57

这里有两个要点。第一,使用math.pi而不是自己写3.14159,精度更高,也更符合工程习惯。如果教材要求用3.14,那改成一个赋值语句pi = 3.14即可。第二,为什么加if r < 0?因为从几何上讲半径不可能是负数,但从程序上讲float(input())接受任何数字。如果用户输入-1,不拦截的话程序会输出一个“面积为3.14”的荒谬结果。第2章的程序题虽然基础,但“对非法输入做出反应”是从一开始就该养成的习惯。

还有一个小坑:{:.2f}表示保留两位小数,输出会自动四舍五入。有些同学会用round(area, 2),但round在某些情况下会有浮点表示的微小误差,考试和作业里更推荐格式化输出,因为它的舍入行为是稳定可预期的。

3.3 经典题二:判断闰年

闰年判断几乎是每一版Python基础教材的标配,它专门训练逻辑表达式和分支结构。闰年的规则是:能被4整除但不能被100整除,或者能被400整除。

year = int(input("请输入年份:")) if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0): print(year, "是闰年") else: print(year, "不是闰年")

运行示例:

请输入年份:2000 2000 是闰年

用四个典型数据来跑边界测试:1900(不是闰年)、2000(是闰年)、2004(是闰年)、2001(不是闰年)。1900能被4和100整除,但不能被400整除,所以不是闰年;2000能被400整除,所以是闰年。这两个值最容易区分你是否真正理解了闰年规则,而不是背了一个“能被4整除”的半吊子结论。

这道题最常见的错误是把and和or的优先级写错。Python里and优先级高于or,所以上面这个表达式等价于( (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0) ),括号其实可以省略,但加了括号可读性更高,也避免别人误解。我建议初学者一律加上括号,这是“给自己看”的注释,不只是为了让机器跑。

3.4 经典题三:累加求和

累加求和题有两种经典考法。第一种是固定范围,比如求1到100的和;第二种是用户输入上限,比如求1到n的和。这里给出两版参考代码。

用for循环实现用户输入版本:

n = int(input("请输入一个正整数:")) total = 0 for i in range(1, n + 1): total = total + i print("1到", n, "的和是:", total)

用while循环做同一个任务:

n = int(input("请输入一个正整数:")) total = 0 i = 1 while i <= n: total = total + i i = i + 1 print("1到", n, "的和是:", total)

比较两段代码,你会发现核心逻辑完全一致:一个计数变量i负责迭代,一个累加变量total负责存和。区别在于for自动帮我们递增i,而while需要手动写i = i + 1。如果你忘了写这一行,程序就会变成死循环,在解释器里表现为“程序卡住不退出”。遇到这种情况,先检查循环体里面有没有让条件最终变成False的语句。

还有一个细节:print必须放在循环外面。如果放在循环体内部,它会每加一次就打印一次,输出一大堆中间结果,这不是题目想要的最终和。这种错误我在作业里见过太多次,本质上是结构没分清。

3.5 经典题四:打印简单图形

图形打印题是用来锻炼嵌套循环的经典素材。所谓“打印直角三角形”,其实就是在训练你管理行和列两个维度的关系。

for i in range(1, 6): for j in range(1, i + 1): print("*", end="") print()

输出结果:

* ** *** **** *****

解释一下背后的道理:外层循环控制行数,i从1到5;内层循环控制每一行打印多少个星号,范围是range(1, i + 1),也就是第1行打印1个,第2行打印2个,依此类推。print("*", end="")让星号连续打印不换行;内层循环结束后执行一个空的print(),作用是换行。

这道题最容易出问题的地方是range(1, i + 1)的+ 1。有人写成range(1, i),那第1行就打印0个星号,第2行打印1个,整体输出会整体少一个星号,第一行还是空的。为什么必须+ 1?因为range左闭右开,不包含结束值,想要打印i个星号,上限就必须是i + 1。这个规律在阅读题里也是高频考点。

4. 这章最容易扣分的三个细节:缩进、命名、边界条件

4.1 缩进错乱:看着对,跑起来全错

Python用缩进表示代码块,这是它跟C/C++最大的区别。很多程序编写题,逻辑想对了,代码也写出来了,但缩进一乱,程序要么直接报IndentationError,要么逻辑完全变样。

常见错例1,循环体里的语句丢掉缩进:

for i in range(3): print(i)

这一看就是错的,print(i)没有缩进,Python解释器直接报错。常见错例2,混用Tab和空格:

if x > 0: print("正数") print("结束")

第二行的print用了4个空格,第三行用了3个空格,虽然肉眼看起来像对齐的,但Python会认为这不是同一个代码块,于是报TabError或IndentationError。

解决方法是把编辑器统一设置为“用空格代替Tab”。大部分现代编辑器(比如VSCode、PyCharm)都默认这么做,你要做的就是不再手动按Tab键缩进,而是让编辑器自动缩进。提交前还有一个土办法:把代码全选,看一下是否每层缩进都是整齐的4个空格。这个习惯能避免大半的语法错误。

4.2 命名随意:运行没问题,检查一眼看穿

程序能运行不代表能拿分。第2章的程序部分虽然对命名规范要求不算苛刻,但一份作业如果全是a、b、c、x、y,老师第一眼的印象分就会很低,更重要的是你自己回头看代码也很痛苦。

我见过一份练习,求圆柱体积,变量全部用单个字母:

r = float(input()) h = float(input()) v = 3.14 * r * r * h print(v)

功能没错,但哪一个是半径,哪一个是高,哪一个是体积?完全要靠猜。改成下面这种写法,代码的可读性立刻不一样:

radius = float(input("请输入圆柱底面半径:")) height = float(input("请输入圆柱高度:")) volume = 3.14159 * radius * radius * height print("圆柱的体积为:{:.2f}".format(volume))

变量名本身就是注释。Python社区推荐的命名风格是小写字母加下划线,比如total_score、user_name。写作业时,变量名应当一看就知道它保存的是什么。命名清晰的时候,连调试都省力很多:报错说radius有问题,你马上就知道是半径那边出了问题,而不是在那猜r是谁。

4.3 边界条件:0、空输入、第一个元素

边界条件是我反复强调的“第五步验边界”的核心。第2章的题目看似基础,边界条件却隐藏在输入输出里,稍不留神就掉坑。

第一类边界是0。计算圆面积时半径输入0,程序应该输出0.00,这没问题;但如果题目求“平均值”,输入个数为0,就直接涉及除以0,程序会报ZeroDivisionError。处理办法是提前判断:数量为0时就不要再做除法运算,而是输出提示信息。

第二类边界是负数。判断绝对值的题目、开平方的题目,遇到负数都会出问题。第2章里最典型的处理方式就是加一个if分支,合法情况走主流程,非法情况输出错误提示。代码里多这几行,分数立刻不一样。

第三类边界是range的起始值。循环从0开始还是从1开始,差别巨大。比如要打印1到n的所有数,用range(1, n + 1);要打印0到n-1的所有数,用range(n)。线段上的“边界点”是最容易出错的地方,一定要在提交前用最小输入(比如n=1)在脑子里跑一遍。

5. 写完答案怎么核对?一份能真正“自查”的清单

5.1 从答案回溯考点

做完整份练习,很多人只关心“运行结果对不对”,却忽略了一个更关键的问题:这道题到底想考我什么?核对答案的第一步,其实是在每道题旁边写一句考点说明。比如“输入半径求面积”考的是输入转换、算术运算、格式化输出;“判断闰年”考的是逻辑表达式和分支结构;“打印三角形”考的是嵌套循环和换行控制。

这一步看起来多余,但它有一个实际好处:当你觉得某道题不知道怎么写时,回到题目对应的知识点,翻教材目录找对应章节,马上就知道该复习哪一页。很多同学卡在“这题我不会”,本质是“不知道自己缺哪个知识点”。从答案回溯考点,就是把这个“不知道”变成“知道”。

5.2 用边界测试代替肉眼检查

运行一遍没报错,并不代表程序正确。你需要主动设计测试数据,而不是只拿题目给的示例跑一次。我建议每个程序大题至少准备三类数据:

测试类型示例数据预期结果
正常值半径=2面积≈12.57
边界值半径=0面积=0.00
非法值半径=-1输出“半径不能为负数”

判断闰年的题目,正常值测一个闰年和一个平年,边界值测1900和2000,因为这俩一个不是闰年一个是闰年,专门用来检验“能被100整除”那条规则的写法是否正确。累加和题目,至少要让n等于1,确认输出是“1到1的和是1”而不是0。

这套测试方法成本极低,效果却非常好。我能想到的大多数作业扣分,都集中在边界数据上。一个正常数据能跑通只说明主流程对了,边界数据能跑通才说明你的思路真正覆盖了题目的所有要求。

5.3 参考答案的“安全用法”

最后说回“答案”本身。网上流传的第2章程序部分答案,质量参差不齐,有些甚至是从旧版本教材里抄来的,代码能跑但不符合当前版本的语法习惯。直接复制粘贴,风险很大;更合理的用法,是先把答案当成“运行结果已知的程序”来做程序阅读练习,一行一行读懂之后再提交自己的版本。

等到你自己写完了,再拿参考答案做对比,重点看三处:变量命名是不是比别人更清晰、边界判断是不是比别人更完整、代码结构是不是比参考答案更易读。如果参考答案用了某段你没见过的写法,比如把area = pi * r * r改成area = pi * r**2,那正好顺藤摸瓜,把这个新知识补进自己的知识体系。

我自己批改练习时,最欣慰的其实不是看到全对的代码,而是看到旁边写着“这题我一开始写成while但发现for更简单”这样的批注。第2章程序部分的价值,就在于让你第一次意识到:程序不是“写完就完事”,而是要能解释、能调试、能应对变化。耐心把每道题亲手跑通一次,比收藏十份网上答案都管用。遇到卡壳,我的建议是先关掉所有答案,回到教材把变量、循环、分支三节再翻一遍,然后用题目里最简单的那个输入在纸上走一遍流程,卡点往往马上就会暴露出来。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询