A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© Jobs 中级黑马   /  2014-9-30 10:04  /  1533 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

调试程序的方法与医生看病的道理类似:先问清基本情况,再进行大致的检查,然后分析检查的结果、确定范围,再进行专项检查,再分析检查结果,如此反复,最后确定问题所在并进行治疗、检查疗效。

必须指出的是:用户调试自己的程序时,应对程序的设计(工作)思路非常清楚,知道每一段、每一行程序所应起到(尽管不见得都能实现)的作用,这是基本的前提。若自己对设计都不清楚、甚至不知道每一段、每一行程序应发挥的作用,是谈不上调试程序的。 1) 观察了解程序的“病症”表现首先是看清情况,程序的任务、程序的预期表现与程序工作的实际表现,大概是什么方面的“病”——对于常见的小“病”,经验丰富的专家不用后续检查就能知道问题所在。经验当然重要,但对于初学者而言,掌握正确的调试思路则更加重要,因为初学者很难通过观察程序而发现问题所在。 2) 弄清程序的主要工作流程在学习过程中设计的程序一般都不太复杂,从总体算法上总是可以划分为几个大的模块(也可称为步骤,可以是一段程序或一个子程序——函数):接收用户的要求和任务(读取相应的参数、输入相应的数据)、对数据进行计算和处理、按格式要求输出相应的结果。对于每一个大的模块,又可以分为许多子模块。
  • #include <stdio.h>
  • int main(void){
  • int a[10000], i, j, num, x, tmp, mini;
  • //从键盘读入用户输入的数据,数据存放在数组a中,num记录读入数据的个数
  • printf("\nPlease input numbers:");
  • for (i=0; i<10000; j++){
  • scanf("%f", x);
  • if (x = -222){ //如果读入的数为结束标志,则结束输入
  • break;
  • }
  • a = x;
  • num++; //num记录已读入的有效数据的个数
  • }
  • //计算与处理:对数据进行从小到大排序,排序使用的方法是选择法
  • for (i=0; i<num; i++){ //依次找出第0,1,2…个最小的并放到相应位置a
  • mini = i; //开始找第i个最小的,先假定a最小,mini负责记最小的所在位置
  • for (j=i+1; j<num; j++){ //从i后的所有数中,找出最小的一个,位置记入mini
  • if (a[j] > a[mini]){ //如果有谁比当前认为最小的还小,则记住其位置
  • mini = j;
  • }
  • }
  • //将找到的最小数与第i个数交换位置,实现第i个最小数到位
  • tmp = a;
  • a[mini] = a;
  • a = tmp;
  • }
  • //输出计算、处理的结果
  • printf("Output:\n");
  • for (i=1; i<=num; i++){ //依次输出第1个到最后一个数
  • printf("%-6d", a);
  • //如果当前为第6个数或最后一个数,则不输出“,”而换行
  • if (i % 6 != 0 && i != num){
  • printf("\n");
  • }else{
  • printf(",");
  • }
  • }
  • }

例如上面的程序是有问题的,它是为了实现以下功能(其中的注释写明了主要模块的功能以及每个模块的实现方法):
  • 程序运行时先显示Please input numbers:,再从键盘上读入一组整数(只考虑int型),数与数之间只使用空格或回车作分隔。数可正可负,最多10000个,但若读入的数为-222时,则表示输入结束且-222不算在该组数内。
  • 对这一组数按从小到大的顺序进行排序。
  • 将排序后的这一组数输出到屏幕上,输出格式为每行6个数,数与数之间使用逗号(,)分隔,两个逗号之间的宽度(不算逗号)为6且使用左对齐格式。注意,行尾没有逗号。

程序的运行效果应类似地如下图所示,其中的100 120 89 72 -19 200 500 210 235 6 24 1234 78 234 -234 -2342 346 23524 7823 -3411 23423 -222是从键盘输入的内容。


3) 进行大致的检查,确定问题存在的模块检查的任务,就是查看程序的实际工作状态(屏幕输出是否正确、各变量的值是否正确)与预期的设计是否一致,若不一致,则肯定有问题。

对于较长、较复杂的程序,检查时不应从开始一行一行检查,这种方法效率低、不科学,也不易发现问题。正确的方法是:先分大模块检查,确定大模块有无问题,再针对有问题的大模块,检查其内部的工作过程。例如,对于程序3-1,应先检查输入完成时工作是否正确,即让程序运行至“计算与处理”时暂停(从键盘输入一组数据),查看相应的结果(这段程序的运行目的就是将输入数据存放至数组a中并由num记录数据个数,因此应检查数组a和num的内容)是否正确,若不正确,则至少找到一部分问题。排除输入的故障后,则可让程序运行到“输出”时暂停,检查相应的结果(即数组a中的数据是否按要求排好顺序)。

在检查过程中,用户应根据自己的经验,灵活调整检查策略,提高工作效率,例如可以使用二分法定位故障,也可观察后估计问题位置再进行检查。 4) 检查故障模块,确定问题并解决对于复杂故障模块内部的运行检查,可以再分子模块(部分)进行分部检查。检查模块的设计是否正确的基本思路是:一步一步运行程序,看程序的运行流程是否如设计期望,看每步程序的运行结果(屏幕输出和相关变量)是否与设计(心算)的一致。例如程序3-1的输入部分,假定未看到问题,则可检查:输入一个数据后,x中的数据是否是输入的数据——若不是,则该条语句肯定有问题,仔细检查应能发现问题;当输入不是结束标志时,则否将数据存入了a、i和计数器num的值是否正确;当输入的是结束标志时,是否如期望的结束输入。

  

ppppppppppp.jpg (43.63 KB, 下载次数: 27)

ppppppppppp.jpg

3 个回复

倒序浏览
没有写出中心
回复 使用道具 举报

请你写出中心,做出补充。
回复 使用道具 举报
谢谢楼主分享,学习了
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马