C语言中常见错误

2024-09-18

C语言中常见错误(共8篇)

C语言中常见错误 篇1

C语言是很多高校开设的第一门程序设计语言,具有强大的功能,使用方便灵活。C语言对语法的检查不如其他高级语言那么严格。C是函数式的语言,利用标准库函数和自己设计的函数可以完成很多强大的功能。善于利用函数可以实现程序的模块化。但对于初学者来说,在C的学习使用中容易忽略一些细节而犯错误。结合在学习使用C语言时积累的一些经验进行了总结,希望能给初学者带来帮助。

1 C语言使用中常见错误分析

1.1 大小写错误

C语言规定所有的标识符是区分大小写的。书写标识符时,忽略了大小写字母的区别就会出现错误。如:

main()

{int a=5;

printf("%d",A);}

编译程序把a和A认为是两个不同的变量名,而显示出错信息。C认为大写字母和小写字母是两个不同的字符。习惯上,符号常量名用大写,变量名用小写表示,以增加可读性。

1.2 将字符常量与字符串常量混淆。

char c;

c="a";

在这里就混淆了字符常量与字符串常量,字符常量是由一对单引号括起来的单个字符,字符串常量是一对双引号括起来的字符序列。C规定以“”作字符串结束标志,它是由系统自动加上的,所以字符串“a”实际上包含两个字符:‘a’和‘’,而把它赋给一个字符变量是不行的。

1.3 忽略了变量的类型,进行了不合法的运算。

main()

{float a,b;

printf("%d",a%b);}

%是求余运算,得到a/b的整余数。整型变量a和b可以进行求余运算,而实型变量则不允许进行“求余”运算。

1.4 忽略了“=”与“==”的区别。

在许多高级语言中,用“=”符号作为关系运算符“等于”。但C语言中,“=”是赋值运算符,“==”是关系运算符。如:if(a==3)a=b;前者是进行比较,判断a是否和3相等,后者表示如果a和3相等,把b值赋给a。由于习惯问题,初学者往往会忽略了“=”与“==”的区别,而犯错误。

1.5 忘记加分号

分号是C语句中不可缺少的一部分,语句末尾必须有分号。

a=1

b=2

编译时,编译程序在“a=1”后面没发现分号,就把下一行“b=2”也作为上一行语句的一部分,这就会出现语法错误。改错时,有时在被指出有错的一行中未发现错误,就需要看上一行是否漏掉了分号。

{z=x+y;

t=z/100;

printf("%f",t);

}

对于复合语句来说,最后一个语句中最后的分号不能忽略不写。

1.6 未注意INT型数据的数值范围

Turbo C等编译系统,对一个整型数据分配2个字节。因此,一个整数的范围为-32768~32767。常见这样的程序段:

Int a;

a=89101;

printf("d%",a);

得到的却是23565,原因是89101已超过32767。

对于超过整数范围的数,要用long型,即改为:

long int a;

a=89101;

printf("ld%",a);

如果只定义a为long型,而在输出时仍用“d%”说明符,也会出现错误。

1.7 在输入语句scanf中忘记使用变量的地址符

例如:

scanf("d%",a);

这是许多初学者刚学习C语言时比较容易犯错误的地方,因为在其他语言中在输入时只需要写出变量名即可,而C语言要求指明“向哪个地址标识的单元送值”。应写成:scanf("d%",&a);

1.8 当scanf函数中的输入项是字符数组名时,又加地址符&

例如:

char str[12];

scanf("%s",&str);

在C语言中,数组名代表该数组的起始地址。应为:

char str[12];

scanf("%s",str);

1.9 给数组整体赋初值

例如:如果想使一个数组中全部元素为0,写成:

int a[6]={0*6};

这样写是错误的,在C语言中不能给数组整体赋初值。可以写成:

int a[6]={0,0,0,0,0,0};或int a[6]={0};

1.1 0 对数组的大小做动态定义

例如:

int n;

scanf("%d",&n);

int a[n];

常量表达式中可以包括常量和符号常量,不能包含变量。C语言不允许对数组的大小作动态定义,即数组的大小不依赖程序运行过程中变量的值。

1.1 1 忽略某些函数的求值顺序

如main()

{int x=5;

printf(%d,%d,%d,%d,x++,x,--x,x);}

运行结果为4 4 4 5

这是由于在Turbo C中执行printf()函数时参数是按照从右到左的顺序被压入栈中的,即先压入x在压入x然后x最后是x++弹出时依次为x++x--x x,因而得到上述结果。

1.1 2 将一个整数(或任何其他非地址类型的数据)赋给一个指针变量

例如:

*pointer-1=100;

pointer-1为指针变量,100为整数,将整数赋值给指针变量是错误的。注意在指针变量中只能存放地址(指针)。

1.1 3 不同类型指针混用

void main()

{int a=2,*p1;

float b=4.5,*p2;

p1=&a;p2=&b;

p1=p2;

printf("%d,%d",*p1,*p2);}

企图使p2也指向a,但是p2是指向实型变量的指针,不能指向整型变量。指向不同类型的指针间的赋值必须进行强制类型转换。例如:

P2=(float*)p1;

作用是先将p1的值转换成指向实型的指针,然后再赋给p2。

1.1 4 混淆数组名与指针变量的区别

例如:

void main()

{int i,a[5];

for(i=0;i<5;i++)

scanf("%d",a++);}

企图通过a的改变使指针下移,每次指向欲输入数据的数组元素。它的错误在于不了解数组名代表数组首地址,它的值是不能改变的,用a++是错误的,应该用指针变量来指向各数组元素。即:

int i,a[5],*p;

a=p;

for(i=0;i<5;i++)

scanf("%d",a++);}

1.1 5 使用文件时忘记打开,或打开方式与使用情况不匹配

例如,对文件的读写,用只读方式打开,却企图向该文件输出数据,例如:

if((fp=fopen("test","r"))==null)

{printf("cannot open this filen");

exit(0);}

ch=fgetc(fp);

while(ch!='#')

{ch=ch+4;

fputc(ch,fp);

ch=fget(fp);}

对以“r”(只读方式)打开的文件,进行既读又写的操作

2 结束语

以上列举了初学者在学习使用C语言时常遇到的一些错误,当然还会遇到其他错误,需具体情况具体分析和认真总结,只有这样才能避免犯这些常见错误,编出运行效率高、占内存少的高质量程序。

摘要:C语言具有功能强、使用方便灵活的特点,是一种应用广泛的高级编程语言。该文根据C语言的特点,列举并分析了在学习和使用C语言时的一些常见错误,以供初学者参考,有助于他们尽快熟练掌握C语言,提高程序设计水平。

关键词:C语言,常见错误,变量,指针,文件

参考文献

[1]谭浩强.C程序设计[M].北京:清华大学出版社,1999.

[2]张莉.C程序设计教程[M].北京:电子工业出版社,2000.

