清华谭浩强C语言课件.常见错误与程序调试

上传人:w****i 文档编号:91877322 上传时间:2019-07-03 格式:PPT 页数:57 大小:203.50KB
返回 下载 相关 举报
清华谭浩强C语言课件.常见错误与程序调试_第1页
第1页 / 共57页
清华谭浩强C语言课件.常见错误与程序调试_第2页
第2页 / 共57页
清华谭浩强C语言课件.常见错误与程序调试_第3页
第3页 / 共57页
清华谭浩强C语言课件.常见错误与程序调试_第4页
第4页 / 共57页
清华谭浩强C语言课件.常见错误与程序调试_第5页
第5页 / 共57页
点击查看更多>>
资源描述

《清华谭浩强C语言课件.常见错误与程序调试》由会员分享,可在线阅读,更多相关《清华谭浩强C语言课件.常见错误与程序调试(57页珍藏版)》请在金锄头文库上搜索。

1、,第十四章,常见错误和程序调试,主要内容,14. 常见错误分析 14. 程序调试,要真正学好C、用好C并不容易,“灵活”固然是好事,但也使人难以掌握,尤其是初学者往往出了错还不知怎么回事。C编译程序对语法的检查不如其他高级语言那样严格(这是为了给程序人员留下“灵活”的余地)。因此,往往要由程序设计者自己设法保证程序的正确性。调试一个C程序要比调试一个PASCAL或FORTRAN程序更困难一些。需要不断积累经验,提高程序设计和调试程序的水平。 C语言有些语法规定和其他高级语言不同,学习过其他高级语言的读者往往按照使用其他高级语言的习惯来写C程序,这也是出错的一个原因。,14.1 常见错误分析 下

2、面将初学者在学习和使用C语言(不包括C+)时容易犯的错误列举出来,以起提醒的作用。这些内容在以前各章中大多已谈到,为便于查阅,在本章中集中列举,供初学者参考,以此为鉴。 (1) 忘记定义变量。如: main( ) x=3; y=6; printf(“%dn “,x+y); ,(2) 输入输出的数据的类型与所用格式说明符不一致。 例如,若a已定义为整型,b已定义为实型。,a=3;b=45; printf(“%f %dn“,a,b); 编译时不给出出错信息,但运行结果将与原意不符,输出为 0000000 16402 它们并不是按照赋值的规则进行转换(如把45转换成4),而是将数据在存储单元中的形式

3、按格式符的要求组织输出(如b占4个字节,只把最后两个字节中的数据按%d,作为整数输出)。,(3) 未注意int型数据的数值范围。 一般微型计算机上使用的C编译系统,对一个整型数据分配两个字节。因此一个整数的范围为,-215215-1,即-3276832767。常见这样的程序段: int num; num=32767; printf(“%d“,num+1); 得到的却是-32768,原因是32768超过32767。变成补码形式,(4) 输入变量时忘记使用地址符。如: scanf(“%d%d“,a,b); 这是许多初学者刚学习C语言时一个常见的疏忽,或者说是习惯性的错误,因为在其他语言中在输入时只

