- 在线时间
- 0 小时
- 最后登录
- 2006-3-12
- 注册时间
- 2004-5-30
- 听众数
- 1
- 收听数
- 0
- 能力
- 0 分
- 体力
- 262 点
- 威望
- 0 点
- 阅读权限
- 30
- 积分
- 109
- 相册
- 0
- 日志
- 0
- 记录
- 0
- 帖子
- 27
- 主题
- 17
- 精华
- 1
- 分享
- 0
- 好友
- 0
升级   4.5% 该用户从未签到
 |
< >C语言的最大特点是:功能强、使用方便灵活。C编译的程序对语法检查并不象其它高级语言那么严格,这就给编程人员留下“灵活的余地”,但还是由于这个灵活给程序的调试带来了许多不便,尤其对初学C语言的人来说,经常会出一些连自己都不知道错在哪里的错误。看着有错的程序,不知该如何改起,本人通过对C的学习,积累了一些C编程时常犯的错误,写给各位学员以供参考。' ]6 J- Z' m9 s2 W L, n2 {
1.书写标识符时,忽略了大小写字母的区别。
2 e' e: F! S+ b5 V6 b9 hmain()! s: n5 _- n" F- B
{5 {$ Q+ x7 I W8 |
int a=5;
3 N3 U$ t3 V& D& n7 Pprintf("%d",A);0 u* G4 `. M* C+ H' M" a( i
}7 g, J# a( z; Y: x9 I# h
编译程序把a和A认为是两个不同的变量名,而显示出错信息。C认为大写字母和小写字母是两个不同的字符。习惯上,符号常量名用大写,变量名用小写表示,以增加可读性。9 @/ ~7 o/ x+ W( G3 y2 c9 R" S
2.忽略了变量的类型,进行了不合法的运算。( u. Z \4 ~/ |+ @2 E2 @
main()
) @0 O7 n5 _5 [) N* h. h{
+ e3 Z0 }: \4 u2 I, c) I5 Kfloat a,b;. y y& Y0 X, j( ? x5 j
printf("%d",a%b);. A- @8 w3 {' X# s
}
; x& [6 _+ T% n a3 U& h( u2 Z4 `%是求余运算,得到a/b的整余数。整型变量a和b可以进行求余运算,而实型变量则不允许进行“求余”运算。) A4 w0 x% l0 d* V! g$ U5 _( c0 v, v
3.将字符常量与字符串常量混淆。 Z& X/ D4 i' h" D
char c;9 { z* O$ E7 F
c="a";, \% L! d$ x! Q0 X* N4 a3 l r
在这里就混淆了字符常量与字符串常量,字符常量是由一对单引号括起来的单个字符,字符串常量是一对双引号括起来的字符序列。C规定以“\”作字符串结束标志,它是由系统自动加上的,所以字符串“a”实际上包含两个字符:‘a'和‘\',而把它赋给一个字符变量是不行的。
2 n& z$ K2 t. S: p" p) ^1 Q8 W4.忽略了“=”与“==”的区别。
) U# C {& N4 X; h4 h在许多高级语言中,用“=”符号作为关系运算符“等于”。如在BASIC程序中可以写! m. j" F n& W6 U3 `8 z
if (a=3) then … F# ^4 w( i5 _: r
但C语言中,“=”是赋值运算符,“==”是关系运算符。如:) a( j0 l' m- D1 a+ M5 p/ H
if (a==3) a=b;
; \4 n: T, f2 s& e前者是进行比较,a是否和3相等,后者表示如果a和3相等,把b值赋给a。由于习惯问题,初学者往往会犯这样的错误。8 i! _# t4 |& \/ P# w
5.忘记加分号。$ e: l7 r# J/ }4 i0 T
分号是C语句中不可缺少的一部分,语句末尾必须有分号。7 c* C- ~* R- L9 t
a=1( W4 `5 e7 s+ q% ?: ~2 Q" Y6 o
b=25 O8 K' a/ E& _8 g4 f7 m) c
编译时,编译程序在“a=1”后面没发现分号,就把下一行“b=2”也作为上一行语句的一部分,这就会出现语法错误。改错时,有时在被指出有错的一行中未发现错误,就需要看一下上一行是否漏掉了分号。
3 g9 n- h( a, y; C F2 u{ z=x+y;
/ _! Z, b3 i# Dt=z/100;8 A( }* N; ]! o1 H3 J
printf("%f",t);- o1 B" ^. X) i' I6 O: W0 ^
}* ?6 t6 B1 [/ d7 r- E# a
对于复合语句来说,最后一个语句中最后的分号不能忽略不写(这是和PASCAL不同的)。 E u$ d+ Y4 p, _; R; R: o$ M/ p
6.多加分号。# B* L; \9 W& n6 i3 o6 \/ [
对于一个复合语句,如:$ T$ l& N! X8 ]: N: T D/ v
{ z=x+y;
3 `+ t. N3 Q; ]( u7 ~0 A0 t5 Lt=z/100;
3 U8 [2 L! t: k( g! W! {printf("%f",t);
& d! p$ X) Y1 {! q+ _% P" x};
9 K1 U' X6 r2 A$ `/ G4 `" t1 i复合语句的花括号后不应再加分号,否则将会画蛇添足。8 V0 [' o* ]7 V4 C: e0 B; P. ~1 a
又如:# W H, q) m5 ]" h
if (a%3==0);" H% [* P, X8 U& P
I++;
& p) `3 E& P$ X/ i- T( E本是如果3整除a,则I加1。但由于if (a%3==0)后多加了分号,则if语句到此结束,程序将执行I++语句,不论3是否整除a,I都将自动加1。' l7 Y4 W5 w' @6 _% X$ Q- y
再如:
. f3 C" h. ?+ B* O0 A( ]5 k* F4 c2 x4 vfor (I=0;I<5;I++);
! q& H' W5 a& p# @; L' Z# {: e* j{scanf("%d",&x);9 N7 c* a. M, K; M. W
printf("%d",x);}7 m, R/ |. s( x6 V4 Y
本意是先后输入5个数,每输入一个数后再将它输出。由于for()后多加了一个分号,使循环体变为空语句,此时只能输入一个数并输出它。( z9 p3 N6 h. }5 `
7.输入变量时忘记加地址运算符“&”。
0 @/ f! c- b {$ L5 W- x) n5 s# tint a,b;" g5 m0 D& |) x
scanf("%d%d",a,b);3 \8 P) S/ H, ^6 O j
这是不合法的。Scanf函数的作用是:按照a、b在内存的地址将a、b的值存进去。“&a”指a在内存中的地址。
, W5 c+ b$ M5 e8 N) T% S0 M! h5 o8.输入数据的方式与要求不符。①scanf("%d%d",&a,&b);& h' B0 T+ f) O: ]2 n
输入时,不能用逗号作两个数据间的分隔符,如下面输入不合法:
; Z+ l0 ]6 r4 Z" O3,4
* U8 N/ T, t- X" u0 g, o输入数据时,在两个数据之间以一个或多个空格间隔,也可用回车键,跳格键tab。: E! k8 y" d# L& ~- |# b7 F" _
②scanf("%d,%d",&a,&b);5 }; ]4 D( W6 T; ]
C规定:如果在“格式控制”字符串中除了格式说明以外还有其它字符,则在输入数据时应输入与这些字符相同的字符。下面输入是合法的:
3 M+ P+ W) M5 E3,4
7 X, M* ?9 J6 N* A0 L5 [+ o此时不用逗号而用空格或其它字符是不对的。
) S5 ]7 ^: B4 M4 t& ^3 4 3:4 6 {# a/ {; ?2 I" g* s% `5 a, o |
又如:1 O. g9 L& F9 ]' e. m" h4 Y6 D
scanf("a=%d,b=%d",&a,&b);
n3 n6 }# q f& Z3 `输入应如以下形式:
- M- ]& d' ^* q+ I' t' Ua=3,b=4
0 }+ r% W |. H6 W2 X" l0 _9.输入字符的格式与要求不一致。$ \4 ]6 R3 ]2 _: x3 ]3 C7 g
在用“%c”格式输入字符时,“空格字符”和“转义字符”都作为有效字符输入。
8 Y/ i8 ]6 _; B P2 C( R) Bscanf("%c%c%c",&c1,&c2,&c3);6 H& _2 y; Y2 i$ I7 P: f! N
如输入a b c ! ]2 |9 j7 g) P6 ^
字符“a”送给c1,字符“ ”送给c2,字符“b”送给c3,因为%c只要求读入一个字符,后面不需要用空格作为两个字符的间隔。
* A; _- Y6 c R" r. g7 e$ c2 u& r10.输入输出的数据类型与所用格式说明符不一致。
/ y. Q: E9 }7 u0 [# G6 x% c+ [% e X0 s+ d例如,a已定义为整型,b定义为实型. C' U4 q. Z; Q* b0 E
a=3;b=4.5;$ Y, g' y5 w Z2 V& P/ @
printf("%f%d\n",a,b);
& [( d7 u9 z( d& W编译时不给出出错信息,但运行结果将与原意不符。这种错误尤其需要注意。4 V g$ k' T+ f i0 n& u
11.输入数据时,企图规定精度。
4 d$ T* O$ Z9 f! `% y0 ?scanf("%7.2f",&a);
2 g6 x; k" j1 Z3 n这样做是不合法的,输入数据时不能规定精度。9 d1 Y) U, ~% i! ^0 l
12.switch语句中漏写break语句。
3 P' R/ Y" l' n例如:根据考试成绩的等级打印出百分制数段。
' }- u3 @: B! o! y# Z" c' lswitch(grade)& ^/ q. T1 g1 ?
{ case 'A':printf("85~100\n");
4 W% B# q% S: I, qcase 'B':printf("70~84\n");
; @/ }1 U- v4 tcase 'C':printf("60~69\n");1 n2 ^& S9 k- I c5 _+ ]
case 'D':printf("<60\n");8 G; @8 @* a: Z" F+ T6 E1 g
default:printf("error\n");
0 m% U, D; n$ O/ d; r$ L* \由于漏写了break语句,case只起标号的作用,而不起判断作用。因此,当grade值为A时,printf函数在执行完第一个语句后接着执行第二、三、四、五个printf函数语句。正确写法应在每个分支后再加上“break;”。例如5 F; h ]. [: E
case 'A':printf("85~100\n");break;, G. D! ~% M# j
13.忽视了while和do-while语句在细节上的区别。% |; g. W: | L# U3 D9 }9 h+ A) j& f
(1)main()
7 z q# h2 [) ]7 T7 `{int a=0,I;
$ K/ L: m; F7 ]1 ^5 Fscanf("%d",&I);4 |' L4 s# F' k% R) g
while(I<=10)' V+ Q7 H8 M1 P4 [8 n4 W
{a=a+I;* ]. y: d! m0 ^$ W( B
I++;; T! F# A0 h3 n" Z$ j5 g8 ^* Y) U
}
' ]' z1 H, v+ v) @! aprintf("%d",a);
: g/ R# ]# Z% e- @% N}# z& `7 `, s! Z( `6 F$ J2 p
(2)main()5 L+ n u Q0 i* y
{int a=0,I;
0 b: ^' b3 T" s- _' `; V9 l# iscanf("%d",&I);
8 k3 w2 o+ e7 r, U; Kdo2 @, a6 P5 D- Q; b
{a=a+I;- `/ Z0 e! Z* p1 R
I++;
& r' B$ E6 q+ D5 d: e) ]4 g d}while(I<=10);) _2 w& B2 h* H* q+ Q" N& M
printf("%d",a);
8 i4 R& N% T- H1 Z6 I}
8 d) K6 v( a. M2 _可以看到,当输入I的值小于或等于10时,二者得到的结果相同。而当I>10时,二者结果就不同了。因为while循环是先判断后执行,而do-while循环是先执行后判断。对于大于10的数while循环一次也不执行循环体,而do-while语句则要执行一次循环体。
; k9 Y" p" t2 h2 E0 e: N14.定义数组时误用变量。
l! \, w3 y7 W2 _* Mint n;/ V' o/ ~$ w: r$ P0 t4 J
scanf("%d",&n);
& X f/ {3 y, v z' q( Y- Pint a[n];; @, v( y! @7 [* J! a, B
数组名后用方括号括起来的是常量表达式,可以包括常量和符号常量。即C不允许对数组的大小作动态定义。* B4 `( F& X, E ~1 y2 ]
15.在定义数组时,将定义的“元素个数”误认为是可使的最大下标值。- G2 n. ^; ?' A" k4 y4 B
main()
q0 a) G: S8 J: F* R$ p+ I{static int a[10]={1,2,3,4,5,6,7,8,9,10};
% I1 D! i: g" L$ {9 m8 dprintf("%d",a[10]);" k O; u9 m: L C& T7 J
}. ?$ o6 M, z7 @1 Y G
C语言规定:定义时用a[10],表示a数组有10个元素。其下标值由0开始,所以数组元素a[10]是不存在的。
! A$ |+ B \: l16.初始化数组时,未使用静态存储。
' d3 {: _7 d/ x$ C1 {) X" j! uint a[3]={0,1,2};5 c+ h, E4 L" q. I' n
这样初始化数组是不对的。C语言规定只有静态存储(static)数组和外部存储(exterm)数组才能初始化。应改为:
9 p3 C( f. z+ V v- Z1 u# estatic int a[3]={0,1,2};( q4 [1 ?! D) V# `3 |
17.在不应加地址运算符&的位置加了地址运算符。
7 Q9 [/ ]- |: }' v! [9 p. Xscanf("%s",&str);' F7 F; j6 y. A3 D
C语言编译系统对数组名的处理是:数组名代表该数组的起始地址,且scanf函数中的输入项是字符数组名,不必要再加地址符&。应改为:
5 r4 q! F f+ o4 \) i+ _6 [scanf("%s",str);
1 y8 |3 a0 I) ?: P Q @( s# A1 ?18.同时定义了形参和函数中的局部变量。
0 b" ]2 d2 P- qint max(x,y)
% V- |4 K5 L3 k2 e$ v# V9 hint x,y,z;: x# S& c/ I1 q. X/ s
{z=x>y?x:y;
4 y9 m# x" }. Lreturn(z);* V3 ?! c7 A9 v5 n
}
& H- u& a: e4 T: |3 y }形参应该在函数体外定义,而局部变量应该在函数体内定义。应改为:4 e* A& X* O: _; w5 I1 t. Y/ b& v
int max(x,y)& w% d2 E- Y s7 {6 d; [( O% t w
int x,y;
3 ^: P) S$ e% I/ v- e" j{int z;+ T7 S0 e. w N1 R8 j( `7 q* {
z=x>y?x:y;
3 N( `! W+ M( {+ d: W: [( @return(z);+ E8 K3 \! ~& z5 X3 z( D
}</P>
; O7 h7 g/ S2 Z& t. @1 ? K7 p( w( c< >以上错误中可能有些不符合新版的C语言,比如数组的初始化,新版中就可以是不是静态变量。由于是转贴就未加修改,以保持文章的原貌,请各位自加区别。<b>版权属于原创作者!!!</b></P> |
zan
|