[3]陈友明.C语言使用中常见错误分析[J].电脑知识与技术,2006(1).

[4]单树倩.C语言使用中常见错误分析[J].电脑知识与技术,2009(26).

C语言中常见错误 篇2

本文分析了初中学生在英语写作时的常见语言错误,归纳了常见语言错误的类型,对学生所犯语言错误的原因进行了探讨,并在此基础上提出了解决问题的途径。

关键词:写作,语言错误,教学策略,纠正策略

写作是一个角度复杂的思维过程,对认知能力、思维能力、语言能力、组织能力和自我监控能力都有相当高的要求。写作是一项实践性很强的活动,只有通过反复练习和实践才能使习作中的语言错误从多到少,从少到无。教师应以正确的态度对待学生写作中出现的各种语言错误,因势利导,积极帮助学生改正语言错误。

一、了解错误类型,弄清出错原因

学生写作中常见的语言错误有以下几类:

1.主谓不一致。主谓不一致即主语和谓语在人称和数等方面未能保持一致。

例如:Every classroom have acomputer and a TV.

[分析]every classroom作主语是单数,have应改为has.

2.冠词误用。冠词误用主要包括该用时不用,不该用时却用了,以及定冠词与不定冠词之间误用。

例如:My mother is driver andshe likes to play piano.

[分析]driver是可数名词,其前应加不定冠词a,而piano为乐器类,与play连用应时,其前必须用定冠词the。

3.指代不明。代词与被指代的人或物之间关系不清。

The cat under the tree is Lily’s.Her cat is at home,

[分析]Her在此指代不明,到底是Lily的还是别人的,所以这个句子有歧义,应具体说清楚是谁的。

4,词性误用。比如,把介词当动词用,把形容词当动词用,或把名词当动词用等。

They without food and gave upat last.

[分析]without是介词。不能单独作谓语,但学生却把它当动词用了。

5.中式英语。按汉语表达习惯编造英语词汇或句子也是学生写作中常见的语言错误。

She is a good student,You canfind her in her book room,

[分析]book room是套用汉语中“书房”造的。此句应改为:She is agood student.You can find her inher study.

了解具体的语言错误类型及其产生的原因有助于学生在写作过程中主动预防和纠正语言错误。另外,从以上简单的归类也不难看出,很多语言错误是由于学生对基础知识掌握不牢,有些语言错误是由于学生受母语干扰,还有些语言错误则是学生对西方文化、价值观缺乏了解和认识所致。

二、写作教学的策略

1.加强基础知识练习

基础知识的重要性不言而喻。教师应着重选用学生感到难懂和易错的知识作为练习项目,如辨别相似词汇,辨析相似句子,针对重点句型和习惯用语的练习,以及就同一个词在不同上下文中用法不同的练习等。

2.模仿文章进行写作练习

教材是教学之本,是教师对学生进行英语写作训练的首选素材。这就像学生刚学英语时需要模仿标准的语音语调一样,模仿课文中的规范词句进行写作同样非常重要。在学习七年级(Unit8 My Coun-try and English-speaking Countries)我们就可利用某一课进行写作,比较自己国家和别的国家之间的不同与相同之处,即从国旗,首都,和著名的建筑物、景点等方面进行比较。

3.加强阅读,多了解西方文化。

丰富课外阅读是加强学生英语写作能力的有效途径,在母语环境中学习英语,学习者只有通过大量阅读才能丰富词汇量,并且语言和文化总是相辅相成的,了解西方文化不仅能够促进学生学习语言,而且有利于帮助他们开拓视野,培养学生的新思维方式。

三、作文批改策略

1.学生自我纠错

当学生出错时,教师不必急于纠错,可用一些不赞同或迷惑的表情暗示,或是给出书面提示,留给学生一定的空间。学生一旦意识到自己的错误,他们通过自我纠正比教师纠错所学的东西要好。这种纠错方式有利于保护学生自尊心,能同时调动学生的积极性,使学生有一种成就感。

2.同学互相纠错

有语言学家认为,教师不应“统治”整个纠错过程。教师鼓励学生之间互相纠正错误,也是一种很好的办法。让学生交换批改彼此的作文,即相互纠错,可帮助学生辨认更多的语法错误和词汇错误。而且让学生相互纠错,他们会产生一种“当老师”的荣誉感和责任感,从而调动他们的学习积极性,更重要的是相互纠错可以让学生获得思考、聆听以及与同学交流的机会,培养学生互相学习,互相帮助的合作精神。

3.建立错题档案

教师可以要求学生建立自己的错题档案,把错误类型、表现形式、原因及改正的结果和方法在笔记本上记录下来,经常翻看、复习和思考。对于学生来说,自己的语言错误档案针对性强,所犯的语言错误得到高度重视,以后遇到相同或类似问题便能迎刃而解,,不会再犯错。教师还可以让学生互相交换笔记本,在翻阅其他同学的错题档案时,反思自己是否会犯相同的错误。

试析C语言常见错误 篇3

1 引言

C语言是程序设计入门语言 , 它具有高级语言和低级语言的特点, 能编写系统软件也能编写应用软件[1]。 它语法结构简洁, 有丰富的运算符和数据类型且对语法限制不严格, 对于初学者来说, 想学好C语言并不容易, 特别是英文较差的初学者, 在调试程序时, 看到程序有错, 不知从何下手。

2 C 语言常见错误分析

2.1 错误分类

在C语言程序中的错误一般分为语法错误、 逻辑错误和运行错误。

(1) 语法错误 : 在程序编译时给出相应的提示信息 , 主要错误类型有两种, 一种是一般性的错误 (error); 另一种是警告性错误 (warning)[2]。 在运行窗口显示错误的个数 、 出错的原因等信息。

(2) 逻辑错误 : 程序语法规则正确 , 但运行结果不一定正确, 这是程序设计人员程序编写错误或者算法错误, 这类错误对初学者来说一般比较难解决。

(3) 运行错误 : 程序编译和连接时无语法错误和逻辑错误, 但程序运行时出错, 或者程序停止执行, 出现这种错误一般是程序不具有 “健壮性”[3]。

2.2 错误解析

(1) 主函数出错

在C语言中一个程序只能有一个主函数, 很多初学者程序运行第一个程序无误后, 又新建第二个程序; 或者新建一程序, 运行后, 接着编写另一个程序, 这样就会出现错误提示信息 “function 'int _cdecl main (void) ' already has a body”,提示主函数已经存在, 在 “输出窗口” 双击相应的错误信息,蓝色的箭头指向 “代码窗口” 的产生错误的语句, 很多情况下指向的位置不正确, 需要上下各行查找。

解决方法: 用/* */把另一个程序注释即可。

(2) 变量未定义或使用未赋值的自动变量

