查错 0

来源:互联网 发布:拍牌照软件 编辑:程序博客网 时间:2024/05/16 18:45
 
题目:


题目大意:

输入分数,排序,用 * 表示重复分数个数。实际就是制作条形图。


问题代码

#include<stdio.h>

void sort(int a[], int n);

int main()

{

     int a[100], i, j,counter;

     for(i=0; scanf("%d",&a[i]) !=EOF; i++)     // i 的值就是分数个数

     

     sort(a,i);

    

     for(j=0;j<i;j++) // debug information 观察排序后的数组

              printf("%d ",a[j]);

     printf("\n");

    for(j=1;j<i;j++)

         {

          counter=1;                       // 再次强调 记得初始化

          while(a[j]==a[j-1])            // 重复数字计数

                      { counter++; j++; }


          printf("%d\t",a[j-1]);    // 这样有一个缺陷,若最后一个分数是唯一的,会被略过,这种情况要单独讨论

          while(counter>0)

                { printf("*"); counter--; }

           printf("\n");

          }

     if(a[i-1]!=a[i-2]) printf("%d\t*\n",a[i-1]);   //单独讨论的情况

     return 0;

}


// 冒泡排序 n是数组元素个数

void sort(int a[], int n)

{

       int i,j,t;

       for(i=0;i<n;i++)

               {

                for(j=0;j<n-1-i;j++) //注意a[j]=a[j+1];j 最大只能取到n-2,避免越界

                       {

                               printf("i=%d j=%d\n",i,j);

                                     // debug information above

                                     //因为最后一位总是没有参与排序,我想看看最后一位到底有没有被访问到。

                                     //在sort第二重循环内插入语句输出i,j,观察 j 能否达到 n-2,i帮助判断在循环的第几次

                                     //得到很奇怪的结果

                              if( a[j]>a[j+1] )

                                     { t=a[j]; a[j]=a[j+1]; a[j+1]=t; }

                         }

              printf(".\n");    //输出一个点便于观察

             }

}


分析:

main函数中i代表分数的个数,值传递到sort中即为n个数排序,数组下标最大为n-1,函数体内

i=0时,j最大取得n-2,在比较大小时有 a[n-2]>a[n-1],所以最后一个元素应该是参与了排序的

for(i=0;i<n;i++)

       for(j=0;j<n-1-i;j++)

               if( a[j]>a[j+1] )

                     { t=a[j]; a[j]=a[j+1]; a[j+1]=t; }

可是结果严重不符……

输出结果

i的值确实是分数个数,a[i]也确实在界外,a[i-1]确实是输入的最后一个分数

共有6个数,j 只达到3,最后的数居然被略去了,没有参与排序,但我觉得没有问题啊!

于是我另建一个.c文件,把sort函数copy过去,检验一下排序结果,没有问题……所以问题定位在调用sort的语句上

既然最后一个元素被忽略了,死马当活马医,在调用sort时(标记为绿色的语句),改为sort(a,i+1); 就AC了

循环的顺序也很奇怪,这个问题不明白,猜测是编译器做了手脚

 

 

 

第二天,再次审视代码……

注意到另一个问题:在输入ctrl + z 前,sort函数已经被调用。并且在输出的值时,除了j的最大值比预期少1外,后半部分i , j的变化规律符合预期。于是仔细检查sort的调用语句,许久之后,发现原来漏了分号

 

for(i=0; scanf("%d",&a[i]) !=EOF; i++) // i 的值就是分数个数

sort(a,i);

for语句后面少了分号,因此会意外地调用sort函数。并且最后一次调用sort时 i 的值是分数个数减一,跳出循环后i自增1,所以看起来 i 确实以分数个数的身份传递入sort中……

 

原来竟然居然只是如此低级的错误……

 

现在对于调试的理解:

对于程序运行时出现的异常行为,通过观察变量超出预期的变化(太大太小,太早太晚),猜测可能出错的地方,一一排除,逐渐的锁定错误所在。

 

自问:希望提高查错效率,怎么办?

自答:更细心;多调试,丰富判断的经验;


技巧:

1、利用printf输出变量值,帮助判断bug所在,可以选择条件编译指令

      #if (常量)

      #endif

2、挑选待观察的变量前要想好。在哪里插入输出语句,输出的格式也要处理好,才便于观察。

3、测试用例,要针对自己的思路来选,看看有没有潜在疏忽点。

4、调试信息的保存,有时需要多次信息的反复对比,可以考虑使用文件操作,把调试信息输出至文件中


(有点泛泛而谈,但以后在调试时多做以上的思考,应该会受益匪浅。)

原创粉丝点击