诊断错误及其处理

上传人:公**** 文档编号:467861489 上传时间:2022-12-24 格式:DOCX 页数:14 大小:28.49KB
返回 下载 相关 举报
诊断错误及其处理_第1页
第1页 / 共14页
诊断错误及其处理_第2页
第2页 / 共14页
诊断错误及其处理_第3页
第3页 / 共14页
诊断错误及其处理_第4页
第4页 / 共14页
诊断错误及其处理_第5页
第5页 / 共14页
点击查看更多>>
资源描述

《诊断错误及其处理》由会员分享,可在线阅读,更多相关《诊断错误及其处理(14页珍藏版)》请在金锄头文库上搜索。

1、编号:时间:2021年x月x日书山有路勤为径,学海无涯苦作舟页码:第1页 共1页一、诊断错误及其处理防止程序出错的第一关是编译器。如果遇到约束违规的情况或语法错误,编译器至少会生成一个诊断错误信息。大多数编译器将其诊断信息分为两类:错误和警告。语法错误很常见,也较易修改。调试程序时首先要改正的是语法错误,调试本身是一种艺术,是程序中断时试着去修复的一种艺术。糟糕的语法会使编译器混乱,甚至可能达到生成很多错误的程度,程序设计者对这种情况不要大惊小怪,应冷静对待,其实很可能仅仅是由于某一个语句引起的,比如说漏掉了while循环中的一个大括号或语句末尾键入了冒号而非分号等。为此我们应该养成一种习惯,

2、自顶向下的修改方法,每次从错误表的开头开始,一次修改一、二个错误再编译,或许错误就能减少许多甚至全部语法错误。模块化程序设计也有助于程序的排错。调试一个充满连接和转折、全局变量等的程序要比调试一个精心设计的模块化程序困难得多。如果程序分成几个模块,各个模块负责程序的一个专项功能,一旦识别出问题可能所处的模块,就很容易地通过检查源代码方式来发现错误,这种策略也称为分治法,因为如果知道了没有问题之处,几乎等同于知道了问题发生的地方。有时我们也可以忽略警告,但这并非是一种良好的编程习惯,追踪每个警告的原因并认真考虑是否有更稳健的方法编写代码能够帮助编程者编写更好的代码。如果我们只是忽略它,当这些“无

3、害”的警告不断累积到一定程度时,可能面临出现混乱的危险。二、差1错误及其处理在C语言中,一个拥有n个元素的数组,不存在下标为n的元素,其元素下标的允许取值范围为0到n-1。请考察下列一段代码:int a10,i;for(i=1; i=0)if(x0) y=1;else y=-1;然而,这段代码实际上所做的与编程者的愿望相去甚远。原因在于C语言中有这样的规则,else总是与同一对括号内最近的未匹配的if结合。如果我们按照上面这段程序实际上被执行的逻辑来调整代码缩进,大致是这样:y=0;if(x=0)if(x0) y=1;else y=-1;也就是说,并非是当x=0) if(x0) y=1;els

4、e y=-1;现在,else与第一个if结合,即使它离第二个if更近也是如此,因为此时第二个if已经被括号“封闭”起来了。四、整数溢出及其处理C语言为编程者提供了三种不同长度的整数:short int、int和long int,但不管是哪种类型表示的整数总有一定的范围,越出该范围时称为整数的溢出。例如现有算法要求如下:求满足条件1+2+3+n32767的最大整数n,请考察如下程序段:int n=1,sum=0;while(sum=32767) sum+=n; n+;printf(“n=%dn”,n-1);乍看该程序时无错误,但事实上,上列程序中的while循环是一个无限循环,原因在于int型数

5、的表示范围为-32768到+32767,当累加和sum超过32767时,便向高位进位,而对int型数而言,最高位表示符号,故sum超过32767后便得到一个负数,while条件当然满足,从而形成无限循环。此时,最好的解决办法是将sum定义为long int型。五、词法陷井及其处理(1)不同于这是初学者最易犯的一个错误,符号作为赋值运算符,符号作为比较。一般而言,赋值运算相对于比较运算出现得更频繁,因此,字符数少的符号就被赋予了更常用的含义赋值运算。此外,在C语言中赋值符号被作为一种操作符对待,因而重复进行赋值运算(如a=b=c=5)可很容易地书写,并且赋值操作还可以嵌入到更大的表达式中。这种使

6、用上的便利性可能导致一个潜在的问题:本意是作比较运算时,却可能无意中误写成了赋值运算。该错误大多数情况下可以通过简单的要素项重排而防止。从编译器的角度出发,对于相等测试,变元在等号的哪一边无关紧要,如果两边都是变量,则需要留意符号“”的个数。但是,如果一边是常量,则存在可以防止错误的适当措施。我们何不养成把常量放在比较运算符左边的习惯呢?因为这样一来,即便漏掉了一个“”符号,保证会出现一个编译错误,因为不能给常数赋值。(2)字符与字符串C语言中的单引号和双引号含义迥异,用单引号引起的一个字符实际上代表一个整数,整数值对应于该字符在编译器采用的字符集中的序列值,因此,采用ASCII字符集的编译器