在C语言中, 使用变量要遵循 “先定义, 后使用” 的原则, 初学者经常忘记定义变量, 在写程序时直接使用, 或者定义变量时关键字与变量名之间没有空格, 这样就会出现提示 “变量名: undeclared identifier, 提示某变量未定义。

在该程序中, 只定义了变量a, 而没有定义变量b, 但在程序中却使用了变量b, 因此在程序调试过程中会显示出错信息。程序运行时结果值不正确, 是因为在程序中定义了变量a, 但没有给a赋值, 而直接用a的, a未赋值, 值不确定, 所以运行结果也不正确。

解决方法: 在程序中定义相应变量且给a赋相应的值。

(3) 大小写混淆

在C规定除了注释所有符号都在英文状态下进行, 而大小写表达的含义是不一样的, 初学者很多不区分大小写, 例如:

编译程序把B和b认为是两个不同的变量名, 还有Int和int含义也不相同 , 显示出错信息 。

解决方法: 将Int改成int, 再把大写B改成小写b即可。

(4) 语句少分号或多分号

在C语言中的简单语句以分号为结束标志, 复合语句是用一对 { } 括起来的一组语句, 空语句只有一个分号, 控制语句根据格式的不同, 需要区别记忆。 初学者很多会忘记加分号, 或者多加分号, 例如:

编译提示 出错信息 :“Syntax error:missing’:’ before identifier’ printf”, 提示语法错误 , 缺少分号 ; 程序中 , if (a>b)后面多写 了分号 , 提示报错 , 而对于比 较特殊的 控制语句do...while( ) 语句里面分号不能省略 , 一定要区别记忆 。

解决方法: If (a>b) ;后面的分号去掉, max=a后面加分号, 变为max=a;。

(5) 主函数或复合语句漏掉花括号

主函数中的语句必须有一对花括号括起来, 还有复合语句也要用左右花括号括起来, 初学者在编写程序时, 一定不要漏掉花括号, 否则程序出现错误提示: “unexpected end of file found”。 例如 :

解决方法: 后面加大括号即可。

(6) 运算符出错

C语言运算符非常丰富 , 不同的运算符对运算对象是不相同的, 初学者经常忽略了运算符对运算对象的要求而进行了非法运算。 一般经常出错的有4种情况,

1) “%” 运算符出错 。

C语言规定 , 求余运算符 “%” 是求两个整型数的相除后的余数, 要求两侧必须为整型数, 如果, 变量a和b为实型数,不能进行求余运算。

解决方法: 把要进行取余运算的变量定义为整型。

2) 在进行比较时关系运算符 “==” 错用为 “=”。

C语言中 “=” 是赋值运算符 , 而 “==” 是关系运算符中的比较运算, 例如: if (a==5) a=b;前者是比较运算, 判断变量a的值是否和5相等, 如果相等, 后者则是把b的值赋给a。 由于习惯成自然 , 初学者很容易把两者写错 。

解决方法: 把赋值号 “=” 换为比较运算符 “==” 即可。

3) 逻辑运算出错 。

If (10<a<100) 此表达式的含义为a>10且a<100, 但在C语言中, 关系运算符的结合性为从左向右, 在此规则下, 10<a<100是先求a<4的值 , 得到一个逻辑值0或1, 再继续用这个数与a<100比较, 结果恒为真, 失去本题目本意。

解决方法: 对于类似情况, 正确的表达方式应写成逻辑表达式的形式if ((10<a) && (a<100))。

4) 自增自减运算符出错 。

在C语言中, “++” 是自增运算符, “- - ” 是自减运算符, 都属于单目运算符, 它们的作用使运算对象的值加1或减1。 例如 :

C语言规定自增 、 自减运算符只适用于整型或字符型变量 , 而不能用 于常量或 表达式 。 在本例中 ++ (x+y) 和 - -(x*10) 均为非法运算 。

解决方法: 理解自增自减运算规则, 避免使用常量或表达式进行运算, 也不要使用不宜理解的表达式。

(7) scanf( ) 函数出错

C语言没有格式输入 /输出语句 , 它的输入输出通过函数调用来实现,。 在使用scanf( ) 函数时有两个方面经常出错:

1) canf( ) 的参数地址列表中忘记加上地址符 “&” , 例 :scanf(“%d” ,a) ;

调试程序时出现语法错误:“local variable 'a' used without having been initialized”。

解决方法: 在参数地址列表中加上地址符, scanf (“%d” ,&a) ;。

2) 数使用经常出错, 在 “格式控制” 字符串中除了格式说明以外可以是空格还可以有其他字符, 如果是空格时, 在输入数据时可以用空格键、 Tab键和回车键, 否则在输入数据时应输入与这些字符相同的字符。 例如: scanf “(x=%d,y=%d” ,&x,&y) ;。

输入10 100或10,100或10:100等都是非法的。

解决方法: 输入x=10,y=100即可。

(8) 使用库函数时忘记用 “#include” 命令包含相应的头文件

C语言规定使用系统函数时要把相应的头文件包含进去 ,例如:

解决方法 : 在程序中 加上 #include<math.h>或 #includemath.h”。

(9) 定义数组时使用最大下标值

C语言规定数组的下标值从0开始 , 所以在本程序中a[4]是不存在的。

解决方法: 不使用数的最大下标。

(10) 定义形参的同时定义了局部变量

有些形参应该定义在函数体外, 局部变量c应该定义在函数体内。

解决方法: 把局部变量c定义在函数体内, 应改为:

(11) 指针变量未正确赋值之前就引用

指针变量就是专门用来存放地址的变量, 指针变量未正确赋值之前, 它将随机指向某个内存。 指针引用不当, 严重时会导致系统崩溃。 例如:

由p指向字符型的指针, q是一个字符变量, 它们类型不同, 不能直接赋值。

解决方法: 把q的地址赋给指针变量p, 具体为: p=&q;。

3 结语

C语言常见错误分析与思考 篇4

简单语句:以分号结束的一条语句。复合语句:用一对花括号括起来的一组语句。空语句:只有一个分号, 而没有表达式的语句。注释语句:注释语句以“/*”开头并以“*/”结尾。用来给程序加注释。

2 C语言的特点

1) 比其他高级语言更接近硬件, 比低级语言更容易描述算法, 程序易编、易读、易查、易修改。可以说兼有高级语言和低级语言的优点。

2) 数据类型和运算符十分丰富, 既有系统定义的简单类型:整型、实型、字符型等。又有用户自定义的构造类型:数组类型、结构体类型、共用体类型等。程序设计和算法描述更为简单和方便。

3) 语法结构简单, 语句数目少, 简单易学。

4) 它是一种结构化程序设计语言, 提供了完整的程序控制语句 (选择语句和循环语句) , 很适合结构化的程序设计方法。

5) 它是一种模块化程序设计语言, 适合大型软件的研制和调试。

6) 它提供了大量的库函数供调用, 简化了程序设计工作。

