您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 经营企划 > 王牌9 扫雷英雄榜――C常见错误及解决方案
王牌91以下“解决方案”中的内容对应的是“错误举例”中内容的解决方法。1.把“=”误当作“==”使用错误举例ect.top=rect.bottom){MessageBox(hwnd,Invalidrectangle!,NULL,MB_OK|MB_ICONERROR);}解决方案因为条件判断误写成了赋值,上面的判断将永远为真,除非rect.bottom为零。比较低级却又难以发现的错误。说它低级是因为它属于再基本不过的语法问题;而它之所以难以发现是因为它不会产生编译错误,唯有在调试过程中跟踪执行才会发现。通常它导致的后果是某一个条件判断失效或者进一步导致死循环。2.使用已释放了的指针错误举例最常出现在释放链表时。初学者容易这样写:while(p){deletep;p=p-next;}解决方案这样是很危险的。正确的方法是:while(p){q=p-next;deletep;p=q;2}3.在定义数组时,将定义的“元素个数”误认为是可使的最大下标值。错误举例main(){staticinta[10]={1,2,3,4,5,6,7,8,9,10};printf(%d,a[10]);}解决方案C语言规定:定义时用a[10],表示a数组有10个元素。其下标值由0开始,所以数组元素a[10]是不存在的。4.输入数据时,企图规定精度。错误举例scanf(%7.2f,&a);解决方案这样做是不合法的,输入数据时不能规定精度。5.输入数据的方式与要求不符。错误举例scanf(%d%d,①&a,&b);输入时,不能用逗号作两个数据间的分隔符,如下面输入不合法:3,4 输入数据时,在两个数据之间以一个或多个空格间隔,也可用回车键,跳格键tab。scanf(%d,%d,&a,&b);②C规定:如果在“格式控制”字符串中除了格式说明以外还有其它字符,则在输入数据时应输入与这些字符相同的字符。下面输入是合法的:3,4 此时不用逗号而用空格或其它字符是不对的。343 :4 又如:王牌93scanf(a=%d,b=%d,&a,&b);输入应如以下形式:a=3,b=46.混淆字符和字符串的表现形式错误举例charsex;sex=”M”;…解决方案sex为字符变量,只能存放一个字符。而字符常量的形式是用单撇号括起来的,应改为sex=‘M’;“M”使用双撇号括起来的字符串,它包括两个字符:‘M’和‘\0’,无法存放到字符变量sex中。7.赋值写法错误:错误举例/*thisprogramiswrong*/intmain(void){intx,*p;x=10;p=x;printf(%d,*p);return0;}解决方案这里原本是想输出x的内容,结果却没有达到效果,应该是p=&x。48.错记“”与“+”的优先级错误举例比如计算n*5:result=n2+n;解决方案因为“”和“”相当于乘除2^N,所以容易误认为它们的优先级高于加减运算,其实不然。当把它们跟加减法一起用的时候一定要注意。这样就错了,应该用括号:result=(n2)+n;9.书写标识符时,忽略了大小写字母的区别。错误举例main(){inta=5;printf(%d,A);}解决方案编译程序把a和A认为是两个不同的变量名,而显示出错信息。C认为大写字母和小写字母是两个不同的字符。习惯上,符号常量名用大写,变量名用小写表示,以增加可读性。10.操作越界:错误举例intfirst[10],second[10];int*p,t;p=first;for(t=0;t20;++t)*p++=t;解决方案这段代码在某些编译器下面可能可以正常工作,但是其实是错误的.first只有10个元素,但是循环却取到第20个去了,虽然可能用户是试图给second赋值,但是c语言并不保证两个数组在内存里面是连续的。王牌9511.定义数组时误用变量。错误举例intn;scanf(%d,&n);inta[n];解决方案数组名后用方括号括起来的是常量表达式,可以包括常量和符号常量。即C不允许对数组的大小作动态定义。12.头文件重复包含错误举例当你的工程越来越庞大时,头文件的管理也麻烦起来。经常遇到这样的情况:在编译一个源文件时,发现因为没有包含某个头文件而导致“符号未定义”之类的错误,于是你加入了这个头文件,可是这个头文件中又包含另外一个头文件,而那个头文件原先已经加在源文件中了,结果产生了“符号重定义”错误,这样你又不得不把这个重复包含的文件去掉。解决方案为了避免出现“符号重定义”错误,可以采取条件编译技术。在创建头文件时,首先为这个头文件定义一个唯一的标识(假设是_SOME_SYMBOL_),然后在头文件的开头及结尾加上几行代码,像下面这样:#ifndef_SOME_SYMBOL_#define_SOME_SYMBOL_....(头文件代码)#endif第一行语句判断是否定义了符号_SOME_SYMBOL_,如果没有,说明本次编译尚未扫描过这个头文件,于是编译正常进行,并且定义符号_SOME_SYMBOL_,以标明文件已被扫描过一次;反之,如果文件已被包含过一次,_SOME_SYMBOL_就有了定义,于是条件编译语句使编译器跳过整个文件。如果所有的头文件都这样处理,就可以大量减少出现“符号重定义”错误的机率。13.将字符常量与字符串常量混淆。错误举例charc;6c=a;解决方案在这里就混淆了字符常量与字符串常量,字符常量是由一对单引号括起来的单个字符,字符串常量是一对双引号括起来的字符序列。C规定以“\”作字符串结束标志,它是由系统自动加上的,所以字符串“a”实际上包含两个字符:‘a'和‘\',而把它赋给一个字符变量是不行的。14.多次循环使用一个指针的时候忘记赋初值:错误举例/*thisprogramiswrong*/intmain(void){char*p1;chars[80];p1=s;do{gets(s);while(*p1)printf(%d,*p1++);}while(strcmp(s,done));return0;}解决方案程序想重复利用缓冲区s来保存每次输入的字符串,但是没次循环结束后,忘记把p1置回到缓冲开始的位置,造成很危险的故障.正确做法:/*thisprogramisnowcorrect.*/intmain(void){char*p1;chars[80];do{p1=s;gets(s);while(*p1)printf(%d,*p1++);王牌97}while(strcmp(s,done));return0;}15.对应该有花括号的复合语句,忘记加花括号。错误举例sum=0;i=1;while(i=100)sum=sum+I;i++;解决方案错误在于没有写成复合语句的形式。因此,while语句的范围到最后一个分号为止。语句“i++;”不属于循环体范围之内。应该为while(i=100){sum=sum+I;i++;}16.忽略了变量的类型,进行了不合法的运算。错误举例main(){floata,b;printf(%d,a%b);}解决方案%是求余运算,得到a/b的整余数。整型变量a和b可以进行求余运算,而实型变量则不允许进行“求余”运算。817.错误的比较两个指针:错误举例chars[80],y[80];char*p1,*p2;p1=s;p2=y;if(p1p2)...解决方案不要试图通过一个对象的指针来比较对向的内容。18.switch语句中漏写break语句。错误举例switch(grade){case'A':printf(85~100\n);case'B':printf(70~84\n);case'C':printf(60~69\n);case'D':printf(60\n);default:printf(error\n);解决方案由于漏写了break语句,case只起标号的作用,而不起判断作用。因此,当grade值为A时,printf函数在执行完第一个语句后接着执行第二、三、四、五个printf函数语句。正确写法应在每个分支后再加上“break;”。例如case'A':printf(85~100\n);break;19.printf()/scanf()中类型不匹配错误举例虽然WINDOWS下一般不用这两个函数了,但是与之类似的sprintf()/sscanf()和fprintf()/fscanf()还是经常使用的。如果格式字串中说明的变量类型与后面的参数列表不一致,printf()将导致输出结果混乱,scanf()有可能导致程序执行结果不稳定,甚至导致非法操作。王牌99解决方案初学者或许会以为类型不一致也无所谓,因为C语言可以自动进行类型转换。这种想法是错误的。类型转换是在编译时已知原类型和所需类型时由编译器产生代码来完成的,而格式字串对编译器来说只是一般的字串,编译器并不理解其中的含义,也就无法知道其中的类型信息;另一方面,从printf()/scanf()函数内部,虽然可以理解格式字串,但却无法知道后面变量表中的各变量的类型,对printf()/scanf()内部来说,变量表只呈现为一段连续的单元字节,唯一可知的是这段连续单元的起始地址。20.忘记加分号。错误举例a=1b=2解决方案分号是C语句中不可缺少的一部分,语句末尾必须有分号。编译时,编译程序在“a=1”后面没发现分号,就把下一行“b=2”也作为上一行语句的一部分,这就会出现语法错误。改错时,有时在被指出有错的一行中\未发现错误,就需要看一下上一行是否漏掉了分号。{z=x+y;t=z/100;printf(%f,t);}对于复合语句来说,最后一个语句中最后的分号不能忽略不写(这是和PASCAL不同的)。21.输入输出的数据类型与所用格式说明符不一致。错误举例a已定义为整型,b定义为实型a=3;b=4.5;解决方案printf(%f%d\n,a,b);编译时不给出出错信息,但运行结果将与原意不符。这种错误尤其需要注意。1022.指针未初始化错误举例int*p;*p=0;解决方案DOS下,这将有可能导致死机;WINDOWS下将导致一个非法操作。切记,使用指针前一定要初始化,使它指向一个确实分配了的空间。23.忽视了while和do-while语句在细节上的区别。错误举例(1)main(){inta=0,I;scanf(%d,&I);while(I=10){a=a+I;I++;}printf(%d,a);}(2)main(){inta=0,I;scanf(%d,&I);do{a=a+I;I++;}while(I=10);printf(%d,a);}解决方案可以看到,当输入I的值小于或等于10时,二者得到的结果相同。而当I10时,二者结果就不同了。因为while循环是先判断后执行,而do-while循环是先执行后判断。对于大于10的数while循环一次也不执行循环体,而do-while语句则要执行一次循环体。王牌91123.输入字符的格式与要求不一致。错误举例scanf(%c%c%c,&c1,&c2,&c3);解决方案在用“%c”格式输入字符时,“空格字符”和“转义字符”都作为有效字符输入。如输入abc 字符“a”送给c1,字符“”送给c2,字符“b”送给c3,因为%c只要求读入一个字符,后面不需要用空格作为两个字符的间隔。24.括号不配对。错误举例while((c=gerchar()!=’#’)putchar(c);解决方案当一个语句中使用多层括号时常出现这类错误,纯属粗心所致。上例少了一个括号。25.输入变量时忘记加地址运算符“&”。错误举例inta,b;scanf(%d%d,a,b);解决方案这是不合法的。Scanf函数的作用是:按照a、b在内存的地址将a、b的值存进去。“&a”指a在内存中的地址。26.忘记定义变量错误举例voidmain(){x=3;12y=6;printf(“%d/
本文标题:王牌9 扫雷英雄榜――C常见错误及解决方案
链接地址:https://www.777doc.com/doc-4598020 .html