QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2955|回复: 0
打印 上一主题 下一主题

[转帖]++C语言中常见错误++

[复制链接]
字体大小: 正常 放大
solucky        

17

主题

1

听众

109

积分

升级  4.5%

该用户从未签到

跳转到指定楼层
1#
发表于 2004-6-6 19:01 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
<>C语言的最大特点是:功能强、使用方便灵活。C编译的程序对语法检查并不象其它高级语言那么严格,这就给编程人员留下“灵活的余地”,但还是由于这个灵活给程序的调试带来了许多不便,尤其对初学C语言的人来说,经常会出一些连自己都不知道错在哪里的错误。看着有错的程序,不知该如何改起,本人通过对C的学习,积累了一些C编程时常犯的错误,写给各位学员以供参考。
. k/ ~+ M8 K9 O+ p' E% r1.书写标识符时,忽略了大小写字母的区别。
, b  P; p, I/ m% Y- S( [# m* w% Ymain()
9 w! h# m  O3 V5 _8 p{3 i) n. v" `$ c$ k8 b1 D
int a=5;, e* I& t2 g- Y  Y
printf("%d",A);" B% q. i2 l- B
}
) f& R- g1 ?4 F- J+ ^9 a5 n# F编译程序把a和A认为是两个不同的变量名,而显示出错信息。C认为大写字母和小写字母是两个不同的字符。习惯上,符号常量名用大写,变量名用小写表示,以增加可读性。; Q: G: R0 |3 b# l( m
2.忽略了变量的类型,进行了不合法的运算。( L1 I& ~2 L/ g  P: x+ I
main()
5 R1 G8 H0 P4 S% F{4 c) i; `/ z. S' f) q1 V# M. L* X
float a,b;
  N7 y* Z; i; g6 l5 j+ Cprintf("%d",a%b);3 s0 T# j; ], ?- J
}
9 J& j( l& @/ O2 ?" N%是求余运算,得到a/b的整余数。整型变量a和b可以进行求余运算,而实型变量则不允许进行“求余”运算。
4 z  l' ~/ G% Y6 V+ I( s3.将字符常量与字符串常量混淆。; G. r) w' N: s$ F
char c;, n5 c  H# q4 X7 ^" n% [! P
c="a";
7 o6 j# ?  {5 ]& ?6 V, o在这里就混淆了字符常量与字符串常量,字符常量是由一对单引号括起来的单个字符,字符串常量是一对双引号括起来的字符序列。C规定以“\”作字符串结束标志,它是由系统自动加上的,所以字符串“a”实际上包含两个字符:‘a'和‘\',而把它赋给一个字符变量是不行的。3 S& B. c2 d8 Y% p6 r3 K
4.忽略了“=”与“==”的区别。
8 h8 K) |4 I/ B在许多高级语言中,用“=”符号作为关系运算符“等于”。如在BASIC程序中可以写" }: k! g3 v2 n& R- [
if (a=3) then …
) r! I; \1 i+ e' E9 o! d9 ~0 N但C语言中,“=”是赋值运算符,“==”是关系运算符。如:
) Q. _! j$ `; D) yif (a==3) a=b;0 S5 G, Q# M# I* n, G/ n
前者是进行比较,a是否和3相等,后者表示如果a和3相等,把b值赋给a。由于习惯问题,初学者往往会犯这样的错误。; e8 \# E% R4 J3 F$ D# U
5.忘记加分号。) r0 [! G7 c$ K( |3 W, r% Y1 p
分号是C语句中不可缺少的一部分,语句末尾必须有分号。" ^+ F3 `7 x9 N; q
a=1* }5 B! b* z/ J$ s
b=2
. G& l6 Y/ |5 w9 q编译时,编译程序在“a=1”后面没发现分号,就把下一行“b=2”也作为上一行语句的一部分,这就会出现语法错误。改错时,有时在被指出有错的一行中未发现错误,就需要看一下上一行是否漏掉了分号。
* E6 h9 S" |& K{ z=x+y;
0 d) R3 L7 e$ [2 Lt=z/100;
1 w0 A) `6 q7 [7 M+ n7 {, w( V  k7 l4 dprintf("%f",t);" {7 \, Z2 ?: s
}
/ t3 a- |/ Z, z( F. r) \: t对于复合语句来说,最后一个语句中最后的分号不能忽略不写(这是和PASCAL不同的)。
& `/ \9 J( g0 h8 }) O/ J6.多加分号。2 f% r3 m1 W+ D" Q% F+ }2 J
对于一个复合语句,如:5 o4 V0 S6 ^# b
{ z=x+y;
+ M- N+ x' R5 O& ~% ^/ vt=z/100;+ S% k5 X/ c# g+ V7 u& {% W
printf("%f",t);6 r" |, A" E7 Z4 ?
};5 }+ X  a* Q$ ~% S. E7 ?% M* N, U
复合语句的花括号后不应再加分号,否则将会画蛇添足。
. g* m$ e: B+ }8 l; R又如:! N2 D2 y3 z2 K, ]% ?* D6 y! Z
if (a%3==0);9 \7 R/ _, D, H4 G
I++;
1 g1 ~, A9 m; ~! Y本是如果3整除a,则I加1。但由于if (a%3==0)后多加了分号,则if语句到此结束,程序将执行I++语句,不论3是否整除a,I都将自动加1。) f0 x* D& l& F  q. j  [
再如:
# ~' |' |- I9 pfor (I=0;I&lt;5;I++);
# _4 ?. h. a6 e# l4 Q' i: _{scanf("%d",&amp;x);' Y2 |" b4 `$ O
printf("%d",x);}, [+ _, z. ~6 ]6 E6 p4 ]: L9 u0 x0 A
本意是先后输入5个数,每输入一个数后再将它输出。由于for()后多加了一个分号,使循环体变为空语句,此时只能输入一个数并输出它。; E  a  H: j7 c
7.输入变量时忘记加地址运算符“&amp;”。- c1 v2 t% a1 ]' n8 ]3 R
int a,b;' v! Y+ Y& o: W; l$ ~; J
scanf("%d%d",a,b);* ]2 z* ~6 g2 A+ y0 i
这是不合法的。Scanf函数的作用是:按照a、b在内存的地址将a、b的值存进去。“&amp;a”指a在内存中的地址。1 ]+ B+ h) }" v& G7 P- E6 ^; J$ i/ w
8.输入数据的方式与要求不符。①scanf("%d%d",&amp;a,&amp;b);9 _+ d9 D1 ^# D; D
输入时,不能用逗号作两个数据间的分隔符,如下面输入不合法:& G& r, S+ C% G
3,4
- s4 {7 J4 P8 G7 j输入数据时,在两个数据之间以一个或多个空格间隔,也可用回车键,跳格键tab。
: i' Q* O! c: ]. @) K②scanf("%d,%d",&amp;a,&amp;b);
4 |7 n. s7 K$ Y# I9 pC规定:如果在“格式控制”字符串中除了格式说明以外还有其它字符,则在输入数据时应输入与这些字符相同的字符。下面输入是合法的:
- |' a6 P& i. V7 D0 H; D! }3,4 1 w5 y5 a/ x" b# p- s, b9 P
此时不用逗号而用空格或其它字符是不对的。
3 _' e7 r; Z0 X3 @' N: E, X3 4 3:4 3 n2 i. d; ]4 S1 r, r( T
又如:
" V3 z7 m" l' ]& T( k: v* Mscanf("a=%d,b=%d",&amp;a,&amp;b);
- z( J/ J& Z+ D/ y& w! p输入应如以下形式:
, b! e5 M4 ?9 x  g. ^9 ga=3,b=4
: s9 [8 r" ]' c" D  t9.输入字符的格式与要求不一致。( f, s! ]5 b! o0 \1 o0 F2 M7 e
在用“%c”格式输入字符时,“空格字符”和“转义字符”都作为有效字符输入。
6 ?8 I2 S" l4 Z( v( }3 m" M- R. zscanf("%c%c%c",&amp;c1,&amp;c2,&amp;c3);
7 i- ~$ y4 h& U3 `% o( Q如输入a b c
; u+ {* T% Y$ z字符“a”送给c1,字符“ ”送给c2,字符“b”送给c3,因为%c只要求读入一个字符,后面不需要用空格作为两个字符的间隔。
0 ~: D( S, P) \7 Q) V" o% ]10.输入输出的数据类型与所用格式说明符不一致。
1 Q2 E$ l4 F* L5 y5 \( q; B9 ^例如,a已定义为整型,b定义为实型
, b- R0 u2 d3 o8 {a=3;b=4.5;
' r) ~3 j" y" L  r, p# ?/ Hprintf("%f%d\n",a,b);
( U4 J; J3 z6 t+ b3 }; V9 H编译时不给出出错信息,但运行结果将与原意不符。这种错误尤其需要注意。8 [6 S+ P" k- U' I. m( T" f% l, M0 P
11.输入数据时,企图规定精度。" O) |5 |7 D# K% E- }: p
scanf("%7.2f",&amp;a);' i0 m2 s' @# N
这样做是不合法的,输入数据时不能规定精度。+ x5 B& |% v% R
12.switch语句中漏写break语句。
: f$ u3 X7 e. t& j2 c例如:根据考试成绩的等级打印出百分制数段。) {4 I* Q% u. M6 B- ]5 [3 t
switch(grade)
# d8 ~& l  }- [" J6 N% S1 _7 K{ case 'A':printf("85~100\n");
& \( [; C! p; O. Ecase 'B':printf("70~84\n");1 Y- X6 S3 F6 a3 S' u+ B& G
case 'C':printf("60~69\n");
5 O* Y8 U+ ], M* @8 Vcase 'D':printf("&lt;60\n");+ w7 f9 {# A# f4 \
default:printf("error\n");
) ^, P2 r+ s6 c1 t2 r; P: n由于漏写了break语句,case只起标号的作用,而不起判断作用。因此,当grade值为A时,printf函数在执行完第一个语句后接着执行第二、三、四、五个printf函数语句。正确写法应在每个分支后再加上“break;”。例如+ o. Q" h8 a' z1 M
case 'A':printf("85~100\n");break;
% C- j1 |3 d# U9 G! B( `+ Y13.忽视了while和do-while语句在细节上的区别。3 W4 ^. {. Q6 y" v4 {
(1)main()! y/ c  ^7 ^  C: W
{int a=0,I;
6 t( i5 Q- q" S5 n" oscanf("%d",&amp;I);: q% O. H  Z. U, d  K1 T7 z
while(I&lt;=10)( s2 x; J0 g: s4 D
{a=a+I;
( n. c6 H4 q% c( L* ^' S0 m4 TI++;
$ t. H$ b% Z7 `( B}( j& }  n" q' p  R+ R
printf("%d",a);
: {& T* t- j) X' H) ^7 o4 C}
  k4 E" F9 r' j# A7 b4 c(2)main()
! `3 F) X- L8 \4 b$ ?{int a=0,I;
, O8 r2 W$ V5 R0 l/ n6 Lscanf("%d",&amp;I);3 e) R' T! W4 O8 e: z
do  j8 L1 A" Q( _0 `- Q* ~8 w4 M
{a=a+I;
" i: }1 d: h) I8 E- Q) n1 }I++;
. E, ^0 }9 X* v0 C- R}while(I&lt;=10);
8 S$ ]$ x" M% R' y8 `5 tprintf("%d",a);1 G! R5 q; j' Y9 O6 }: [# I
}" o) O. S3 [3 e+ @; M! v
可以看到,当输入I的值小于或等于10时,二者得到的结果相同。而当I&gt;10时,二者结果就不同了。因为while循环是先判断后执行,而do-while循环是先执行后判断。对于大于10的数while循环一次也不执行循环体,而do-while语句则要执行一次循环体。
9 A  m$ B! Z9 o8 ]14.定义数组时误用变量。
3 M1 o* R" ?8 Q! G) Wint n;
' G4 ]# Q+ a" v" |1 T% Cscanf("%d",&amp;n);
4 }' `, q+ N. h5 Jint a[n];8 Y: |7 j3 S3 ^. G4 y
数组名后用方括号括起来的是常量表达式,可以包括常量和符号常量。即C不允许对数组的大小作动态定义。+ S# X7 i- O# O
15.在定义数组时,将定义的“元素个数”误认为是可使的最大下标值。
8 B6 N! p4 f  O+ d& i* j, t5 ?main()9 q  I6 j* y2 G. e4 I
{static int a[10]={1,2,3,4,5,6,7,8,9,10};
+ I" H1 @' S: pprintf("%d",a[10]);# k- W; `7 s5 Q2 F0 p
}
8 P3 ^% ?% e1 }+ T  OC语言规定:定义时用a[10],表示a数组有10个元素。其下标值由0开始,所以数组元素a[10]是不存在的。! G$ H) G; C4 Y
16.初始化数组时,未使用静态存储。! K! Z" q9 D0 v
int a[3]={0,1,2};# ?% w; K' b: g" _+ V3 f' A
这样初始化数组是不对的。C语言规定只有静态存储(static)数组和外部存储(exterm)数组才能初始化。应改为:
' I8 X3 s) B; [! s, H# p. d/ Bstatic int a[3]={0,1,2};
7 j! B( K* S0 J# E9 S17.在不应加地址运算符&amp;的位置加了地址运算符。
5 j* k) \) ^& `5 K' dscanf("%s",&amp;str);
" y) s' ?; [1 o% v5 M( w3 r7 o1 FC语言编译系统对数组名的处理是:数组名代表该数组的起始地址,且scanf函数中的输入项是字符数组名,不必要再加地址符&amp;。应改为:. p* @# a  j6 C. _8 L; U
scanf("%s",str);6 Z7 i3 a+ l$ W/ `
18.同时定义了形参和函数中的局部变量。
/ z9 p( a# I  C& K  Oint max(x,y)
0 c% ~' D+ |% ~# c% x) M3 cint x,y,z;* H/ {6 h$ a* I8 {0 B- v
{z=x&gt;y?x:y;% ]' `! \% q& M% E/ M8 U
return(z);
8 y" I8 `% n8 B# S" K}
) r6 C0 v+ o5 D# a! h形参应该在函数体外定义,而局部变量应该在函数体内定义。应改为:
# g" y7 |& w3 R8 N; Jint max(x,y)* o9 U* O  y4 _5 {' R0 O  q$ o
int x,y;7 U2 X. ~! l' U3 W
{int z;* v, b% o+ i$ ~6 a% t8 n% _( q
z=x&gt;y?x:y;! [$ g: A1 [/ s" T0 A: ?
return(z);( j) o- p" C9 Z
}</P>3 `# V) ]1 Q7 U- c+ U
<>以上错误中可能有些不符合新版的C语言,比如数组的初始化,新版中就可以是不是静态变量。由于是转贴就未加修改,以保持文章的原貌,请各位自加区别。<b>版权属于原创作者!!!</b></P>
zan
转播转播0 分享淘帖0 分享分享0 收藏收藏1 支持支持0 反对反对0 微信微信
笑一笑 只牵动苦涩的嘴角 我的寂寞谁知道 我害怕 用真心面对这世界 只好越来越沉默
您需要登录后才可以回帖 登录 | 注册地址

qq
收缩
  • 电话咨询

  • 04714969085
fastpost

关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

手机版|Archiver| |繁體中文 手机客户端  

蒙公网安备 15010502000194号

Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

GMT+8, 2026-7-20 03:51 , Processed in 0.436466 second(s), 51 queries .

回顶部