7、而言,a的含义与0141或97严格一致。而用双引号引起的字符串,代表的却是一个指向无名数组起始字符的指针,该数组被双引号之间的字符以及一个额外的二进制值为零的字符0初始化。整型数(一般为16位或32位)的存储空间中可以容纳多个字符(一般为8位),因此,有的C编译器允许在一个字符常量(以及字符串常量)中包含多个字符。也就是说,用yes代替“yes”不会被编译器检测到,后者的含义是“依次包含y、e、s以及字符0的4个连续内存单元的首地址”,而前者的含义并没有正确地定义,有些C编译器会处理成出错,但大多数C编译器的理解为“一个整数值,由y、e、s所代表的整数值按照特定编译器实现中定义的方式组合得到”

8、。因此,这两者如果在数值上有什么相似之处,也完全是一种巧合而已。(3)整数溢出C语言为编程者提供了三种不同长度的整数:short int、int和long int,但不管是哪种类型表示的整数总有一定的范围,越出该范围时称为整数的溢出。例如现有算法要求如下:求满足条件1+2+3+n32767的最大整数n,请考察如下程序段:int n=1,sum=0;while(sum=32767) sum+=n; n+;printf(“n=%dn”,n-1);乍看该程序时无错误,但事实上,上列程序中的while循环是一个无限循环,原因在于int型数的表示范围为-32768到+32767,当累加和sum超过327

9、67时,便向高位进位,而对int型数而言,最高位表示符号,故sum超过32767后便得到一个负数,while条件当然满足,从而形成无限循环。此时,最好的解决办法是将sum定义为long int型。(4)词法分析中的“贪心法”C语言中的某些符号,例如/、*、=、+等,只有一个字符长,称为单词符符号。而/*、=、+等包含了多个字符,称为多字符符号。当C编译器读入一个字符/后又跟了一个字符*,那么编译器就必须做出判断:是将其作为两个分别的符号对待,还是合起来作为一个符号对待。C语言的处理策略是“贪心法”,即从左到右一个字符一个字符地读入,如果该字符可能组成一个符号,那么再读入下一个字符,判断已经读入

10、的两个字符组成的字符串是否可能是一个符号的组成部分;如可能,再读入下一个字符,重复上述判断,直到读入的字符组成的字符串已不再可能组成一个有意义的符号为止。所以a-b:应理解为(a-)-b;而将描述命题x除以p所指向的值时,应书写为:y=x/(*p);而不要写为:y=x/*p,因为编译器将/*理解为一段注释的开始。六、C语言常见错误小结 C语言的最大特点是:功能强、使用方便灵活。C编译的程序对语法检查并不象其它高级语言那么严格,这就给编程人员留下“灵活的余地”,但还是由于这个灵活给程序的调试带来了许多不便,尤其对初学C语言的人来说,经常会出一些连自己都不知道错在哪里的错误。看着有错的程序,不知该

11、如何改起,本人通过对C的学习,积累了一些C编程时常犯的错误,写给各位学员以供参考。 1.书写标识符时,忽略了大小写字母的区别。 main() int a=5; printf(%d,A); 编译程序把a和A认为是两个不同的变量名,而显示出错信息。C认为大写字母和小写字母是两个不同的字符。习惯上,符号常量名用大写,变量名用小写表示,以增加可读性。 2.忽略了变量的类型,进行了不合法的运算。 main() float a,b; printf(%d,a%b); %是求余运算,得到a/b的整余数。整型变量a和b可以进行求余运算,而实型变量则不允许进行“求余”运算。 3.将字符常量与字符串常量混淆。 ch

12、ar c; c=a; 在这里就混淆了字符常量与字符串常量,字符常量是由一对单引号括起来的单个字符,字符串常量是一对双引号括起来的字符序列。C规定以“”作字符串结束标志,它是由系统自动加上的,所以字符串“a”实际上包含两个字符:a和,而把它赋给一个字符变量是不行的。 4.忽略了“=”与“=”的区别。 在许多高级语言中,用“=”符号作为关系运算符“等于”。如在BASIC程序中可以写 if (a=3) then 但C语言中,“=”是赋值运算符,“=”是关系运算符。如: if (a=3) a=b; 前者是进行比较,a是否和3相等,后者表示如果a和3相等,把b值赋给a。由于习惯问题,初学者往往会犯这样的

13、错误。 5.忘记加分号。 分号是C语句中不可缺少的一部分,语句末尾必须有分号。 a=1 b=2 编译时,编译程序在“a=1”后面没发现分号,就把下一行“b=2”也作为上一行语句的一部分,这就会出现语法错误。改错时,有时在被指出有错的一行中未发现错误,就需要看一下上一行是否漏掉了分号。 z=x+y; t=z/100; printf(%f,t); 对于复合语句来说,最后一个语句中最后的分号不能忽略不写(这是和PASCAL不同的)。 6.多加分号。 对于一个复合语句,如: z=x+y; t=z/100; printf(%f,t); ; 复合语句的花括号后不应再加分号,否则将会画蛇添足。 又如: if (a%3=0);

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

最新文档


当前位置:首页 > 办公文档 > PPT模板库 > 总结/计划/报告

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