c语言易错知识Word文档下载推荐.docx
《c语言易错知识Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《c语言易错知识Word文档下载推荐.docx(8页珍藏版)》请在冰点文库上搜索。
![c语言易错知识Word文档下载推荐.docx](https://file1.bingdoc.com/fileroot1/2023-5/6/edf28d32-010f-4f75-a461-a1829ee3b04c/edf28d32-010f-4f75-a461-a1829ee3b04c1.gif)
scanf(“%s”,&
a);
有学生想,输入语句的输入变量前一定要加取址符,所以这个语句里加了取址符,肯定不会出错。
而结果却又恰恰错了,这是为什么呢?
因为a在这里既表示数组名字,又表示数组首地址,它本身已经代表了地址,所以就不用再加取址符了。
解决此类问题的办法就是在使用输入语句的时候要仔细观察,什么时候该加取地址符号,什么时候不该加,一定要搞清楚。
1.3逻辑运算符&
&
和位运算符&
相混淆
if(x&
y)
编辑人员此判别条件的本意是将x和y的“与”(&
)运算结果作为条件。
程序运行时,并不出错,但是结果却不对。
原因是误用按位“与”运算符‘&
’替代了“与”运算符‘&
’,这种错误初学者很容易犯,但是又十分隐秘,在某些特殊情况下甚至可以得出正确的结果,所以更具有迷惑性。
位运算符是C语言独特的一种运算符,其中“&
”表示对两个操作数按二进制位进行“与”运算,规则是:
0&
0=0,0&
1=0,1&
0=0,1&
1=1。
如6&
5=4,其中6变为00000110,5变为00000101,按位“与”运算的结果为100即4。
1.4误把赋值=当恒等==
if(a==0)误写成if(a=0)。
上述写法将导致条件始终为假,进入不了if语句条件为真的分支。
编程的时候要仔细,要遵守c语言的语法规则。
1.5条件语句(if)和循环条件语句后误加分号
if(x>
y);
x=y;
这样相当于满足条件执行空语句。
下面的x=y语句将被无条件执行。
一般情况下if()条件后不需要加分号。
for(i=1;
i<
10;
i++);
{````}
上述for语句相当于满足条件执行空语句,真正的循环语句则没有被执行。
一般情况下for()循环条件后不需要加分号。
这两个都是初学者容易犯的错误,又很难察觉出来。
1.6循环语句中改变了循环变量的值
求水仙花数
main()
{inti,a,b,c;
for(i=100;
1000;
i++)
{a=i%10;
i=i/10;
b=i%10;
c=i%10;
/*i的值被改变*/
if(a*a*a+b*b*b+c*c*c==i)printf(“%d”,i);
}
此程序看起来思路非常正确,可是高度的时候就是死循环,运行不出结果。
为什么呢?
仔细观察可知,在循环语句里,循环变量i每次进入循环后都被改变了,导致了i永远都满足循环条件,所以就死循环了。
为了避免此类错误,在编程时应尽量避免在循环语句中改变循环变量。
1.7作为输出结果的变量没有赋初值
求数组中的最大值能最大值的下标
{inta[10]={8,2,3,4,5,6,3,7},max=a[10],m,i;
for(i=0;
i<
i++)if(a[i]>
max)
{max=a[i];
m=i;
printf(“%d%d”,max,m);
程序看似一点毛病都没有,上机调试也都通过,但是结果却不对。
原因就在下标变量m没有赋初值,系统随机赋了初值,导致结果错误。
给m赋初值0就可以了。
1.8初值赋了,但是赋的位置不对
求100以内的完数
s=0;
=100;
{for(j=1;
j<
=i/2;
j++)if(i%j==0)s+=j;
if(s==i)printf(“%d”,i);
}是不是这样每一次循环s都变了?
程序运行的结果预期是6和28,可是实际上却没有任何结果。
原因就是s=0这个语句放错了位置,应该放在外层循环里面,也就是每判断一个数都应该从0开始累加。
求1!
+2!
+……+100!
{inti,j,s=0,t=1;
=i;
j++)t=t*j;
s+=t;
}
printf(“%d”,s);
}t=1应该放在第三行
此程序看似正确,可是运行结果却不对,原因也是在t=1这个赋值语句,它的位置应该在外层循环的里面,而不是在外面。
这种错误,对于初学者来讲,很容易犯,却又发现不了,在程序调试的时候会浪费很多时间,又会影响编程的自信心。
1.9数组和整型或者实型变量不能重名
{inta[10],a;
…}
数组名为a,其他变量的名字就不能再用a。
1.10数组输出时的错误
现在想输出数组a中的所有数值。
inta[10]={1,2,3,4,5,6},i;
for(i=0;
printf(“%d”,a[10]);
这个程序看似输出数组的十个元素,其实只输出其中的一个元素。
解决此类问题的办法是大家要理解数组下标和循环变量的关系。
printf(“%d”,a[i]);
这个错误也是初学者经常犯的,解决的办法就是牢记C语言中数组下标是从0开始的。
1.11字符串不加结束标记
chara[3]=“abc”,b[3]=“def”;
strcat(a,b);
printf(“%s”,a);
编程者本意是把字符串a和b连接后输出。
可上机的运行结果则是abcdef$%#&
即连接的后面又带了一些乱码。
看看好像又挑不出程序有任何毛病,再仔细观察下,原来字符串都有结束标记‘\0’,所以在定义数组的时候应该是字符串的实际长度加1,而我们这两个字符串的长度就不够了,应该改成长度为4,或者更大。
这样程序就不会有问题了。
所以在处理字符串的时候一定要注意结束标记‘\0’,否则会有不可预料的结果出现。
{chara[10]=“abc”,b[4]=“def”;
inti=0,j=0;
while(b[i]!
=‘\0)a[j]=b[i];
puts(a);
此程序的编程本意是想把字符串b复制到字串a中。
可是在输出的时候结果为def^&
*,即在复制结果后面带了一些乱码。
这个错误对于初学者来讲,可能也很难发现,实际上应该在输出字符串a之前,应该给字符串加个结束标记‘\0’。
这样程序就不会出错了。
1.12字符串复制,比较等出现的错误
chara[4]=“abc”,b[4]=“def”;
a=b;
编写这段代码的本意是把字符串b复制到字符串a中,初学者往往想通过语句a=b来实现,结果出错。
正确的写法则应该是利用函数strcpy(a,b)来实现此功能。
if(a>
b){}
这一段代码的本意是比较字符串a和字符串b的大小,但是这样比较是不正确的,应该改成
if(strcmp(a,b)>
0){}
解决这类问题关键是要记住字符数组名字代表的是字符数组的地址,是常量,不能直接进行复制等操作。
这是个容易忽视的地方,也是考试经常出题的地方,希望引起大家的注意。
1.13函数调用时参数传递出错
voidswap(inta,intb)
{intt;
t=a;
b=t;
此段代码的本意是一个交换两个变量值的函数,但实际上这个函数完不成这个功能,因为本函数传递的是数值,函数调用时传递数值只是对实际参数值的一个拷贝,并不能改变实际参数的值,要完成此功能必须传入地址。
因此上例应该为:
voidswap(int*a,int*b)
t=*a;
*a=*b;
*b=t;
1.14忘记加头文件
求1-1/3+1/5-1/7…,求此序列的和,直到最后一项的绝对值小于1e-6为止。
程序如下:
{doubles=0,x=1;
longk=1;
intflag=1;
while(fabs(x)>
1e-6){s+=x;
k+=2;
flag=-flag;
x=flag/k;
学生在调试这个程序时,未发现错误,可就是结果运行不出来。
其实程序是没有任何错误。
解决此类问题的办法就是要在程序的前面加上一个头文件#include“math.h”,如果不加这个头文件的话,系统将不认识fabs这个函数。
1.15函数定义中未声明形参类型
这种情况下调用函数,系统默认把其处理为整型参数,若没有声明函数的类型,返回值也为整型。
调用时所有参数以整型传递,会出现参数不匹配的情况。
解决办法就是明确定义函数参数的类型和个数。
2教学建议
结合实际教学过程中出现的问题,我们认为教师可以向学生提出几点建议:
(1)
C语言编程是一个循序渐进的过程。
不要好高骛远,一开始学,就想编写那些很复杂很大的程序,这是不切合实际,要踏踏实实打基础。
(2)
C语言一定要仔细,不能毛毛草草,该写逗号的地方,就不能写成分号。
(3)
学习C语言的过程中,要善于总结、积累。
一是积累一些编程的方法、思想,下次再遇到类似的问题,就会有思路。
二是要积累编程过程中遇到的错误,最好准备一个小本子,把它记录下来。
下次再遇到这样的问题,就会解决了,这样会节省很多时间。
3结束语
以上是笔者教学实践过程中总结出来的学生学习C语言比较容易出错的知识点,这些错误大多是计算机编译时无法检测出来的,而大家又很难发现的错误。
其中“循环语句中改变了循环变量的值”和“赋初值的位置不对”,是笔者在实际教学过程中经常发现的错误。
笔者总结出的这些问题,希望对C语言教学有一些帮助。