7) 生成目标代码质量高, 一般只比汇编生成的目标代码效率低10%~20%。

8) 用C语言写的程序可移植性好。一般不用修改就能用于各种型号的计算机和各种操作系统。

9) C语言学习难度较大, 特别是指针、地址、函数调用等内容较难度大, 需要认真学习才能掌握。

3 对C语言常见错误分析

1) 使用标识符时, 混淆了大小写字母的区别。

编译程序时候, 编辑系统会提示A1和A2这两个变量未定义而显示出错信息。C认为大写字母和小写字母是两个不同的字符。习惯上, 符号常量名用大写, 变量名用小写表示, 以增加可读性。

2) 遗漏分号出现的错误, 这个错误一般常出现在初学者所编程序中。

3) 忽略了“==”与“=”的区别。

在高级语言BASIC程序中, 用“=”符号作为关系运算符“等于”。如在程序中可以这样写

但C语言中, “==”是关系运算符, “=”是赋值运算符。例如:

前者是比较运算, 判断z和10是否相等, 如果相等, 后者则是把x值赋给z。由于习惯成自然。初学者在这方面很容易出错。

4) 忘记必要的逻辑运算符, 例如:

此表达式的含义为x>4并且x<5, 但在C语言中。关系运算符遵循左结合性, 即结合性从左向右, 在此规则下, 4<x<5的求值是先求x>4, 得到一个逻辑值0或1, 再继续拿这个数与5比较, 结果恒为真, 失去本题目本意。对于类似情况, 正确的做法是, 应使用逻辑表达式, 写成:

5) 地址运算符“&”不能正确合适添加。

这类做法是错误的。Scanf函数的作用是:按照x、y在内存的地址将x、y的值存进去。“&x”指x在内存中的地址。“&y”指y在内存中的地址。

应写成:

6) 输入数据的方式与要求不符。

(1) 例如:scanf ("%d%d", &c, &d) ;。输入时, 不能用逗号作两个数据间的分隔符, 如下面输入不合法:5, 6。输入数据时, 在两个数据之间以一个或多个空格间隔, 也可用回车键, 跳格键tab。

(2) scanf ("%d, %d", &c, &d) ;

C规定:如果在“格式控制”字符串中除了格式说明以外还有其它字符, 则在输入数据时应输入与这些字符相同的字符。下面输入是合法的:5, 6回车。但此时不用逗号而用空格或其它字符是不对的。例如:56回车, 或者5:6回车。

7) 输入数据的同时时, 规定了输入数据的精度。例如:scanf ("%8.3f", &c) ;应该是输入数据的时候不能规定精度, 此种做法不合法.

8) switch语句中忘掉了必要的break语句。

例如:根据考试成绩的等级打印出百分制数段。

由于漏写了break语句, case只起标号的作用, 而不起判断作用。因此, 当x值为1时, 输出为:Spring Summer Autumn Winter Error!

原因是丢失了break语句, 正确的写法是:

9) 忽视了while和do-while语句在细节上的区别。

可以看到, 当输入W的值小于或等于20时, 二者得到的结果相同。而当W>20时, 二者结果就不同了。因为while循环是先判断后执行, 而do-while循环是先执行后判断。对于大于20的数while循环一次也不执行循环体, 而do-while语句则要执行一次循环体。

10) 使用未赋值的自动变量, 例如:

运行结果是-858993460, 这里的-858993460是一个不可预知的数, 因此, 在引用自动变量时, 必须对其初始化或对其赋值。

11) 使用库函数时, 没有用“#include”命令将该原型函数的头文件包含进来, 例如:

输出结果为:w=0.000000, 这显然是错误的, 正确的写法是:

12) 在定义数组时, 将定义的“元素个数”误认为是可使的最大下标值。

C语言规定:定义时用c[10], 表示c数组有10个元素。其下标值由0开始, 所以数组元素c[10]是不存在的。

13) 初始化数组时, 未使用静态存储。

int a[3]={3, 4, 5};这样初始化数组是不对的。C语言规定只有静态存储 (static) 数组和外部存储 (exterm) 数组才能初始化。应改为:static int a[3]={3, 4, 5};。

14) 定义形参时同时定义了函数中的局部变量。

形参应该在函数体外定义, 而局部变量应该在函数体内定义。应改为:

15) 对指针变量赋予非指针值, 如:

由于p是整型, 而q是指向整型的指针, 它们的类型并不相同, q所要求的是一个指针值, 即一个变量的地址, 应该写成:

int p, *q;q=&p;这样才是正确对指针变量赋予非指针值。

4 结语

对于任何一种程序语言的学习, 没有捷径, 只有反复上机实验, 发现问题不断解决问题, 熟能生巧, 举一反三。

摘要:就C语言的语句展开分析, 介绍了C语言中的语句分类、C语言与其他许多语言相比具体有什么特点, 最后通过实例例举C语言常见错误及简析。

关键词:C语言,语句分类,常见错误

参考文献

[1]李建华.C语言程序设计[M].上海:上海复旦大学出版社, 2014.

[2]郑凯.二级C语言程序教程[M].武汉:华中科技大学出版社, 2011.

C语言程序设计常见错误解析 篇5

一、常见错误分类

1. 语法错误

指违背了C语法的规定, 对这一类错误, 编译程序一般能给出“出错信息”, 并且告诉在哪一行出错, 但经常出现出错位置不准确, 导致初学者无法完成程序的调试。

2. 逻辑错误

程序并无违背语法规则, 但程序执行结果与原意不符。这是由于程序设计人员设计的算法有错或程序编写有错, 导致逻辑上出现错误, 这一类错误往往是最难于解决的, 对于初学者更是难于解决。

3. 运行错误

程序无语法错误, 也无逻辑错误, 但在运行时出现错误甚至是停止运行。比如程序不具有“健壮性”就会出现此类错误。

二、常见语法错误解析

1. 变量未定义

当程序编译运行时, 出现“undefined symbol‘x’in function main”错误信息时, 就是提示在主函数里变量x没有定义;可能在程序定义变量x就漏掉没定义或者大小写混淆了, 加上变量x的定义语句或者大小写统一后该问题就解决了。

2. 语句丢分号

当程序编译运行时, 出现“statement missing;in function main”错误信息时, 就是提示在主函数中某行语句少了分号, 找到丢了分号的语句加上分号该问题就解决了。

3. 复合语句丢右半边花括号

当程序编译运行时, 出现“compound statement missing}in function main”错误信息时, 就是提示在主函数中某个复合语句少了右半边的花括号, 找到对应位置加上}就可以了。

4. 复合语句丢左半边花括号

