改错题100套.docx
- 文档编号:8498878
- 上传时间:2023-01-31
- 格式:DOCX
- 页数:122
- 大小:76.37KB
改错题100套.docx
《改错题100套.docx》由会员分享,可在线阅读,更多相关《改错题100套.docx(122页珍藏版)》请在冰豆网上搜索。
改错题100套
前言
改错题难以分类,只好按其顺序逐题分析。
改错题分值30分,通常一题中有两个错误,偶而也有一个错或三个错的,其得分按比例分配,如该题共有三个错,能改正一个错则得10分;能改正二个错则得20分,以此类推。
凡错误必在/***************found***************/的下一行,这样就方便了我们的改错工作,但这并不能让我们很容易找出错误原因并做出相应的修正。
文档中给出了解答和解析,但这只是一种“纸上查错”法,没有能充分利用上机环境下的系统查错手段,所以我又增加了前30题上机查错的方法分析,便于大家能比较迅速掌握改错题的解答。
改错题的错误性质可分为一,两大类,一是语法错,但这类错误在考试中出现比较少,更多的是逻辑错误。
改错前应当对程序进行编译,利用系统的查错功能,知道错误的原因,查看有无语法错误,是什么样的语法错误,再进行相应的修正。
如没有语法错误,或已经将语法错误修改完毕,此时应该按要求运行程序,根据运行的结果与应当得到的正确结果作比较,往往也能帮助我们找到错误的原因,以下我将调试过程详细说明。
为便于观看报错信息方便,在进行源程序编译前,应调整源程序显示窗口的大小,使屏幕下方的组建选项卡的高度能达到整个屏幕的一半。
目录
第1套第2套第3套第4套第5套第6套第7套第8套第9套第10套
第11套第12套第13套第14套第15套第16套第17套第18套第19套第20套
第21套第22套第23套第24套第25套第26套第27套第28套第29套第30套
第31套第32套第33套第34套第35套第36套第37套第38套第39套第40套
第41套第42套第43套第44套第45套第46套第47套第48套第49套第50套
第51套第52套第53套第54套第55套第56套第57套第58套第59套第60套
第61套第62套第63套第64套第65套第66套第67套第68套第69套第70套
第71套第72套第73套第74套第75套第76套第77套第78套第79套第80套
第81套第82套第83套第84套第85套第86套第87套第88套第89套第90套
第91套第92套第93套第94套第95套第96套第97套第98套第99套第100套
二级C上机试题[改错]
第一套返回目录
下列给定程序中,函数fun()的功能是逐个比较a,b两个字符串对应位置中的字符,把ASCII值小或相等的字符依次存放到c数组中,形成一个新的字符串。
例如:
a中的字符串为fshADfg,b中的字符串为sdAEdi,则c中的字符串应为fdAADf。
请改正程序中的错误,使它能得到正确结果。
注意:
不要改动main函数,不得增行或删行,也不得更改程序的结构。
试题程序如下:
#include
#include
voidfun(char*p,char*q,char*c)
{intk=0;
while(*p||*q)
/***************found***************/
{if(*p<=*q)
c[k]=*q;
elsec[k]=*p;
if(*p)p++;
if(*q)q++;
/***************found***************/
k++
}
}
main()
{chara[10]="fshADfg",b[10]="sdAEdi", c[80]={´\0´};
fun(a,b,c);
printf("Thestringa:
");puts(a);
printf("Thestringb:
");puts(b);
printf("Theresult:
");puts(c);
}
正确答案:
【1】{if(*p>=*q)【2】k++;
解析:
错误1:
依题意,把ASCII值小或相等的字符存放到c数组中,故if语句的关系运算符应为">="。
错误2:
C语言规定,每个语句要用分号结束。
调试过程:
打开1_err.c源程序,并进行编译、组建,此时组建选项卡中显示如下报错信息:
syntaxerror:
missing';'before'}'
1_err.obj-1error(s),0warning(s)
其中“1_err.obj-1error(s),0warning(s)”,表明有一个致命性错误语法,无警告性语法错误。
其错误性质是“syntaxerror:
missing';'before'}'”,其意思是:
语法错,在'}'前少了';',用鼠标双击“syntaxerror:
missing';'before'}'”,光标停留在“}”这一行上,结合程序中的错误定位提示,知道遗漏“;”的一定是“k++”这一行,于是补一个“;”,再次编译,此时系统不再报告还有语法错误。
运行该程序,弹出窗口显示如下内容:
Thestringa:
fshADfg
Thestringb:
sdAEdi
Theresult:
sshEdig
与期望结果不同。
仔细观察,可发现是将a、b字符串中对应位置上ASCII码较大的字符复制到c数组中去了。
按回车,回到编辑状态。
将第一个错误所在行中的语句“if(*p<=*q)”改成“if(*p>=*q)”。
再重新组建、运行程序并观察结果,这次发现程序能正确运行。
最后保存修改后的源程序。
第二套返回目录
下列给定程序中,函数fun()的功能是根据整型形参m,计算如下公式的值。
y=1-1/(2×2)+1/(3×3)-1/(4×4)+…+(-1)(m+1)/(m×m)例如:
m中的值为5,则应输出0.838611。
请改正程序中的错误,使它能得到正确结果。
注意:
不要改动main函数,不得增行或删行,也不得更改程序的结构。
试题程序:
#include
#include
doublefun(intm)
{doubley=1.0;
/***************found***************/
intj=1;
inti;
for(i=2;i<=m;i++)
{j=-1*j;
/***************found***************/
y+=1/(i*i);
}
return(y);
}
main()
{intn=5;
printf("\nTheresultis%lf\n",fun(n));
}
正确答案:
【1】doublej=1.0;【2】y+=j/(i*i);
解析:
错误1:
为了做后面的除法运算,j要定义为实型数,否则除得的结果将为整数。
错误2:
题中公式是加减相间的运算,通过j来实现。
调试过程:
编译后系统表明程序无任何语法错误,此时需要通过运行程序来查找程序的逻辑错误。
运行结果显示:
Theresultis1.000000。
但正确结果应为:
0.838611。
这表明程序中的数据也许是以整数的形式出现来执行除法运算,所以小数部分有错,为0。
观察到第一个Found下行中的语句是intj=1;,是否应将它改为doublej=1.0;再考虑程序中的j倒底起什么作用?
下面发现有关j的语句只有一句“j=-1*j;”,j永远是以1或-1的形式出现,而本题是一个级数求和,且级数中各项的符号是正负交替,j的作用明显是控制各项的符号的,j应当还要在计算各项值的表达式中出现,结合到将第二个错误所在行,将语句y+=1/(i*i)改成y+=1.0/(i*i),就使得分子和分母均为实数。
重新组建并运行程序并观察到结果是0,838611,修改正确。
第三套返回目录
下列给定程序中,函数fun的功能是按以下递归公式求函数值。
Fun(n)=15n=1
Fun(n)=Fun(n-1)×2n>1
例如:
当给n输入5时,函数值为240;当给n输入3时,函数值为60。
请改正程序中的错误,使它能得到正确结果。
注意:
不要改动main函数,不得增行或删行,也不得更改程序的结构。
试题程序:
#include
/***************found***************/
fun(intn);
{intc;
/***************found***************/
if(n=1)
c=15;
else
c=fun(n-1)*2;
return(c);
}
main()
{intn;
printf("Entern:
");
scanf("%d",&n);
printf("Theresult:
%d\n\n",fun(n));
}
正确答案:
【1】fun(intn)【2】if(n==1)
解析:
错误1:
该行是函数的首部,不是一条语句,因此不能以分号结束。
错误2:
if后面应该紧跟一个条件判断表达式,若写成"if(n=1)",则说明该表达式的值永远为真,也就是说这个条件永远成立,没有递归执行。
调试过程:
编译后系统告诉我们程序有一个致命性错误。
有两条出错信息提示:
双击第一条错信息提示“found'{'atfilescope(missingfunctionheader?
)”(意为少了函数的首部)后光标停留在“{intc;”一行上,结合第一个“/***************found***************/”的位置,可知出该错误是在“fun(intn);”函数的首行上。
函数首行出错在二级C考试上机考试中是常见错误,通常有三类差错:
1、函数类型说明不正确;2、形参与实参不匹配;3、多了一个分号。
如何检查第一类错误?
函数内有一条return语句,返回int类型变量c的值,而函数类型虽然没有说明,但是允许其默认值为int型;如何检查第二类错误?
看main主函数中是如何调用函数的,调用形式是fun(n),且主函数中说明n是整型变量,说明该函数只能有一个整型形参,显然本题也没有犯下参数不匹配的错误;第三类错误最容易检查,确实多了一个分号,按理说,函数的首行后面应当是函数体的开始,是应当出现一个“{”,现在没有,无怪乎系统要报告“少了函数的首部”,删除了多余的分号后再次编译,知道所有的语法错误都消除了,运行程序,并根据题目要求输入3,结果是15而不是理想中的360,说明程序中有逻辑错误,是在第二个found下面的一句if(n=1)中。
通常在if语句的条件式中应当出现比较运算,而这里却出现了赋值运算符号,参考题目的要求,将改成if(n==1)。
这次修改后你将会发现大功告成了。
第四套返回目录
下列给定程序中函数fun()的功能是计算1/n!
的值。
例如:
给n输入5,则输出0.008333。
请改正程序中的错误,使它能得到正确结果。
注意:
不要改动main函数,不得增行或删行,也不得更改程序的结构。
试题程序:
#include
#include
/***************found***************/
intfun(intn)
{doubleresult=1.0;
if(n==0)
return1.0;
while(n>1&&n<170)
/***************found***************/
result*=n++;
result=1/result;
returnresult;
}
main()
{intn;
printf("InputN:
");
scanf("%d",&n);
printf("\n1/%d!
=%lf\n",n,fun(n));
}
正确答案:
【1】doublefun(intn)
【2】result*=n--;
解析:
错误1:
函数的返回值为实型数据,所以函数的返回类型应为double。
错误2:
根据阶乘的概念,从n开始,每递减1的数相乘,直到1,因此此处n递减,而不是递增。
调试过程:
程序中第一个错误是函数的首行。
根据上一题介绍的方法逐一检查。
函数中有两条return语句,返回值均为double类型,而函数首行的类型说明却是int,将它改为double并重新编译,系统不再报告有任何语法错误,运行程序并输入5但其结果是0.000000而不是理想中的0.008333,检查第二个错误所在行中的语句result*=n++;,每执行一次乘法运算后n增值1,直到n=170才停止运算,并不是计算n!
的倒数,而是计算5*6*…*170的倒数了,改为result*=n--;,经过组建、运算程序,发现修改正确。
第五套返回目录
下列给定程序中函数fun()的功能是计算正整数num的各位上的数字之平方和。
例如:
输入352,则输出应该是38;若输入328,则输出应该是77。
请改正程序中的错误,使它能得到正确结果。
注意:
不要改动main函数,不得增行或删行,也不得更改程序的结构。
试题程序:
#include
#include
longfun(longnum)
{
/***************found***************/
longk=1;
do
{k+=(num%10)*(num%10);
num/=10;
/***************found***************/
}while(num)
return(k);
}
main()
{longn;
printf("\Pleaseenteranumber:
");
scanf("%ld",&n);
printf("\n%ld\n",fun(n));
}
正确答案:
【1】longk=0;【2】while(num);
解析:
错误1:
k用来存放各位数字的平方和,初值应为0。
错误2:
do-while语句的语法,while()后加分号。
调试过程:
经语法检查发现第二个错误所在行“}while(num)”少了分号,补上后消除了语法错误。
运行时发现无论是按照要求352或328,输出结果值都比预期值多了1。
经检查第2个错误所在行中的求和单元初值是1而不是0,相差恰好是1,改为k=0后程序能得出正确结果。
第六套返回目录
下列给定程序中,函数fun()的功能是将字符串s中位于偶数位置的字符或ASCII码为奇数的字符放入字符串t中(规定第一个字符放在第0位中)。
例如:
字符串中的数据为ADFESHDI,则输出应当是AFESDI。
请改正程序中的错误,使它能得到正确结果。
注意:
不要改动main函数,不得增行或删行,也不得更改程序的结构。
试题程序:
#include
#include
#include
#defineN80
/***************found***************/
voidfun(chars,chart[])
{inti,j=0;
for(i=0;i /***************found***************/ if(i%2=0||s[i]%2! =0) t[j++]=s[i]; t[j]=´\0´; } main() {chars[N],t[N]; printf("\nPleaseenterstrings: "); gets(s); fun(s,t); printf("\nTheresultis: %s\n",t); } 正确答案: 【1】voidfun(char*s,chart[]) 【2】if(i%2==0||s[i]%2! =0) 解析: 错误1: 由于本题中函数的功能是对字符串进行处理,而不是对单个字符进行处理,因此,函数的参数应为字符串指针。 错误2: if语句中要用关系运算符,而不是赋值运算符。 调试过程: 语法检查时有许多出错信息,一下子头都搞晕了,不知道如何处理才好。 此时应当利用题目中告诉我们的出错位置提示,第一个错是函数的首行,按前两题的方法进行检查。 函数的类型说明是void,且函数无返回值,应当说函数类型说明无差错。 再考虑形参与实参的匹配问题。 从主函数中可以看出两个参数均为字符数组,而fun函数的第一个形参却是一个字符变量,改正的方法有两种,1、改为chars[],2、改为char*s。 第二个错是if语句,语句句中的条件表达式一般应使用比较运算符,将i%2=0改为i%2==0。 运行后发现程序修改正确。 第七套返回目录 下列给定程序中,函数fun()的功能是找出100~n(不大于1000)之间百位数字加十位数字等于个位数字的所有整数,把这些整数放在s所指的数组中,个数作为函数值返回。 请改正程序中的错误,使它能得到正确结果。 注意: 不要改动main函数,不得增行或删行,也不得更改程序的结构。 试题程序: #include #defineN100 intfun(int*s,intn) {inti,j,k,a,b,c; j=0; for(i=100;i { /***************found***************/ k=n; a=k%10; k/=10; b=k%10; c=k/10; if(a==b+c) /***************found***************/ s[j]=i; } returnj; } main() {inta[N],n,num=0,i; do {printf("\nEntern(<=1000): "); scanf("%d",&n); } while(n>1000); num=fun(a,n); printf("\n\nTheresult: \n"); for(i=0;i printf("%5d",a[i]); printf("\n\n"); } 正确答案: 【1】k=i;【2】s[j++]=i; 解析: 错误1: k就是当前要被判断的数,是随着i值的变化而变化的。 错误2: 在循环中,j是数组的下标要递增。 调试过程: 本程序无语法错。 运行该程序输入1000后却无任何结果输出。 第一个逻辑错误是k=n;这一句。 下面几句是分解k的各位数字。 但n是主函数中传递过来的循环范围的上限,需要判断的应当是上面一句for(i=100;i 运行后依然无结果。 第二个逻辑错误是s[j]=i;这一句。 其中j记录了符合条件的数的个数,但每当找到一个符合条件的数后,j却没有增1。 故将此句改为s[j++]=i;。 运行后发现程序修改正确。 第八套返回目录 下列给定程序中,函数fun()的功能是求出数组中最小数和次最小数,并把最小数和a[0]中的数对调,次最小数和a[1]中的数对调。 请改正程序中的错误,使它能得到正确结果。 注意: 不要改动main函数,不得增行或删行,也不得更改程序的结构。 试题程序: #include #include #defineN20 voidfun(int*a,intn) {inti,m,t,k; /***************found***************/ for(i=0;i {m=i; for(k=i;k if(a[k] /***************found***************/ k=m; t=a[i]; a[i]=a[m]; a[m]=t; } } main() {intx,b[N]={11,5,12,0,3,6,9,7,10,8},n=10,i; for(i=0;i printf("%d",b[i]); printf("\n"); fun(b,n); for(i=0;i printf("%d",b[i]); printf("\n"); } 正确答案: 【1】for(i=0;i<2;i++)【2】m=k; 解析: 错误1: 由于题目要求将最小数和次最小数分别与a[0]和a[1]中的数对调,因此这层循环只需循环两次。 错误2: 赋值语句的执行方向是从右向左,即把右边的值赋给左边的变量。 调试过程: 本程序无语法错。 运行该程序显示原始数据“1151203697108”后再也没有显示,按回车键也不能返回,表示发现程序进入了死循环。 单击显示窗口右上角的Closebox,强制退出,回到编辑状态,利用found()信息来改错。 第一个逻辑错误行中的for(i=0;i 第二个逻辑错误行是k=m;分析这两个变量的作用,在上面有m=i一句语句,m的作用是保存符合条件的下标,因此当if(a[k] 若本题不容易从分析着手,则就硬记,100道题不可能每题者需要硬记,少数几题还是能记下来的。 第九套返回目录 下列给定程序中,函数fun()的功能是计算并输出high以内的素数之和。 high由主函数传给fun()函数。 若high的值为100,则函数的值为1060。 请改正程序中的错误,使它能得到正确结果。 注意: 不要改动main函数,不得增行或删行,也不得更改程序的结构。 试题程序: #include #include #include intfun(inthigh) {intsum=0,n=0,j,yes; while(high>=2) {yes=1; for(j=2;j<=high/2;j++) /***************found***************/ ifhigh%j==0 {yes=0; break; } /***************found***************/ if(yes==0) {sum+=high; n++; } high--; } returnsum; } main() { printf("%d\n",fun(1
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 改错 100