4、需写出变量名即可,而C语言要求指明“向哪个地址标识的单元送值”。应写成scanf(“%d%d“, (5) 输入时数据的组织与要求不符。 用scanf函数输入数据,应注意如何组织输入,数据。假如有以下scanf函数: scanf(“%d%d“, 对scanf函数中格式字符串中除了格式说明符外,,对其他字符必须按原样输入。因此,应按以下方法输入: 3,4 此时如果用“34”反而错了。还应注意,不能企图用 scanf(“input a ,scanf(“%d,%d“,若为零作为假。如果a的值为3,b的值为4,,ab,按原意不应输出“ae q u a lt ob”。而现在先将b的值赋给a,a也为4,赋值

5、表达式的值为4。if语句中的表达式值为真(非零),因此输出“ae q u a lt o b”。 这种错误在编译时是检查不出来的,但运行结果往往是错的。而且由于习惯的影响,程序设计者自己往往也不易发觉。 (7) 语句后面漏分号。 C语言规定语句末尾必须有分号。分号是C语句不可缺少的一部分。这也是和其他语言不同的。有的初学者往往忘记写这一分号。如:,a=3 b=4 编译时,编译程序在“a=3”后面未发现分号,就把下一行“b=4”也作为上一行的语句的一部分,这就出现语法错误。有时编译时指出某行有错,但在该行上并未发现错误,应该检查上一行是否漏了分号。 如果用复合语句,有的学过PASCAL语言的读者往

6、往漏写最后一个语句的分号,如: t=a; a=b; b=t ,在PASCAL中分号是两个语句间的分隔符而不是语句的一部分,而在C中,没有分号的就不是语句。 (8) 在不该加分号的地方加了分号。 例如: if(ab); printf(“a is larger than bn“);,总之,在if、for、while语句中,不要画蛇添足多加分号。,(9) 对应该有花括弧的复合语句,忘记加花括弧。 如: sum=0; i=1; while(i=100) sum=sum+i; i+; 本意是实现1+2+100,即i。但上面的语句只是重复了sum+1的操作,而且循环永不终止。因为i的值始终没有改变。错误在

7、于没有写成复合语句形式。因此while语句的范围到其后第一个分号为止。语句“i+;”不属于循环体范围之内。,100 i=0,(10) 括弧不配对。 当一个语句中使用多层括弧时常出现这类错误,纯属粗心所致。如:while(c=getchar( )!=#) putchar(c); 少了一个右括弧。,(11) 在用标识符时,忘记了大写字母和小写字母的区别。 例如: main( ) int a,b,c; a=2;b=3; C=A+B; printf(“%d+%d=%“,A,B,C); 编译时出错。编译程序把a和A认作是两个不同的变量名处理,同样b和B,c和C都分别代表两个不同的变量。,(12) 引用数

8、组元素时误用了圆括弧。 如: main( ) int i,a(10); for(i=0;i10;i+) scanf(“%d“, C语言中对数组的定义或引用数组元素时必须用方括弧。 (13) 在定义数组时,将定义的“元素个数”误认为是“可使用的最大下标值”。,main( ) int a10=1,2,3,4,5,6,7,8,9,10; int i; for(i=1;i=10;i+) printf(“%d“,ai); ,(14) 对二维或多维数组的定义和引用的方法不对。 main( ) int a5,4; printf(“%d“,a1+2,2+2); ,(15) 误以为数组名代表数组中全部元素。 例

9、如: main( ) int a4=1,3,5,7; printf(“%d%d%d%dn“,a); ,(16) 混淆字符数组与字符指针的区别。 main( ) char str4; str=“Computer and c“; printf(“%sn“,str); 编译出错。str是数组名,代表数组首地址。在编译时对str数组分配了一段内存单元,因此在程序运行期间str是一个常量,不能再被赋值。,(17) 在引用指针变量之前没有对它赋予确定的值。 main( ) char *p; scanf(“%s“,p);, 应当改为 char *p,c20; p=c; scanf(“%s“,p);,(18)

10、 switch语句的各分支中漏写break语句。,(18) switch语句的各分支中漏写break语句。 例如: switch(score) case 5:printf(“ery good!“); case 4:printf(“Good!“); case 3:printf(“Pass!“); case 2:printf(“Fail!“); defult:printf(“data error!“); ,原因是漏写了break语句。case只起标号的作用,而不起判断作用,因此在执行完第一个printf函数语句后接着执行第2、3、4、5个printf函数语句。应改为 switch(score) c

11、ase 5:printf(“erygood!“);break; case 4:printf(“Good!“); break; case 3:printf(“Pass!“); break; case 2:print(“Fail!“); break; defult:print(“data error!“);, (19) 混淆字符和字符串的表示形式。 char sex; sex=“M“; sex是字符变量,只能存放一个字符。而字符常量的形式是用单引号括起来的,应改为 sex=M; “M”是用双引号括起来的字符串,它包括两个字符:M和0,无法存放到字符变量sex中。,(20) 使用自加(+)和自减(-

12、)运算符时出的错误。 例如: main( ) intp,a5=1,3,5,7,9; p=a; printf(“%d“,*p+); 不少人认为“*p+”的作用是先使p加1,即指向第1个元素a1处,然后输出第一个元素a1的值3。其实应该是先执行p+,而p+的作用是先用p的原值,用完后使p加1。p的原值指向数组a的第0个元素a0,,(21) 有人习惯用传统的方式对函数形参进行声明,但却把对函数的形参和函数中的局部变量混在一起定义。如: max(x,y) int x,y,; =xy?x,y; return(); ,应改为 max(x,y) int x,y; int ; =xy?x:y; return(

13、); (22) 所调用的函数在调用语句之后才定义,而又在调用前未加说明。 main( ) float x,y,;,x=35;y=-76; =max(x,y); printf(“%fn“,); float max(float x,float y) return(=xy?x:y); 这个程序乍看起来没有什么问题,但在编译时有出错信息。原因是max函数是实型的,而且在main函数之后才定义,也就是max函数的定义位置在main函数中的调用max函数之后。改错的方法可以用以下二者之一:, 在main函数中增加一个对max函数的声明,即函数的原型: main( ) float max(float,flo

14、at);/*声明将要用到的max函数为实型*/ float x,y,; x=35;y=-76; =max(x,y); printf(“%fn“,); 将max函数的定义位置调到main函数之前。即:,float max(float x,float y) return(=xy?x:y); main() float x,y,; x=35;y=-76; =max(x,y); printf(“%fn“,); 这样,编译时不会出错,程序运行结果是正确的。,(23) 误认为形参值的改变会影响实参的值。 main( ) inta,b; a=3;b=4; swap(a,b); printf(“%d,%dn“,

15、a,b); swap(int x,int y) int t; t=x;x=y;y=t; ,原意是通过调用swap函数使a和b的值对换,然后在main函数中输出已对换了值的a和b。但是这样的程序是达不到目的的,因为x和y的值的变化是不传送回实参a和b的,main函数中的a和b的值并未改变。 如果想从函数得到一个以上的变化了的值,应该用指针变量。用指针变量作函数参数,使指针变量所指向的变量的值发生变化。此时变量的值改变了,主调函数中可以利用这些已改变的值。如: main( ) int a,b,*p1,*p2; a=3;b=4;,p1= (24) 函数的实参和形参类型不一致。 main( ),int

16、 a=3,b=4; c=fun(a,b); fun(float x,float y) 实参a、b为整型,形参x、y为实型。a和b的值传递给x和y时,x和y的值并非3和4。C要求实参与形参的类型一致。如果在main函数中对fun作原型,声明: fun (float, float); 程序可以正常运行,此时,按不同类型间的赋值的规则处理,在虚实结合后x=3.0, y=4.0。也可以将fun函数的位置调到main函数之前,也可获正确结果。 (25) 不同类型的指针混用。 main( ) int i=3,*p1; float a=15,*p2; p1=,p2=p1; printf(“%d,%dn“,*p1,*p2);

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 高等教育 > 大学课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号