当程序编译运行时, 出现很多个错误, 而且错误信息都一样, 即“declaration syntax error”, 基本可以确定是某个复合语句少了左半边的花括号, 就导致复合语句中所有语句都出现这样的错误提示信息, 找到复合语句的起始位置加上{就可以了。

5. 错把“=”当成“==”

在使用条件表达式时, 若错把“=”当成“==”使用会导致运行结果与题意不符, 如:

程序运行时, 无论输入多少运行输出结果都是1, 原因就在错把x==1写成x=1了, x=1相当于对变量x赋值1, 使得if语句后面的表达式永远为真, 所以输出都是1。所以要正确理解使用“=”和“==”。

6. 在不需要加分号的地方加了分号

在进行选择结构和循环结构程序设计时, 一定记得不要在if和while等后面的表达式后括号外加上分号, 否则会导致程序出错。

若有以下程序段:

按照语法要求, if的子句若是两条以上语句必须形成复合语句, 在if (a>b) 后面本不该加上分号, 但错误的加上了以后运行会报错, 提示你else位置出错, 没有正确和if相匹配, 原因是错误加上分号以后分号就成了if语句的子句, 如果想在if语句成立时可以执行语句a>b就必须去掉分号或者将分号和语句max=a一起复合成复合语句。

若有以下程序段:

程序的本意是求输入的正数的和, 但在编译运行时, 输出的结果却不是正数之和, 原因在于错误的在语句while (a>0) 后面加了分号, 加了分号导致该分号成为了while语句的子句, 当a>0时相当于什么都不做, 所以无法实现将正数进行累加, 若加正确实现程序本来功能, 应该将分号去掉或者将分号和语句s=s+a;一起用花括号复合成复合语句。

7. 在scanf函数语句里没有正确使用取址符&

按照语句要求, 在使用格式输入函数scanf时, 必须使用地址表列对变量进行赋值, 否则变量无法正确得到所赋的值, 但程序编译运行时并不报错, 只是运行结果与预期不符, 这就需要编写者自行进行调试, 利用断点或单步调试来测试每一步执行的结果, 最终解决问题。

若有以下程序段:

程序编译运行时并没有出错报告, 运行时输入2, 3输出结果是a=2, b=x。x是变量b在内存中所占单元里初始化的数值, 预先无法知道x到底是多少, 为什么会得到这样的输出结果?原因就是变量b前的取址符丢掉了, 导致无法正确将数值3存储到变量b在内存中所占的存储单元, 因此变量a可以正确得到赋值而变量b却无法得到正确赋值。

8. 输入的数据形式与要求不符

在用scanf进行数据输入时, 要求输入格式必须与格式提示符格式保持一致, 否则尽管变量前都正确加了地址符&也无法使变量正确得到赋值。

如在7的程序段中, 运行时输入的两个数据之间必须用逗号进行分隔, 即2, 3;而且不能加有其他的输入成分, 否则都会导致变量无法正确被赋值, 如输入2 3, 2;3等等都不正确, 这样输入变量a可以正确得到赋值, 但变量b无法正确得到赋值;若输入a=2, b=3诸如此类的话将导致变量a和b斗无法正确被赋值。

以上各种语法错误是初学者在编写调试程序时会经常遇到的, 还有很多其他的错误信息随着学习的时间的推移都会遇到, 如在学习数组时会遇到一些与数组相关的错误信息, 经过不断的学习, 积累调试经验这些问题都会迎刃而解的。

三、初学者编程时的注意事项

1. 先纸上编写然后上机运行

对于初学者来说, 如果采用直接上机进行编写编调试的话效果肯定不好, 加上对语法的理解应用不够熟练常常导致束手无措;如果能在上机前先将程序在纸上写好然后再上机运行效率将大大提高。

2. 在人工检查无误后才可以上机调试

在编译运行时, 有时提示的出错行并不是真正出错的行, 如果在提示出错的行上找不到错误的话应该到其上下各一行查看。另外, 有时提示出错的类型并非绝对准确, 由于出错的情况繁多而且各种错误互有关联, 因此要善于分析, 找出真正的错误。

3. 运行结果不对, 多数属于逻辑错误

逻辑错误比较难于修改调试, 要经过一段时间的学习积累, 才能较快的解决这一问题。

参考文献

[1]谭浩强著, C程序设计[M], 北京:清华大学出版社, 2005.7

[2]刘若华, C语言程序设计教学中常见错误及分析[J], 农业网络信息, 2011.02

C语言中常见错误 篇6

关键词:C语言,常见错误,程序调试,实例

C语言是在国内外广泛流行、使用的一种计算机高级程序设计语言。它的主要特点是:概念简洁、数据类型丰富、表达能力强,运算符多且使用方便灵活。与其它程序设计语言相比较,具有灵活的编程风格,语法限制不太严格,程序设计自由度大(例如:一个语句可以采用多种方式,分多行撰写;对数组下标越界不做检查;整型、字符型和逻辑型的数据可以通用等)。这就给程序设计人员留下“灵活的余地”,但是由于这个灵活往往给程序调试,尤其对初学C语言的人来说,经常会出一些连自己都不知道错在哪里的实例。看着有错的程序,不知该如何进行修改。通过在C语言的教学与研究过程中,分析了一些关于C语言程序设计时容易犯的错误实例,提供给学习C语言的同学及相关人员参考。

1 C语言常见错误实例与分析

实例1.Printf语句中“控制字符串”部分分写在不同的行。

例如:main()

该程序的目的是为了显示这样的结果:*****

但程序运行后却出现错误信息:“Unterminated string or character constant in function main”,对上述错误,只要在程序第二行、第三行的最后分别加上“”即可得到正确的结果,也就是说printf语句中的“控制字符串”部分分写在不同的行时加“”连接。

实例2.忽略了“=”与“==”的区别。

在许多高级语言中,用“=”符号作为关系运算符“等于”。如在BASIC程序中可以写if(m=10)then…,但C语言中,“=”是赋值运算符,“==”是关系运算符。

例如:if(m==10)m=n;

前者是进行比较,m是否和10相等,后者表示如果m和10相等,把n值赋给m。由于习惯问题,初学者往往很容易犯这样的错误。

实例3.定义变量的位置不正确。

例如:#include

程序运行后出现错信息“Improper use of a typedef symbol in function main”,只要把第六行:FILE*fp;放到第四行前,程序通过。原因是:说明部分要放在其他语句之前。

实例4.将字符常量与字符串常量混淆。

在这里就混淆了字符常量与字符串常量,字符常量是由一对单引号括起来的单个字符,而字符串常量是一对双引号括起来的字符序列。C规定以‘�’作字符串结束标志,它是由系统自动加上的,所以字符串“M”实际上包含两个字符:‘M'和‘�',而把它赋给一个字符变量是不正确的。

实例5.输入变量时忘记加地址运算符“&”。

这是不合法的。Scanf函数的作用是:按照a、b在内存的地址将a、b的值存进去。“&a”指a在内存中的地址。“&b”指b在内存中的地址。

实例6.输入数据的方式与要求不符。

1)scanf("%d%d",&x,&y);

输入时,不能用逗号作两个数据间的分隔符,如下面输入不合法:

