程序错误和编程风格.ppt
C语言程序设计(Programming in C),程序错误和编程风格,程序错误编程风格,程序错误,一个编程大师说:“任何一个程序,无论它多么小,总存在着错误。”初学者不相信大师的话,他问:“如果一个程序小得只能执行一个简单的功能,那会怎样?”“这样的程序没有意义,”大师说,“但如果这样的程序存在的话,操作系统最后将失效,产生一个错误。”初学者不满足,他问:“如果操作系统不失效,那么会怎么样?”“没有不失效的操作系统,”大师说,“但如果这样的操作系统存在的话,硬件最后将失效,产生一个错误。”初学者仍不满足,再问:“如果硬件不失效,那么会怎样?”大师长叹一声道:“没有不失效的硬件。但如果这样的硬件存在的话,用户就会想让那个程序做一件不同的事,这件事也是一个错误。”没有错误的程序世间难求。【James 1999】,C程序错误,程序中的错误可分为语法错误逻辑错误(语义错误)运行错误,C程序错误,语法错误,逻辑错误(语义错误),语法错误指编程时违背了C语法的规定,对这类错误,编译程序一般都能够给出“出错信息”,并且告诉在哪一行出错及出错的类型。只要仔细检查,可以很快发现并排除这类错误。,程序并没有违背语法规则,但程序的执行结果与预期不符。这是由于程序与设计人员的本意不相符,即出现逻辑错误(或语义错误)。,运行错误,运行时发生的、与运行状态或环境有关的错误。,C程序中常见错误,使用的变量没有定义变量没有赋值初就直接使用输入输出的数据类型与所用格式说明符不一致超出数据范围输入变量时忘记使用地址符号输入时数据的组织方式与要求不符“=”与“=”混淆 语句的分号缺少或放置错误 缺少“”符号引用错误,(、)、括号不配对 引用数组元素越界.,C程序中常见错误,使用的变量没有定义(语法错),例如:,正确:main()int x,y;x=3;y=x+5;,错误:x、y没有定义main()x=3;y=x+5;,C/C+规定:任何变量都必须在使用前定义,否则编译时会出错。,C程序中常见错误(续),变量没有赋初值就直接使用(逻辑错),例如:,错误:sum没有赋初值int addition(int n)int i;int sum;for(i=0;i n;i+)sum+=i;return(sum);,正确:int addition(int n)int i;int sum=0;for(i=0;i n;i+)sum+=i;return(sum);,C程序中常见错误(续),变量赋初值:累加的初值应为0、连乘的初值应为1,例如:,求累加和:sum=0;for(k=10;k=20;k+)sum=sum+k;,求累乘积:fact=1;for(k=1;k=8;k+)fact=fact*k;,求累加和:sum=0;for(k=10;k=20;k+)sum=sum+k;,求累乘积:fact=1;for(k=1;k=8;k+)fact=fact*k;,C程序中常见错误(续),输入输出的数据类型与所用格式说明符不一致(逻辑错),例如:,错误:数据输出时的格式错误main()int a=3;float b=4.5;printf(%f%dn,a,b);,正确:main()int a=3;float b=4.5;printf(%d%fn,a,b);,TC2.0,C程序中常见错误(续),超出数据范围(逻辑错),例如:,错误:x的有效范围在-128127之间main()char x;x=300;,300101001011002,C程序中常见错误(续),输入变量时忘记使用地址符号(本来是语法错,表现为逻辑错),例如:,错误:scanf函数的实参格式main()int a,b;scanf(%d%d,a,b);printf(%d%d,a,b);,正确:main()int a,b;scanf(%d%d,C程序中常见错误(续),输入时数据的组织方式与要求不符,例如:,main()int a,b;scanf(%d,%d,运行时输入:35 12,C程序中常见错误(续),误把“=”作为关系运算符“=”,例如:,错误:关系运算与赋值运算混淆if(a=b)c=0;else c=1;,正确:if(a=b)c=0;else c=1;,1.为何if语句中的条件总是成立或不成立?在排除可能出现的逻辑错误外,有可能与条件表达式书写不正确有关。例如:if(x=3)x=x+8;这时的条件x=3始终成立,语句x=x+8也总是执行。要判断x是否等于3就必须写成x=3。又如:if(x=0)x=x+8;这时条件x=0总是不成立,语句x=x+8永远不执行。要判断x是否等于0就必须写成x=0或!x。同样,在其它使用条件的语句中也要注意类似问题。,C程序中常见问题-if语句,2.为什么会出现if-else不匹配?这种错误的原因可能比较复杂;总的原则是:(1)有一个else必有一个if,所以首先在数量上要匹配(2)逻辑关系要合理;若执行的是复合语句,不要漏掉复合语句标志。例如:if(xy)t=a;a=b;b=t;else t=m;编译时就会提示出错信息,正确的写法:if(xy)t=a;a=b;b=t;else t=m;(3)若条件不成立时要求执行的语句有多条,else后必须为复合语句。例如:if(xy)t=a;a=b;b=t;else t=m;m=n;n=t;,C程序中常见问题-if语句,C程序中常见错误(续),语句的分号放置错误,例如:,语法错误:缺少“;”main()unsigned int i,sum;sum=0;for(i=0;i10;i+)sum+=i,正确:main()unsigned int i,sum;sum=0;for(i=0;i 10;i+)sum+=i;,逻辑错误:“;”放错位置main()unsigned int i,sum=0;for(i=0;i 10;i+);sum+=i;,C程序中常见错误(续),语句的分号放置错误,例如:,正确:main()unsigned int i,sum;sum=0;for(i=0;i 10;i+)sum+=i;,逻辑错误:“;”放错位置main()unsigned int i,sum;sum=0;for(i=0;i 10;i+);sum+=i;,C程序中常见错误(续),“”的使用问题,例如:,逻辑错误:循环体部分没有使用”sum=0;i=1;while(i=10)sum+=i;i+;,正确:sum=0;i=1;while(i=10)sum+=i;i+;,C程序中常见错误(续),符号引用错误,(、)、括号不配对 引用数组元素超界.,数组下标越界错误:int a10;for(i=0;i=10;i+)scanf(%d,正确方式:int a10;for(i=0;i10;i+)scanf(%d,C程序中常见错误(续),整除运算的结果依然是整数 字符与字符串,9/2的结果为4,而9.0/2的结果为4.5。因此,需要对9或2进行强制类型转换,以得到4.5,即 9/(float)2=4.5 特别注意:1/3+1/3+1/3的结果为0。,字符常量是由单引号括起的一个字符,如:s。而s是字符串常量,由双引号括起,包含两个字符:s和0。使用时不能混淆,例如:char c,p;p=s;/正确c=s;/错误,字符变量c只能存放一个字符,(1)+和-运算只能适用于变量(尤其是整型变量)例如:n*m+正确的,(n*m)+是错误的,因为(n*m)是表达式。(2)前置和后置有区别:int n,post,pre;n=2;post=n+;/执行后post为2,n为3 n=2;pre=+n;/执行后pre为3,n为3,C程序中常见问题-+/-运算,C程序中常见问题-定长数组与变长数组,定义定长数组:int a5;,变长数组:int n;int an;,定义数组并初始化数组元素:int a5=1,2,3,4,5;,访问数组元素(写、读):for(i=0;i 5;i+)ai=i*2;for(i=0;i 5;i+)printf(%d,ai);,变长数组:int n=20;int an;,C99标准规定:定义数组时,其大小可以不确定,但不是所有的编译器都支持该特性,C程序中常见问题-字符数组 与 字符串,定义字符数组:char name5;,定义字符数组及初始化:char name15=c,h,i,n,a;char name2=c,h,i,n,a;,定义字符数组及初始化:char name1=c,h,i,n,a,0;char name2=china;Char name3=china;,scanf(%s,name);或 gets(name);读入一个字符串时,系统会自动加上结束标志0。,C程序中常见问题-if语句,Code 1:if(mark=90)printf(优);else if(mark=80)printf(良);else if(mark=70)printf(中);else if(mark=60)printf(及格);else printf(不及格);,例如:百分制成绩mark与对应五级制,Code 2:if(mark 60)printf(不及格);else if(mark 70)printf(及格);else if(mark 80)printf(中);else if(mark 90)printf(良);else printf(优);,Code 3:if(mark=60)printf(及格);else if(mark=70)printf(中);else if(mark=80)printf(良);else if(mark=90)printf(优);else printf(不及格);,C程序中常见问题-if语句,Code 4:if(mark=90)printf(优);else if(80=mark 90)printf(良);else if(70=mark 80)printf(中);else if(60=mark 70)printf(及格);else printf(不及格);,例如:百分制成绩mark与对应五级制,Code 5:if(mark=90)printf(优);else if(80=mark,编程风格,程序是最复杂的东西(虽然你开始写的程序很简单,但它们会逐渐变得复杂起来),是需要用智力去把握的智力产品。编程时应强调程序的易读性,尤其在团队协作的情况下。一套鲜明的编程风格,可以让协作者、后继者和自己一目了然,在很短的时间内看清程序的结构,理解设计思路。在简单程序中,涉及编程风格的内容主要有:1)缩进格式 2)符号的声明和命名方式 3)大括号的位置 4)注释,编程风格,人们常用的缩进格式是:逻辑上属于同一个层次的互相对齐;逻辑上属于内部层次的推到下一个对齐位置。,1)缩进格式 2)符号的声明和命名方式 3)大括号的位置 4)注释,if(x max(y,z)sum=place4+y;else while(x)sum+=x;x-;sum=sum+z;,if(x max(y,z)sum=place4+y;else while(x)sum+=x;x-;sum=sum+z;,对比一下,编程风格,采用直观的符号为常量、变量、函数等命名。在团队开发中,应有一套命名规范。,1)缩进格式 2)符号的声明和命名方式 3)大括号的位置 4)注释,double x,y;x=1.5;y=x*x*3.14159;,#define PI 3.1415925double radius,area;radius=1.5;area=radius*radius*PI;,#define N 100int aN;for(i=0;i N;i+)ai=i*2+1;,#define ARR_SIZE 100int arrARR_SIZE;for(i=0;i ARR_SIZE;i+)arri=i*2+1;,编程风格,采用直观的符号为常量、变量、函数等命名。,1)缩进格式 2)符号的声明和命名方式 3)大括号的位置 4)注释,#define TRUE 1#define FALSE 0/*判断正整数d是否为素数,若是返回TRUE,否则返回FALSE*/int isPrime(int d)int i;if(d 2)return FALSE;for(i=2;i=(int)sqrt(d);i+)if(d%i=0)return FALSE;return TRUE;,int isPrime(int d)int i;if(d 2)return 0;for(i=2;i=(int)sqrt(d);i+)if(d%i=0)return 0;return 1;,编程风格,经典C语言书中(Kernighan和Ritchie著)将开始的大括号放在一行的最后,而将结束大括号放在一行的第一位,函数体的“”和“”则在最左边,.,1)缩进格式 2)符号的声明和命名方式 3)大括号的位置 4)注释,/*判断正整数d是否为素数,若是返回TRUE,否则返回FALSE*/int isPrime(int d)int i;if(d 2)return FALSE;for(i=2;i=(int)sqrt(d);i+)if(d%i=0)return FALSE;return TRUE;,int isPrime(int d)int i;if(d 2)return FALSE;for(i=2;i=(int)sqrt(d);i+)if(d%i=0)return FALSE;return TRUE;,编程风格,变量的注释;函数的功能和参数进行注释;文件注释;.,1)缩进格式 2)符号的声明和命名方式 3)大括号的位置 4)注释,/*判断正整数d是否为素数:先计算d的因子个数c(不包括1和d自己),若c不为0,则d是素数,返回TRUE,否则返回FALSE*/int isPrime(int d)int i,count_factor=0;/*用于计算因子数目*/if(d 0)return FALSE;else return TRUE;,int isPrime(int d)int i,c=0;if(d 0)return FALSE;else return TRUE;,编程风格,风格没有对和错,没有什么理由去选择一种风格而不选择另外一种。程序是最复杂的东西(虽然你开始写的程序很简单,但它们会逐渐变得复杂起来),是需要用智力去把握的智力产品。编程时应强调程序的易读性,尤其在团队协作的情况下。一套鲜明的编程风格,可以让协作者、后继者和自己一目了然,在很短的时间内看清程序的结构,理解设计思路。应该用规范的、清晰的、容易理解的方式写程序。,编程,学习程序设计就好比学习射击,而程序设计语言就对应射击中的气枪、手枪、步枪等各种枪械。学习射击必须要选择一种枪械,不可能没有枪还能学好射击的,也不可能同时学会使用所有的枪械。但是,如果掌握一种枪械的射击,再学别的也就触类旁通了。因为在熟悉一种枪械的同时,也学习了射击技术本身。再学其他的,自然事半功倍。学习程序设计也是一样,必然要从学习一门程序设计语言开始入手。在学会系统的编程理念之后,用什么工具都一样!,学 C/C+的 50 条忠告:来自网落,供参考,1.把C+当成一门新的语言学习(和C没啥关系!真的。);2.看Thinking In C+,不要看C+变成死相;3.看The C+Programming Language和Inside The C+Object Model,不要因为他们很难而我们自己是初学者所以就不看;4.不要被VC、BCB、BC、MC、TC等词汇所迷惑他们都是集成开发环境,而我们要学的是一门语言;5.不要放过任何一个看上去很简单的小编程问题他们往往并不那么简单,或者可以引伸出很多知识点;6.会用Visual C+,并不说明你会C+;7.学class并不难,template、STL、generic programming也不过如此难的是长期坚持实践和不遗余力的博览群书;,学 C/C+的 50 条忠告:来自网落,供参考,8.如果不是天才的话,想学编程就不要想玩游戏你以为你做到了,其实你的C+水平并没有和你通关的能力一起变高其实可以时刻记住:学C+是为了编游戏的;9.看Visual C+的书,是学不了C+语言的;10.浮躁的人容易说:XX语言不行了,应该学YY;是你自己不行了吧!?11.浮躁的人容易问:我到底该学什么;别问,学就对了;12.浮躁的人容易问:XX有钱途吗;建议你去抢银行;13.浮躁的人容易说:我要中文版!我英文不行!不行?学呀!14.浮躁的人容易问:XX和YY哪个好;告诉你吧,都好只要你学就行;15.浮躁的人分两种:a)只观望而不学的人;只学而不坚持的人;,学 C/C+的 50 条忠告:来自网落,供参考,16.把时髦的技术挂在嘴边,还不如把过时的技术记在心里;17.C+不仅仅是支持面向对象的程序设计语言;18.学习编程最好的方法之一就是阅读源代码;19.在任何时刻都不要认为自己手中的书已经足够了;20.请阅读The Standard C+Bible(中文版:标准C+宝典),掌握C+标准;21.看得懂的书,请仔细看;看不懂的书,请硬着头皮看;22.别指望看第一遍书就能记住和掌握什么请看第二遍、第三遍;23.请看Effective C+和More Effective C+以及Exceptional C+;24.不要停留在集成开发环境的摇篮上,要学会控制集成开发环境,还要学会用命令行方式处理程序;,学 C/C+的 50 条忠告:来自网落,供参考,25.和别人一起讨论有意义的C+知识点,而不是争吵XX行不行或者YY与ZZ哪个好;26.请看程序设计实践,并严格的按照其要求去做;27.不要因为C和C+中有一些语法和关键字看上去相同,就认为它们的意义和作用完全一样;28.C+绝不是所谓的C的扩充如果C+一开始就起名叫Z语言,你一定不会把C和Z语言联系得那么紧密;29.请不要认为学过XX语言再改学C+会有什么问题你只不过又在学一门全新的语言而已;30.读完了Inside The C+Object Model以后再来认定自己是不是已经学会了C+;31.学习编程的秘诀是:编程,编程,再编程;,学 C/C+的 50 条忠告:来自网落,供参考,32.请留意下列书籍:C+面向对象高效编程(C+Effective Object-Oriented Software Construction)面向对象软件构造(Object-Oriented Software Construction)设计模式(Design Patterns)The Art of Computer Programming;33.记住:面向对象技术不只是C+专有的;34.请把书上的程序例子亲手输入到电脑上实践,即使配套光盘中有源代码;35.把在书中看到的有意义的例子扩充;36.请重视C+中的异常处理技术,并将其切实的运用到自己的程序中;37.经常回顾自己以前写过的程序,并尝试重写,把自己学到的新知识运用进去;38.不要漏掉书中任何一个练习题请全部做完并记录下解题思路;,学 C/C+的 50 条忠告:来自网落,供参考,39.C+语言和C+的集成开发环境要同时学习和掌握;40.既然决定了学C+,就请坚持学下去,因为学习程序设计语言的目的是掌握程序设计技术,而程序设计技术是跨语言的;41.就让C+语言的各种平台和开发环境去激烈的竞争吧,我们要以学习C+语言本身为主;42.当你写C+程序写到一半却发现自己用的方法很拙劣时,请不要马上停手;请尽快将余下的部分粗略的完成以保证这个设计的完整性,然后分析自己的错误并重新设计和编写(参见43);43.别心急,设计C+的class确实不容易;自己程序中的class和自己的class设计水平是在不断的编程实践中完善和发展的;44.决不要因为程序很小就不遵循某些你不熟练的规则好习惯是培养出来的,而不是一次记住的;,学 C/C+的 50 条忠告:来自网落,供参考,45.每学到一个C+难点的时候,尝试着对别人讲解这个知识点并让他理解你能讲清楚才说明你真的理解了;46.记录下在和别人交流时发现的自己忽视或不理解的知识点;47.请不断的对自己写的程序提出更高的要求,哪怕你的程序版本号会变成Version 100.XX;48.保存好你写过的所有的程序那是你最好的积累之一;49.请不要做浮躁的人;50.请热爱C+!,