C语言复习易错点总结_第1页
C语言复习易错点总结_第2页
C语言复习易错点总结_第3页
C语言复习易错点总结_第4页
C语言复习易错点总结_第5页
已阅读5页,还剩1页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、精选优质文档-倾情为你奉上精选优质文档-倾情为你奉上专心-专注-专业专心-专注-专业精选优质文档-倾情为你奉上专心-专注-专业1.1递增(减)运算符的表达式例如:i=3,a=(+i)+(+i)+(+i);大多数学生都知道i+和+i的最终结果都是使i的值加1,但i+和+i作为表达式的用途是不一样的,+i是“先加后用”,i+是“先用后加”。上面的题目是“+”运算符最典型的应用,其中a的结果是18,而不是有些书上分析的4+5+6=15。因为在这里要考虑运算符的优先级,很显然“+”的优先级高于“+”。若是“i=3,a=(+i)+(+i)+(+i)”则a结果是9,而两者最终的i值都将自增3即为6。“”运

2、算符和“+”运算符使用方式一样,不再赘述。1.2输入语句中缺取址符&例如:scanf(“%d”,x);这一语句错在x前缺取址符,导致输入的数值没有赋给变量x,所以结果出错。再如:char a10;scanf(“%s”,&a);有学生想,输入语句的输入变量前一定要加取址符,所以这个语句里加了取址符,肯定不会出错。而结果却又恰恰错了,这是为什么呢?因为a在这里既表示数组名字,又表示数组首地址,它本身已经代表了地址,所以就不用再加取址符了。解决此类问题的办法就是在使用输入语句的时候要仔细观察,什么时候该加取地址符号,什么时候不该加,一定要搞清楚。1.3逻辑运算符&和位运算符&相混淆例如:if(x&y

3、)编辑人员此判别条件的本意是将x和y的“与”(&)运算结果作为条件。程序运行时,并不出错,但是结果却不对。原因是误用按位“与”运算符&替代了“与”运算符&,这种错误初学者很容易犯,但是又十分隐秘,在某些特殊情况下甚至可以得出正确的结果,所以更具有迷惑性。位运算符是C语言独特的一种运算符,其中“&”表示对两个操作数按二进制位进行“与”运算,规则是:0&0=0,0&1=0,1&0=0,1&1=1。如6&5=4,其中6变为,5变为,按位“与”运算的结果为100即4。1.4误把赋值=当恒等=例如:if(a=0)误写成if(a=0)。上述写法将导致条件始终为假,进入不了if语句条件为真的分支。编程的时候

4、要仔细,要遵守c语言的语法规则。1.5条件语句(if)和循环条件语句后误加分号例如:if(xy);x=y;这样相当于满足条件执行空语句。下面的x=y语句将被无条件执行。一般情况下if()条件后不需要加分号。例如:for(i=1;i10;i+);上述for语句相当于满足条件执行空语句,真正的循环语句则没有被执行。一般情况下for()循环条件后不需要加分号。这两个都是初学者容易犯的错误,又很难察觉出来。1.6循环语句中改变了循环变量的值例如:求水仙花数main() int i,a,b,c;for(i=100;i1000;i+) a=i%10;i=i/10;b=i%10;i=i/10;c=i%10;

5、/*i的值被改变*/if(a*a*a+b*b*b+c*c*c=i)printf(“%d”,i);此程序看起来思路非常正确,可是高度的时候就是死循环,运行不出结果。为什么呢?仔细观察可知,在循环语句里,循环变量i每次进入循环后都被改变了,导致了i永远都满足循环条件,所以就死循环了。为了避免此类错误,在编程时应尽量避免在循环语句中改变循环变量。1.7作为输出结果的变量没有赋初值例如:求数组中的最大值能最大值的下标main() int a10=8,2,3,4,5,6,3,7,max=a10,m,i;for (i=0; imax)max=ai; m=i;printf(“%d%d”,max,m); 程序

6、看似一点毛病都没有,上机调试也都通过,但是结果却不对。原因就在下标变量m没有赋初值,系统随机赋了初值,导致结果错误。给m赋初值0就可以了。1.8初值赋了,但是赋的位置不对例如:求100以内的完数s=0;for(i=1;i=100;i+) 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!main() int i,j,s=0,