输入数据时,在两个数据之间以一个或多个空格间隔,也可用回车键,跳格键tab。

2)scanf("%d,%d",&x,&y);

C规定:如果在“格式控制”字符串中除了格式说明以外还有其它字符,则在输入数据时应输入与这些字符相同的字符。下面输入是合法的:

此时不用逗号而用空格或其它字符是不对的。如下面输入不合法:

又如:scanf("a=%d,b=%d",&a,&b);输入应如以下形式:

实例7.输入字符的要求与格式不一致。

在用“%c”格式输入字符时,“转义字符”和“空格字符”都作为有效字符输入。

例如:输入O K!

则字符“O”送给c1,空格字符“”送给c2,字符“K”送给c3,因为%c只要求读入一个字符,后面不需要用空格作为两个字符的间隔。

实例8.同时定义了形参与函数中的局部变量。

形参应该在函数体外定义,而局部变量应该在函数体内定义。应改为:

实例9.误用变量定义数组。

数组名后用方括号括起来的是常量表达式,可以包括常量和符号常量。即C不允许对数组的大小作动态定义。

实例10.被调用的函数未在主函数中进行声明。

例如:main()

程序运行后出现错误信息:“Type mismatch in redeclaration of‘swap’”,只要在程序的第二句int a,b;前加一句:void swap();程序运行通过。也就是说:被调用函数的定义出现在主调函数之后(除了函数的值是整型或字符型的),要在main()函数中对被调用函数进行说明,void型函数也不例外。

2 结论

通过上面这些实例的分析,可以看出,由于C语言的开放式编程风格,让C语言初学者,在进行C语言程序设计时往往会出现一些微妙的、不易觉察的错误。C语言作为一门完善的编程语言,具有它的科学性与严谨性。因此,只有在充分掌握和熟练运用C语言的基本概念、语法规范及结构的基础上,才能真正享受到C语言灵活自如的编程风格的魅力,这也是学习一切科学知识的基本方法。

参考文献

[1]谭浩强.C程序设计[M].北京:清华大学出版社,2008:37-242.

[2]杨路明.C语言程序设计[M].北京:京邮电大学出版社,2006:20-150.

C语言中常见错误 篇7

C语言中指针的引入是为了便于直接与硬件进行交互, 通常把能够表示内存单元的地址成为指针。

指针是C语言中的一个重要概念, 和特色。正确而灵活地运用指针, 可以有效地表示复杂的数据结构;能动态分配内存;方便地使用字符串;能直接处理内存单元地址等。同时, 也正是由于指针的这些特点, 其使用也是相当灵活。本文将以实例来说明在指针使用方面容易出现的一些错误, 并分析和讨论如何解决这些问题。

2 常见问题及解决办法

2.1 指针的初始化

2.1.1 错误示例

int*p;

printf (“%d”, *p) ;

编译时出现警告:“p”未进行初始化, 程序在运行时报错。

2.1.2 解决办法

上述错误在于未将p指向某个内存单元, 便进行引用, 导致程序无法运行。在使用指针变量之前, 应确保为指针分配了某个内存空间, 将其指向某个可用的单元。可更改如下:

int a=1;

int*p=&a;

printf ("%d", *p) ;

2.2 指针的内存分配问题

由指针的定义知, 指针指向的地址为内存空间, 其本身一般为指针变量, 因变量的使用均需占用内存, 且指针变量所指向的内容为内存地址, 因而指针的内存空间分配问题也显得极为重要。通过指针可以动态分配一块内存区域, 而这一区域的索引就是该段内存的首地址, 这就为动态内存分配提供了便利, 因而通过指针来索引所分配的内存空间便成为了一种非常恰当的方式。

2.2.1 错误示例

int*p;

scanf ("%d", p) ;

printf ("%d", *p) ;

编译成功, 程序运行时可输入一个整型数据, 但无法输出该数据。

2.2.2 解决办法

上述程序已定义了一个指向整型变量的指针p, 但未为p分配空间, 程序可以输入, 但是无法输出, 是因为p所指向的内容不明确。改正如下:

int*p;

p= (int*) malloc (sizeof (int) ) ;

scanf ("%d", p) ;

printf ("%d", *p) ;

2.2.3 指针使用过程中的内存分配方式

(1) malloc () 函数

malloc () 函数用来分配内存, 该函数声明 (函数原型) 为:void*malloc (unsigned size) ;

malloc向系统申请分配指定size个字节的内存空间, 返回类型是void类型。void表示未确定类型的指针。使用时, 需包含头文件malloc.h或stdlib.h, 由用户指定分配的字节数, 在返回后强行转换为实际类型的指针。如上一节中的程序。

(2) realloc () 函数

realloc () 函数用来重调已分配空间的大小, 该函数声明为:void*realloc (void*block, int size) ;

block是指向要扩张或缩小内存空间的指针, size指定新的大小。realloc和malloc函数的区别在于malloc是为新的指针分配空间, 而realloc是为已存在的指针重新分配大小, 可通过下面的示例来说明:

int*p;

p= (int*) malloc (8) ;

p= (int*) realloc (p, 12) ;

通过malloc函数为新的指针p在内存中开辟了8个字节单元的空间, 而realloc函数将p原先分配的8个字节空间扩充为12个字节大小。

(3) calloc () 函数

calloc () 函数用来分配一个能容纳n个元素, 每个元素长度为size的内存空间, 该函数声明为:

void*calloc (unsigned n, unsigned size) ;

在内存的动态存储区中分配n个长度为size的连续空间, 函数返回一个指向分配起始地址的指针;如果分配不成功, 返回NULL。calloc在动态分配完内存后, 自动初始化该内存空间内容为0, 而malloc不进行初始化, 所分配的空间里边是随机的数据。示例如下:

int*p= (int*) calloc (10, sizeof (int) ) ;

for (int i=0;i<10;i++)

printf ("%3d", *p++) ;

程序中为p指针分配了10个指向整型变量的指针空间, 该程序运行时将输出10个0。

2.3 指针指向的数据类型错误

在程序需要使用函数时, 可能会使用作为临时变量的某个指针, 通常情况下, 指针所指向的变量类型均是已确定的, 当其指向不同类型的变量时, 便会产生问题。请看下面的问题

2.3.1 错误示例

主函数中的函数调用为:

function (1) ;

编译时提示:

cannot convert from'int*'to'float*' (指针类型不能转换)

2.3.2 解决办法

出现上述指针类型不匹配的问题, 可使用强制类型转换解决如下:

但是强制类型转换会带来新的问题, 它会导致指针指向空间的变化。例如:在C语言中short型占2个字节单元, 而int型占用4个字节单元内存, 如图1所示。

程序中使用输出语句:

prinf (“%d”, *p) ;

