以下程序基本摘自CSDN、BCCN、百度上的题帖,以及我和我身边人写的程序。限于篇幅,他们对问题的影响不大。我删除或重写了一些部分,一些与相应问题无关的错误也进行了修改。完整的更正程序已在code::blocks10.05(编译器gcc、调试器gdb、平台windows7旗舰版)上运行。1.程序画面一闪而过#includeintmain(void){intiSignal;/*定义代表信号灯状态的变量*/printf("红灯为0,绿灯为1\n");/*输出提示信息*/scanf("%d",&iSignal);/*输入iSignal变量*/if(iSignal==1)/*使用if语句判断*/{printf("灯是绿的,车可以跑了\n");/*判断结果为真时输出*/}if(iSignal==0)/*用if语句判断*/{printf("灯是红的,车不能跑\n");/*判断结果为真时输出*/}return0;}分析:在XP以上系统用win-tc、dev-cpp等IDE编译运行本程序时,无论输入什么数,结果都会被闪现,因为程序执行完语句后直接退出。解决方法:这里有几种方法:(1):在程序开头加入#include,然后加入system("pause");在程序结束时;此方法只适用于MS-DOS,windows,不适用于*nix等系统(二):在需要暂停的地方加一两个getchar();这个方法实际上并没有暂停程序,而是让程序等待用户输入几个回车。但是效果和暂停是一样的。(3):在程序开头加入#include,并加入一个getch();在需要暂停的地方,原理和上一个差不多。在win-tc中用的比较多。2.if,for,while后面直接进行判断;例如:#includeintmain(void){inta;scanf("%d",&a);if(a==123);////错误,if(a==123)后面不应该跟;,而应该跟////{printf();}code{printf("ccc");}else{printf("ddd");}getchar();返回0;}#includeintmain(void){intn,i;printf("请输入一个数>2:");scanf("%d",&n);for(i=2;i{if(n%i==0)break;}if(iprintf("%d不是手书\n",n);elseprintf("%d是手书\n",n);return0;}解析&解决方法:见注3,leakyheaderfile,main函数的格式不规范例如:main(){inta;scanf("%d",&a);printf("input%d",a);}分析:本程序不包含头文件stdio.h,即省略了#include,如果只有scanf和printf函数,stdio.h可以省略,可以正确运行,但这是一个很不好的习惯。而main()这种写法,C89标准勉强允许这种形式,C99标准也不允许。还有voidmain(),至今没有标准考虑接受不过有些编译器是允许的。当然,这种写法广为流传,应该和老谭的书有很大关系。main()函数要写成intmain(void)的形式,在main()函数末尾加上return0;也就是说,#includeintmain(void){inta;scanf("%d",&a);printf("输入%d",a);return0;}4.scanf格式控制的误用例如:#includeintmain(void){floata,b,c;printf("shuru3gexishu:");scanf("%f,%f,%f",&a,&b,&c);printf("何氏%f",a+b+c);return0;}解析:scanf()函数可以让普通字符在字符串中按格式放置。除空格字符外的普通字符必须与输入字符串完全匹配。否则,如上面的程序,则scanf()将其解释为键入数字,键入逗号,然后键入数字,键入逗号,最后键入数学。这意味着它必须像这样输入:2.3,5.1,3.8。如果没有完全匹配,则scanf()读取将失败。作为写程序的人,你可以按这种格式输入,但用户不知道应该输入哪种格式。所以应该改为scanf("%f%f%f",&a,&b,&c);解决办法:看一行scanf的分析。5.scanf参数错误例如:#includeintmain(void){charstr[80];printf("请输入您的姓名");scanf("%s",&str);printf("你好%s",str);return0;}分析:在scanf()中,要读取int、long、float、double、char等类型的数据,需要在第n(n>=2)个参数上加上&,因为scanf()函数,第n个(n>=2)参数是变量的地址,不是变量本身:比如defineintnum;然后scnaf("%d",&num);而读取字符串时不加&,因为字符串的变量名本身就代表地址。所以在这个例子中它应该是scanf("%s",str);同时这条规则也适用于结构体中的变量,即structfoo{charch;charstr[80];intnum}data;那么它应该是scanf("%c%s%d",&data.ch,data.str,&data.num);解决方法:见分析6、数据类型混淆例如:#includeintmain(void){inta;双b=1;对于(a=1;a<=6;aA++)b*=A;printf("%ld",b);}分析:定义b为双精度浮点型,输出使用%ld为长整型,数据类型不一致,输出为0。PS:例子老谭书上关于用TC调试的那一节给出的好像是inta;后面写的printf("%f",a);产生错误。解决方法:定义b为长整型long,即longb=1;(其实这里也涉及到隐式转换,所以更正确的做法是将a定义为长整型)7.C语言中例如:#includeintmain(void){printf("请输入华氏温度\n");浮动a,c;scanf("%f",a);c=5/9*(a-32);printf("摄氏温度为%4.2f",c);return0;}分析:C语言中,两个整数相除时,如果不能相除,则直接舍弃小数部分,即“截尾”。所以5/9的结果是0。解决方法:应该使用类型转换,或者显式划分的两个数的类型c=(float)5/9*(a-32);c=5.0/9*(a-32);c=5.0/9.0*(a-32);8、数字和字符混合输入#includeintmain(void){charch;整数,我;printf("请输入一个字符和一个整数:\n");while((ch=getchar())!='\n'){scanf("%d",&num);for(i=0;iintmain(void){inti=5;printf("%d%d",i++,i++);return0;}分析:这个问题,在实际编程中,应该没有人会这样写,但是还是有很多初学者纠结于此。在编程领域,很多时候,实践是最好的老师。如果你对代码有疑虑,最好在电脑上敲一遍,再编译运行。但是,对于i++,i++来说,即使程序编译运行了,也不一定有正确的结果。用VC、TC、gcc编译运行后的结果不一定相同。或者从某种角度来看,这里的结果正确与否其实并不重要。printf("%d%d",i++,i++);在此语句中,i++和i++是未指定的行为。也就是说,C语言的标准并没有规定运算的顺序。如果用gcc编译加上-Wall选项,会出现警告:gcc2_1.c-o2_1-g-Wall2_1.c:infunction'main':2_1.c:6:24:warning:on'i'运算结果可能未定义。因此,要解决这个问题,最好的办法就是不要在程序中写这样的代码。解决办法:见上。10.60<=成绩<=70例子:if(60<=成绩<=70)printf("pass");elseif(70<=grade<=85)printf("好");分析:在数学中,60<=grade<=70的表达式是成立的,但是在C语言中,没有这样的表达式。解决方案:应该重写为if((60<=grade)&&(grade<=70))printf("pass");else...11.switch接受什么值?示例:#includeintmain(void){doublechoice;scanf("%lf",&选择);开关(选择){案例1.0:printf("1.0");休息;案例2.0:printf("2.0");休息;默认值:printf(“它不是1.0或2.0”);}return0;}分析:这种问题在实际编程中也不会出现。但是有的C语言题可能会这样出现。switch()接受整数:整数或字符。因此,switch()不接受浮点数、字符串等类型。解决方法:没别的...12.===混淆示例:voidcount(void);/*计数器函数*/voidshow_count(void);/*上报计数结果*/intmain(void){puts("Please输入一些字母:(#toend)");数数();显示计数();puts("感谢您使用HerBal_Tea制作的程序!");系统(“暂停”);return0;}voidcount(void){while((ch=getchar())!=STOP){if(ch=SPACE){sp_count++;继续;}if(ch=ENTER){n_count++;继续;}other_count++;}/*endofwhile((ch=getchar())!='#')*/}voidshow_count(void){puts("\nspaceenterother");printf("%5d%6d%6d\n",sp_count,n_count,other_count);}分析:我自己也犯了这个错误。在数学中,=表示相等,在许多编程语言中,=表示赋值,==表示相等。思维惯性导致错误。而这个错误C编译器既不会报错也不会warn。很难检查是否出了问题。debugging的值监控看了不下20遍,也没找到。最后逐行查看源码,才发现问题所在。这个问题在C语言四书五经中的ctrapsandpitfalls和expertcprogramming中都有提到。解决办法:小心点。13、溢出问题示例:求斐波那契数列的前n项#include#defineN100intmain(void){intfib[N];诠释我;fib[0]=fib[1]=1;printf("%d%d",fib[0],fib[1]);对于(i=2;iintmain(void){doublea=158.385427;printf("%.2lf",a);return0;}解析:C语言中printf("%.2lf",num);直接截断到小数点后两位,不是四舍五入而是类似于零截断。解决办法:如下//四舍五入显示数字,用户输入准确//可以区分正负#include#include#includeintmain(void){整数宽度;双a=158.385427;puts("请输入宽度");scanf("%d",&宽度);如果(a>0.0)a=(int)(a*pow(10,width)+0.5)/pow(10,width);否则a=(int)(a*pow(10,width)-0.5)/pow(10,width);printf("结果为%.*lf\n",width,a);系统(“暂停”);return0;}15.函数返回值示例:#includedoublesalary();/*计算工资税的函数*/voidmain(){intchoice;炭想要0;双重结果;while(1){printf("欢迎使用个人所得税计算器\n");printf("\n");printf("1.工资薪金所得税计算\n");printf("\n");printf("请输入要计算的税目编号:");scanf("%d",&选择);如果(选择==1){工资();printf("%lf",结果);}双倍薪水(){双倍工资l,结果;printf("请输入您的工资:");scanf("%lf",&sal);如果(萨尔<=3000){结果=萨尔;}if(sal>3000&&sal<=4500){结果=sal*0.05;}if(sal>4500&&sal<=7500){结果=sal*0.1-75;}if(sal>7500&&sal<=12000){结果=sal*0.2-525;}if(sal>12000&&sal<=38000){结果=sal*0.25-975;}if(sal>38000&&sal<=58000){结果=sal*0.3-2725;}if(sal>58000&&sal<=83000){结果=sal*0.35-5475;}if(sal>83000){结果=sal*0.45-13475;}returnresult;}分析:这个问题简单来说就是自定义函数没有返回计算值,和存储类和链接有关,即变量的作用域、链接、存储周期。解决方案:/**main.c**创建于:2011-6-11*作者:ice*/#includedoublesalary();/*计算工资税的函数*/intmain(void){intchoice;//charwant0;////这个want0变量没有使用doubleresult;while(1){printf("欢迎使用个人所得税计算器\n");printf("\n");printf("1.工资薪金所得税计算\n");printf("\n");printf("请输入要计算的税目编号:");scanf("%d",&选择);if(choice==1){result=salary();//必须有一个值接受返回值printf("%lf",result);}}}doublesalary(){双倍工资,结果;printf("请输入您的工资:");scanf("%lf",&sal);如果(萨尔<=3000){结果=萨尔;}if(sal>3000&&sal<=4500){结果=sal*0.05;}if(sal>4500&&sal<=7500){结果=sal*0.1-75;}如果(萨尔>7500&&萨尔<=12000){结果=sal*0.2-525;}if(sal>12000&&sal<=38000){结果=sal*0.25-975;}if(sal>38000&&sal<=58000){结果=sal*0.3-2725;}if(sal>58000&&sal<=83000){结果=sal*0.35-5475;}if(sal>83000){结果=sal*0.45-13475;}返回结果;}