7、t=1;for(i=1;i=100;i+) for(j=1;j=i;j+) t=t*j;s+=t; printf(“%d”,s);t=1应该放在第三行此程序看似正确,可是运行结果却不对,原因也是在t=1这个赋值语句,它的位置应该在外层循环的里面,而不是在外面。这种错误,对于初学者来讲,很容易犯,却又发现不了,在程序调试的时候会浪费很多时间,又会影响编程的自信心。1.9数组和整型或者实型变量不能重名例如:main() int a10,a;数组名为a,其他变量的名字就不能再用a。1.10数组输出时的错误例如:现在想输出数组a中的所有数值。int a10=1,2,3,4,5,6,i;for(i=0;

8、i10;i+)printf(“%d”,a10);这个程序看似输出数组的十个元素,其实只输出其中的一个元素。解决此类问题的办法是大家要理解数组下标和循环变量的关系。再如:int a10=1,2,3,4,5,6,i;for(i=0;ib)这一段代码的本意是比较字符串a和字符串b的大小,但是这样比较是不正确的,应该改成 if(strcmp(a,b)0)解决这类问题关键是要记住字符数组名字代表的是字符数组的地址,是常量,不能直接进行复制等操作。这是个容易忽视的地方,也是考试经常出题的地方,希望引起大家的注意。1.13函数调用时参数传递出错例如:void swap(int a,int b) int t;

9、t=a;a=b;b=t;此段代码的本意是一个交换两个变量值的函数,但实际上这个函数完不成这个功能,因为本函数传递的是数值,函数调用时传递数值只是对实际参数值的一个拷贝,并不能改变实际参数的值,要完成此功能必须传入地址。因此上例应该为:void swap(int *a,int *b) int t;t=*a;*a=*b;*b=t;1.14忘记加头文件例如:求1-1/3+1/5-1/7,求此序列的和,直到最后一项的绝对值小于1e-6为止。程序如下:main() double s=0,x=1;long k=1;int flag=1;while(fabs(x)1e-6)s+=x;k+=2;flag=-f

10、lag;x=flag/k; 学生在调试这个程序时,未发现错误,可就是结果运行不出来。其实程序是没有任何错误。解决此类问题的办法就是要在程序的前面加上一个头文件#include“math.h”,如果不加这个头文件的话,系统将不认识fabs这个函数。1.15函数定义中未声明形参类型这种情况下调用函数,系统默认把其处理为整型参数,若没有声明函数的类型,返回值也为整型。调用时所有参数以整型传递,会出现参数不匹配的情况。解决办法就是明确定义函数参数的类型和个数。2教学建议结合实际教学过程中出现的问题,我们认为教师可以向学生提出几点建议:(1) C语言编程是一个循序渐进的过程。不要好高骛远,一开始学,就想

11、编写那些很复杂很大的程序,这是不切合实际,要踏踏实实打基础。(2) C语言一定要仔细,不能毛毛草草,该写逗号的地方,就不能写成分号。(3) 学习C语言的过程中,要善于总结、积累。一是积累一些编程的方法、思想,下次再遇到类似的问题,就会有思路。二是要积累编程过程中遇到的错误,最好准备一个小本子,把它记录下来。下次再遇到这样的问题,就会解决了,这样会节省很多时间。1. 关于条件表达式。形如:逻辑表达式? 表达式1 : 表达式2。逻辑表达式的值若为非零(真),则条件表达式的值等于表达式1,若逻辑表达值的值为零(假),则条件表达式的值等于表达式2的值。特别要注意的是条件表达式的结合方向是从右向左结合的