当p为是int型指针时, 输出为:12345678;当p为short型指针时, 输出为5678。由此可知, 强制类型转换可能会使指针的作用域范围改变至无法预测的内容, 可能会产生错误, 故在程序中出现变量所占内存空间大小不同时, 最好不要使用强制类型转换方法。

2.4 指针指向数组时的越界问题

数组名表示一个数组在内存中的起始地址, 因此可以使用下述语句将指针变量指向一个对应类型的数组:

int array[10];

int*p=array;

但是在实际使用时, 在移动指针时指针发生越界现象的情况却是不易觉察的。如下例:

2.4.1 错误示例

此程序在编译和链接的时候编译器不会报错, 运行时也可以输入, 但是输出的却是一些非预期的数据。初学者在开始时可能没有注意到p所指向位置的问题, 在第一个循环中将p已经指向了array的最后一个元素, 导致在第二个循环的时候p的指向已经越界了。

2.4.2 解决办法

在两个循环中间加入语句:

p=array;

程序就可以正常运行了, 即将p指向的内容重新定位到数组开始的位置。在编写程序的时候不经意间就会遇到这类隐蔽性的错误, 在此指出, 要时刻关注指针当前所指向的位置。

2.5 指针作为函数参数时使用错误

编程内容的重点之一就是函数的编写与调用。在函数调用时传给函数的是实参, 而实参与形参的关系若区分不清也会引起不必要的错误。

2.5.1 错误示例

下面是一个给两个数从小到大排序的函数:

程序运行结果:不管输入的两个数大小如何, 均原样输出。

2.5.2 解决办法

上述swap函数含有两个参数, 均是指针类型, 函数内定义了两个临时变量用于接收实参的值, 但是程序仅做了临时变量x和y大小的排序, 没有对main () 中的两个指针指向的数据进行数值大小的排序, 因为swap函数修改的并不是实参p1和p2所指的内容, 只是使用了它们传过来的值。程序中可将swap () 直接改为对实参进行操作, 在本例中它们分别是a和b的内容。修改如下:

程序运行时即可得到正确的排序结果。

2.6“野指针”问题

“野指针”不是NULL指针, 是指向“垃圾”内存 (不可用内存) 的指针。一般情况下不会错用NULL指针, 因为用i语句很容易判断。但是“野指针”是很危险的, if无法判断一个指针是正常指针还是“野指针”。如下例:

2.6.1 错误示例

程序可正常编译和连接, 但是运行时弹出警告:“Debug Assertion Failed”, 其原因就是“野指针”的存在。想要避免“野指针”的问题, 便需要了解“野指针”的成因。

2.6.2“野指针”的成因

“野指针”的成因主要有3种:

(1) 指针变量没有被初始化。任何指针变量刚被创建时不会自动成为NULL指针, 它的缺省值是随机的, 它会乱指一气。所以, 指针变量在创建的同时应当被初始化, 要么将指针设置为NULL, 要么让它指向合法的内存。

(2) 指针p被free或者delete之后, 没有置为NULL, 让人误以为p是个合法的指针。free和delete函数只是把指针所指的内存给释放掉, 指向该段内存的指针任然会指向这段内存的首地址, 只不过这段内存不能再被程序使用而已。通常情况下会用语句if (p!=NULL) 进行防错处理, 但是此时if语句却起不到防错作用, 因为即便p不是NULL指针, 它也不指向合法的内存块, 也不能使用。

(3) 指针操作超越了变量的作用范围。如上节所述。

2.6.3 解决办法

针对上述野指针的成因分析, 可以使用下述方法避免由“野指针”的存在而引起的错误:

(1) 指针变量在定义时或引用之前对其进行初始化操作。

(2) 在释放指针所占内存空间的操作中, 在调用free函数之后将原指针赋值为NULL。在程序中不要再次使用已释放空间的指针。

(3) 严格控制变量的作用域, 尤其是指针所指的空间, 避免发生越界的问题。

3 结语

通过简单的实例说明了在C语言编程中使用指针经常会出现的一些问题, 讨论了如何为指针分配空间, 各种分配方式有何差异, 指针所指向的数据类型有何不同, 指针引用和“野指针”等问题, 这些都是在编程中经常会遇到的问题。文中实例简单、程序清晰, 所列出的代码均为程序中的主要代码, 省去了头文件包含代码和main () 函数的主体内容, 与实际程序略有不同。在通常的编程中遇到使用指针的情况时, 一般要都要复杂于这些简单的例子, 所以编程人员更要分析和掌握对基本问题的解决办法, 养成良好的编程习惯, 力争减少由于代码编写错误而花费的时间。

参考文献

[1]谭浩强.C程序设计 (第三版) .北京:清华大学出版社, 2005.

[2]郭旭文, 郭斌, 主编.C语言程序设计与项目实践.北京:电子工业出版社, 2011.

[3]王为青, 刘变红.C语言高级编程及实例剖析.北京:人民邮电出版社, 2007.

C语言中常见错误 篇8

1 词法“陷阱”

试想下,当我们阅读一个句子时,我们并不去考虑组成这个句子的单词中单个字母的含义,而是会把单词作为一个整体来理解。的确,字母本身并没有什么意义,而是我们将字母组成单词,然后给单词赋予一定的意义。对于C语言编写程序,也是一样的道理。

“符号”是程序的一个基本组成单位,作用相当于一个句子中的单词。如下将讨论符号以及符号间的一些常见问题。

1.1“=”不同于“==”

在C语言中,符号“=”为赋值运算符,符号“==”为比较运算符。一般的,赋值运算相对于比较运算出现得更频繁,以此字符数较少的“=”被赋予了赋值运算的含义。学生在程序设计中,往往本意想用作比较运算,却可能无意中误写成赋值运算。如示例1:

执行程序时会发现即使输入a,b的值不相同,输出结果仍然是“a,b相等”。此问题的原因就在于if中的条件误将赋值运算符“==”写成了比较运算符“=”。

1.2“x<y<z”与“x<y&&y<z”

在c语言中关系运算符号与数学中接触到的比较符号,从使用方式和能够都很相似,所以误将两者完全等价。

如示例2:

执行程序时,输入“1 2 3”或“3 2 1”,没有输出结果。此问题在于对“a>b>c”关系运算符应用的误解。比如:输入“1 2 3”,分析“if(c>b>a)”的结果,由于关系符“>”的结合性自左向右,即“3>2”比较的结果为“真”。在C语言关系运算中,以“1”代表“真”,以“0”代表“假”,所以最终比较的是“1>1”,自然运算结果为“假”,也就不会出现预期的输出“c最大”。因此,正确代码应将三段条件结构依次修改为:if(a>b&&a>c)、if(b>a&&b>c)、if(c>b&&c>a)。

1.3 scanf()函数的几点注意问题

1.3.1输入数据的方式与要求不符

因C语言规定:如果在“格式控制”字符串中除了格式说明以外还有其它字符则在输入数据时应输入与这些字符相同的字符。

比如:scanf("%d,%d",&a,&b);

输入时,如果用空格作两个数据间的分隔符输入: 4 5,则不合法。

合法的输入形式应是: 4,5

再如:scanf("a=%d,b=%d",&a,&b);

正确的输入形式应是:a=3,b=4

1.3.2输入数据中的空格和回车

scanf()函数,在用“%c”格式声明输入字符时,有不同于其他格式类型需注意的地方。字符格式类型中,空格符、转义字符都作为有效字符;而对于数值型数据,空格符、回车键、Tab键或非法数值字符均认为数值字符输入的终止符。

如下示例3:

执行时输入“f”,结果没有等输入(y/n)就显示结果如下图1。

不难发现字符变量ms得到的字符为“回车”,即输入“f”后用户敲入的“回车键”。如何避免此种现象的产生,可以采取以下几种方法。

方法一:规避编译器误将回车键作为字符存储至字符变量ms中,可以使用scanf("n%c",&ms);

方法二:在两次输入语句中间加入清除缓冲流的语句,fflush(stdin);

改进后,正确执行结果如图2。

1.4 字符与字符串

C语言中,单引号和双引号含义迥异,在某些情况下如果把两者弄混,编译器并不会检测报错,从而在运行时会产生难以预料的结果。

用单引号引起来的一个字符实际上代表一个整数,整数值对应该字符在编译器采用字符集中的序列集。用双引号引起来的字符串,代表着一个指向无名数组起始字符的指针,该数组被双引号之间的字符以及一个空字符’’初始化。具体不同,如下示例5:

运行结果如下图3,如果语句换成printf('n');虽编译时没有异常,但运行时应用程序错误,具体问题如图4。

2 语法“陷阱”

要理解一个C程序,仅仅理解组成该程序的符号是不够的。初学者还必须理解这些符号是如何组成表达式、语句和程序的,有时候这些定义和直觉相悖,容易引起混淆。下面就讨论一些容易产生问题的语法结构。

2.1 语句结束符:分号的使用

在C程序中如果不小心多写了一个分号可能不会造成不良后果,因为这实际上产生一个空语句。但是也有重要的例外,在if或者while子句之后需要紧跟一条语句时,如果此时多加了一个分号,就会产生出人意料的结果。示例6:

程序运行结果没有输出。但如果if(x>2)条件后面加上分号,则输出“x>2”。同样的道理,如下,正常输出结果为“543”;而如果while子句后加上分号,此程序变成了“死循环”。示例7:

2.2 switch语句

C语言的switch语句控制流能够依次通过并执行各个case部分,这一点是C语言的不同之处。如下分析有无“break”语句的效果,示例8:

程序运行结果为:red。如果将程序中三个“break”全部删除,程序运行结果为:redblueyellow。原因是C语言中的switch语句在执行了控制流程中的第一个之后,会自然而然地顺序执行下去,直到最后一个case语句。

实际中,C语言中switch语句的这种特性,既是它的优点,又是它的一大弱点。说到弱点是因为初学者很容易遗漏各个case后面的break语句,造成难以理解的程序结果。说到优势是因为当程序员有意的略去一个break语句,则可以实现多个分支共同作用处理,重要的是看程序员如何应用。

2.3 else“悬挂”引发的问题

此问题是大多数初学者很容易弄错,而且并非C语言独有,其他语言也会让程序员们常常失误。在应用多支路的程序设计中, 往往会用到if的嵌套结构,常常容易出现错误。

如实现如下的分段函数。程序代码示例9:

如上代码在执行测试时会发现实际输出结果与编程者的愿望相去甚远。原因在于C语言中有这样的规则,else总是与同一对括号内最近的缺少对于else部分的if结合匹配。也就是说,并不单单是x<0时y=-5,还包括x=0时y=-5。

故该问题用添加括号的办法,改为正确程序部分代码如下:

此时,else并没有同离它更近的第二个if匹配,而是与第一个if结合,因为第二个if已经被括号“封闭”起来了,构成了if的嵌套结构。

3 语义“陷阱”

3.1整数溢出

C语言提供的数据类型有许多,其中整型数据提供了三种不同长度的类别:short int、int和long int。不管是哪种数据类型都有一个固定的长度,它能存储的最大值是一个固定的整数,当尝试去存储一个大于这个固定最大值时,将会导致整数溢出.

例如:求满足条件1+2+3+…+n≤32767的最大整数n,如下实例10:

乍看该程序时无错误,但事实上,上列程序中的while循环是一个无限循环,原因在于int型数的表示范围为-32768到+32767, 当累加和sum超过32767时,便向高位进位,而对int型数而言,最高位表示符号,故sum超过32767后便得到一个负数,while条件当然满足,从而形成无限循环。解决此类问题是将数据容量升高,sum定义为long int型。

3.2求值顺序

可能说起求值顺序,许多人能联想到运算符的优先级问题,但其实这不是一回事。运算符优先级是诸如:a+b*c等同于a+(b*c);而求值顺序是诸如:if(n!=0&&x/n>y),此时即使n=0时,也不会出现“0作为除数”的错误。原因就是因为当n=0时,n!=0的表达式为0,不会再运算到后面的表达式。

C语言中某些运算符总是以一种已知的、规定的顺序来对其操作数进行求值,而另外一些则不是这样的。再如:a<b&&c<d;C语言中a<b应该首先被求值,如果a小于b,则进一步对c<d判断,最终得到表达式的值;但是如果a大于b,则表达式结果肯定为假, 也无须对后面的继续求值。这也就是常说的“运算符短路原则”。

C语言中只有四个运算符(&&、||、?: 、,)存在规定的求值顺序。逻辑运算符“&&”和“||”首先对左操作数求值,只在需要时才对右侧操作数求值。运算符“?:”是三元运算符,在a?b:c中,首先对操作数a进行判断,再确定求b还是c。如:1>2?3:4,由于1>2结果为假,则最终表达式值为4。而逗号运算符,首先对左侧操作数求值,然后该值被“丢弃”,再对右侧操作数求值。如:a=1,2,3;最终a的值为3。

4 总结

本文笔者通过多年的教学经验总结出一些应用性实例,针对初学者在学习C语言时易犯的错误,分类讨论后给予错误分析,并提出相应的解决方案。如想熟练掌握C语言,需要学生们不断地总结分析,大量的上机实践,这样才能积累更多的程序设计经验。

摘要:C语言是编程领域中很有影响力的一种程序设计语言。它简洁、紧凑,使用方便、灵活,并且具备高级语言和低级语言的特征。由于C语言的编译系统对语法的检查不如其他语言那么严格,因此C语言对使用者的要求比较高.笔者结合实际教学中的经验,分类列举出C语言中常见的错误进行分析与探讨,以此对初学者给予借鉴。

上一篇:双电源切换回路下一篇:农村社区卫生服务工作