12、。例:与 y=(x0?1:x0) y=1; else if(x0?1:x0?1:(x5) printf(%d,x); else printf(%dn,x-);8. 各类运算符的优先级别:详细请看谭老的C程序设计(第二版)的P375页。初等运算符(括号加结构体运算符)单目运算符(注意逻辑非运算符! 它是除初等运算符外具有最高优先级别的)算术运算符(先乘除模,后加减,再移位)关系运算符逻辑运算符(& ,| ,不包括 ! )条件运算符(唯一一个三目运算符,即 ? : )赋值运算符逗号运算符(即顺序求值运算符)例:以下十个运算符+ ! != , ?: & = | %中优先级别最高和最低的分别是_!_和

13、_,_。9. static的作用。l 一是其声明的局部变量为静态局部变量,静态局部变量的值在程序整个运行期间不释放,即下次调用该函数时其值仍保留;其如果在编译时赋初值的,只赋值一次;不赋初值的,编译器自动赋值为0(数字型)或空字符(字符型);虽然静态局部变量在函数调用结束后仍存放,但外部的程序仍然不能引用。l 二是其声明的外部变量为静态外部变量,只能用于本文件,即使其他文件用了extern仍不能引用。10. 十进制(一般的数字序列),八进制(以0开头的数字序列,字符用ddd赋值),十六进制(以0 x开头的数字序列,字符用xhh赋值)。另外1.5e-2表示1.5*10-2或者0.015。例:设有

14、以下语句: char c;c=x1C;则C的二进制的值是_C_A) B) C) D) 解:c=x1C;是指以十六进制的形式给字符c赋值,其相当于c=28;所以转换为二进制即11100。11. 定义结构体与typedef的代码:struct people / people是结构体名 char name10; / 成员列表 int age; float height; double weight; / 分号千万不能漏typedef struct people SP; / 用typedef方式定义新的类型名SP,方便些/-/ 也可以写成这样typedef struct people char nam

15、e10; int age; float height; double weight;SP;12. 判别几个容易混淆语句的异同。异同都在我的脑海里,懒得打出来了,希望你自己想想,然后可以印在你脑海里。break与continuewhile,dowhile与forifelse ifelse与switchcasedefaultdefine与typedef13. int *p4与int (*p)4的异同。l int *p4表示p是指针数组。由于比*优先级高,因此p先与4结合,形成p4形式,这显然是数组形式,它有4个元素。然后再与p前面的“*”结合,“*”表示此数组是指针类型的,每个数组元素(相当于一个

16、指针变量)都可指向一个整型变量。l int (*p)4表示p是一个指针变量。它有4个元素,每个元素为整型。也就是p所指的对象是有4个整型元素的数组,即p是行指针。应该记住,此时p只能指向一个包含4个元素的一维数组,p的值就是该一维数组的首地址。p不能指向一维数组中的第j个元素。14. *p+与*(+p),*(p+)与*(+p),还有 (*p)+l *p+与*(+p)作用不同。前者是先取*p值,后使p的指针值加1。后者是先使p的指针值加1,再取*p值。l 若p初值为a(即&a0),输出*(p+)时,得a0的值,而输出*(+p),则得到a1的值。l (*p)+表示p所指向的元素值加1,即(a0)+

17、,如果a0=3,则(a0)+的值为4。注意:是元素值加1,而不是指针值加1。15. 若有定义int asizesize;l 请记住*(a+i)和a i 是等价的。l *(a i +j)、*(*(a+i)+j)都是二维数组元素a i j的值。有人可能会问“a+1的值和a+1的地址怎么会是一样的呢”?其实,a+1是地址(指向第1行首地址),而*(a+1)并不是“a+1单元的内容(值)”,因为a+1并不是一个实际变量,也就谈不上它的内容。*(a+1)就是a1,而a1是一维数组名,所以也是地址。以上各种形式都是地址计算的不同表示。l a,a0的值虽然相同,但是由于指针的类型不同(a是指向一维数组,a0指向a00元素)因此,对这些指针进行加1的运算,得到的结果是不同的。请记住,二维数组名(如a)是指向行的。因此a+1中的“1”代表一行中全部元素所占的字节数。一维数组名(如a0,a1)是指向列元素的。a0+1中的“1”代表一个元素所占的字节数。在行指针前面加一个*,就转换为列指针。例如,a和a+1是行指针,在它们前面加一个*就是*a和*(a+1) ,它们就成为列指针,分别指向a数组0行

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论