- UID
- 2
- 斋米
-
- 斋豆
-
- 回帖
- 0
- 积分
- 1897
- 在线时间
- 小时
- 注册时间
- 2009-12-26
- 最后登录
- 1970-1-1
|
C语言的最大特点是:功能强、使用方便灵活。C编译的程序对语法检查并不象其它高级语言那么严格,这就给编程人员留下“灵活的余地”,但还是由于这个灵活给程序的调试带来了许多不便,尤其对初学C语言的人来说,经常会出一些连自己都不知道错在哪里的错误。看着有错的程序,不知该如何改起,本人通过对C的学习,积累了一些C编程时常犯的错误,写给各位学员以供参考。 D; h9 c' j3 M/ [& P
8 z. B4 _+ C! S; x1.书写标识符时,忽略了大小写字母的区别。
) P6 b1 m7 J- u+ ]! D+ I2 z- b- Y' X8 wmain()! ~$ Z, L1 v( _( z" P: H' g/ {2 Z
{
+ {- a. p3 [( {int a=5;9 R! O5 Y" ~. h& @2 M
printf("%d",A);
! w" D, p* `9 l2 P}6 W2 j$ f( Z4 d; \$ Y2 _+ K
编译程序把a和A认为是两个不同的变量名,而显示出错信息。C认为大写字母和小写字母是两个不同的字符。习惯上,符号常量名用大写,变量名用小写表示,以增加可读性。
) b( A/ r9 [5 ^2.忽略了变量的类型,进行了不合法的运算。
0 w! z+ J* @1 c& O, k( I) H- Qmain()
6 q: t5 [5 a+ S# d8 y1 |{; Z6 h; Q% W8 b( K! n
float a,b;6 ]1 c) A! Q- F4 s7 c" R
printf("%d",a%b);8 t/ T5 _( D" R5 r& n
}( H) d; C( { |' Z2 n* U
%是求余运算,得到a/b的整余数。整型变量a和b可以进行求余运算,而实型变量则不允许进行“求余”运算。% l% Y, [4 o% C, A" q O# ^& h
3.将字符常量与字符串常量混淆。
! V( ]2 i3 N7 W' W8 D& \$ ichar c;
% l7 n) U8 `' \8 ?! A" ec="a";
: ]) s, n1 U! ] Q在这里就混淆了字符常量与字符串常量,字符常量是由一对单引号括起来的单个字符,字符串常量是一对双引号括起来的字符序列。C规定以“\”作字符串结束标志,它是由系统自动加上的,所以字符串“a”实际上包含两个字符:‘a'和‘\',而把它赋给一个字符变量是不行的。
2 v0 r# v: d0 H; ^/ I' Q k4.忽略了“=”与“==”的区别。
# P. ^2 J& }5 f5 V0 R2 K1 _在许多高级语言中,用“=”符号作为关系运算符“等于”。如在BASIC程序中可以写2 w% _; }8 k$ g6 m' Z
if (a=3) then …
1 W \% h8 S _: f但C语言中,“=”是赋值运算符,“==”是关系运算符。如:
* u) I% `$ M) Y8 Iif (a==3) a=b;( \% e# o4 G0 ]
前者是进行比较,a是否和3相等,后者表示如果a和3相等,把b值赋给a。由于习惯问题,初学者往往会犯这样的错误。* y+ T4 U, b) \ ~& Q n% H
5.忘记加分号。
& o) f6 b8 y) I分号是C语句中不可缺少的一部分,语句末尾必须有分号。
& B) \, ^3 _/ a8 u$ K' ha=1
" ^( r/ t2 I$ S7 ?$ L1 ]b=29 m+ e8 r" f. j% q$ t7 T% ^
编译时,编译程序在“a=1”后面没发现分号,就把下一行“b=2”也作为上一行语句的一部分,这就会出现语法错误。改错时,有时在被指出有错的一行中未发现错误,就需要看一下上一行是否漏掉了分号。! a0 |+ y' W( e F! m
{ z=x+y;7 z& L/ A K% m& h; R
t=z/100;2 L' ^- R) v( ~9 Y* Q" A
printf("%f",t);
, ]7 N# s& v; `: ?* @' a: H}
1 U$ W( z( N% ~2 G8 ]对于复合语句来说,最后一个语句中最后的分号不能忽略不写(这是和PASCAL不同的)。
' G3 j! K) {" g# @) S; w6.多加分号。2 l$ @! R; E; {4 b' O H3 `
对于一个复合语句,如:
: L+ I, v7 L! I4 i7 o{ z=x+y;5 x' |( H$ j8 ^; b. a! M
t=z/100;# x! n( y. S$ N ]6 m! ] P
printf("%f",t);
/ j) m% f0 r1 N};/ C- f2 ~- l$ R$ X2 r" v) h
复合语句的花括号后不应再加分号,否则将会画蛇添足。8 v6 U6 n9 K8 V/ {3 |' z" l1 u' R
又如:
* b5 @6 r2 U1 ^if (a%3==0);
' Q: A [* S7 I2 E `I++;. Y+ C) z p3 v. I
本是如果3整除a,则I加1。但由于if (a%3==0)后多加了分号,则if语句到此结束,程序将执行I++语句,不论3是否整除a,I都将自动加1。, y8 H6 ^2 `! W
再如:
0 C _2 e6 \/ C% x/ Efor (I=0;I<5;I++);
9 m0 p f. P' M{scanf("%d",&x);4 E s( {" c/ y. _! K) j
printf("%d",x);}9 i. f$ ^' Y' d" y4 x
本意是先后输入5个数,每输入一个数后再将它输出。由于for()后多加了一个分号,使循环体变为空语句,此时只能输入一个数并输出它。* S2 c- f3 n! P( P
7.输入变量时忘记加地址运算符“&”。
6 B3 T2 k" C1 m6 g! J! q' ^. Vint a,b;
! E" _8 O! r2 O/ ~) j5 K, Xscanf("%d%d",a,b);- b, t3 z; `. \& K- ]/ @; M
这是不合法的。Scanf函数的作用是:按照a、b在内存的地址将a、b的值存进去。“&a”指a在内存中的地址。$ j+ i; R; ?; \; T, @" F0 V* H- h
8.输入数据的方式与要求不符。①scanf("%d%d",&a,&b);
& n1 d6 }9 [7 |, c+ D, M输入时,不能用逗号作两个数据间的分隔符,如下面输入不合法:
2 c# E# r: H, ^5 Y" N6 L3,4 ( }9 V; N% m, o( d9 v' |; c6 y v
输入数据时,在两个数据之间以一个或多个空格间隔,也可用回车键,跳格键tab。
2 g6 A8 S) E( v1 ?②scanf("%d,%d",&a,&b);# ^5 j! ?7 d8 t' H0 O
C规定:如果在“格式控制”字符串中除了格式说明以外还有其它字符,则在输入数据时应输入与这些字符相同的字符。下面输入是合法的:
- o, b& f$ v9 j6 i' {: N# T3,4
! {5 E) v- }; R q) g此时不用逗号而用空格或其它字符是不对的。2 L, p) r) f+ Z; x" W O8 p
3 4 3:4 9 G1 N5 t( J h: ?3 E1 B/ X o
又如:% ?6 w1 Q- n j: V( _* l
scanf("a=%d,b=%d",&a,&b);0 I3 D8 ~( x0 e7 ^" s* b+ Y
输入应如以下形式:* r; q" p5 [$ p2 X4 Z4 c
a=3,b=4
/ ]# z8 p: }+ d4 I" }9.输入字符的格式与要求不一致。/ N( l5 j3 i# {9 J7 u
在用“%c”格式输入字符时,“空格字符”和“转义字符”都作为有效字符输入。( J0 T, v( f, T0 W
scanf("%c%c%c",&c1,&c2,&c3);
* u) B+ b" p; I: C如输入a b c 7 x/ G% i# n0 K* z
字符“a”送给c1,字符“ ”送给c2,字符“b”送给c3,因为%c只要求读入一个字符,后面不需要用空格作为两个字符的间隔。* A3 {: _" Q4 ~
10.输入输出的数据类型与所用格式说明符不一致。! M8 S) g; s4 \% C$ g. ?! ]" R
例如,a已定义为整型,b定义为实型
1 P% M; L1 B3 _2 L% Ea=3;b=4.5;
! S$ N( }! [% Pprintf("%f%d\n",a,b);
3 ~* G/ I; C( u. j9 U2 k% C" }3 n1 L编译时不给出出错信息,但运行结果将与原意不符。这种错误尤其需要注意。
) W' i2 U# E' c4 X11.输入数据时,企图规定精度。
: c7 U$ N* G5 g( vscanf("%7.2f",&a);
c$ k8 [: v( ~这样做是不合法的,输入数据时不能规定精度。
+ q9 P( a7 s9 {6 f }- F! ]& e% n12.switch语句中漏写break语句。
: h5 X" x8 g- x" A( Z0 w9 c例如:根据考试成绩的等级打印出百分制数段。' ]9 f: m* i+ u2 V
switch(grade)% c, l1 s, }0 f1 @# y- q6 w
{ case 'A':printf("85~100\n");
?+ b, H" q3 a* \3 n3 a" scase 'B':printf("70~84\n");$ U, M( O( u" d$ a$ [( F
case 'C':printf("60~69\n");3 t8 T# k5 n' e2 b* a ?' \
case 'D':printf("<60\n");
6 ?0 a+ T, \ |* [5 vdefault:printf("error\n");4 m: J2 M/ W' U* @
由于漏写了break语句,case只起标号的作用,而不起判断作用。因此,当grade值为A时,printf函数在执行完第一个语句后接着执行第二、三、四、五个printf函数语句。正确写法应在每个分支后再加上“break;”。例如* f0 {, e2 T: c; x. s: z3 s
case 'A':printf("85~100\n");break;
* {; M1 ^0 n. Y: g# i9 g13.忽视了while和do-while语句在细节上的区别。8 x' J- |" l3 d
(1)main()5 B7 n; X: a" {2 X% i, b
{int a=0,I;* \8 Q( R/ d+ p0 i6 g$ {( A
scanf("%d",&I);6 h; Y; P& ?3 \( M
while(I<=10)
- [- J( w- }1 d{a=a+I;
' K8 Q8 H' D- O5 F, wI++;
( N' J/ @ J3 y+ |. @! H1 d/ ?}( p c+ e, a7 {; a$ w0 D
printf("%d",a);1 t9 l# a- r" J# y
}
3 n* B c G1 v- T- C+ F(2)main()
8 D. \! m# U- D{int a=0,I; m& b) v' o2 I' J
scanf("%d",&I);9 d* l( Q+ ^) U3 J/ [/ k0 u
do
. `) h8 y! w7 v9 J8 b. S @{a=a+I;
% f7 B, ?$ f4 A7 KI++;
6 I; H4 w3 X$ ]& r% a* B}while(I<=10);* i$ K) ?5 s" Z# ^/ c! F( v
printf("%d",a);
/ Y) Y# s( N: U+ Y3 u! j* _& L( o}
! m7 K0 L# D! A" G% T6 x* k可以看到,当输入I的值小于或等于10时,二者得到的结果相同。而当I>10时,二者结果就不同了。因为while循环是先判断后执行,而do-while循环是先执行后判断。对于大于10的数while循环一次也不执行循环体,而do-while语句则要执行一次循环体。
+ \- ]6 M) r7 X! E7 Q8 L4 Y14.定义数组时误用变量。
# t V5 G: u/ ?* Lint n;
- J' W+ r+ q/ e& g# Qscanf("%d",&n);; E; l- |$ `0 [0 |
int a[n];! g5 Q( _1 n k: i
数组名后用方括号括起来的是常量表达式,可以包括常量和符号常量。即C不允许对数组的大小作动态定义。
+ B7 x! e* i& T3 ]15.在定义数组时,将定义的“元素个数”误认为是可使的最大下标值。% w/ ^2 {. w! S1 L
main()
% K0 J8 v I" l5 ?7 _; M! ^" D1 [8 o{static int a[10]={1,2,3,4,5,6,7,8,9,10};
4 R, z) P2 J. J! t8 q; i$ ?printf("%d",a[10]);4 B4 {) I v- Y7 z
}) w7 V) L+ |2 r2 B
C语言规定:定义时用a[10],表示a数组有10个元素。其下标值由0开始,所以数组元素a[10]是不存在的。
& H7 f1 ?9 y3 v16.初始化数组时,未使用静态存储。
+ N# R, ^) e' [7 X& o+ F! e6 tint a[3]={0,1,2};
/ `. d7 ?( k; T" `' D这样初始化数组是不对的。C语言规定只有静态存储(static)数组和外部存储(exterm)数组才能初始化。应改为:5 N, a& m# m: t
static int a[3]={0,1,2};( d4 q! e2 K T) }- K2 A
17.在不应加地址运算符&的位置加了地址运算符。( [: E' K8 C3 ?4 a
scanf("%s",&str);
) L; o7 c5 u( Y: L! UC语言编译系统对数组名的处理是:数组名代表该数组的起始地址,且scanf函数中的输入项是字符数组名,不必要再加地址符&。应改为:" b& l; }/ J& s. a; p) W, f' Y
scanf("%s",str);7 B) A$ r* `- [4 [
18.同时定义了形参和函数中的局部变量。
/ r# K2 g7 N6 F# zint max(x,y)# ~) O7 M+ J0 z' {! L
int x,y,z;+ g, z1 X) E0 j- ?& t: n
{z=x>y?x:y;
7 ]/ v) K* f1 |5 g( _; q i8 Breturn(z);
4 Z! U3 T2 E( @" ~3 `! [}- u8 l1 f+ ]9 A$ M0 Y5 s! x2 @. ^
形参应该在函数体外定义,而局部变量应该在函数体内定义。应改为:
7 X' i2 {5 w$ Y& t% K" I7 n* Aint max(x,y)
) f, i% d# N: i7 Vint x,y;5 b0 a$ X( j# s! _# ?# O
{int z;
* j! E8 s7 W* Kz=x>y?x:y;
/ i8 w+ D$ ?$ Lreturn(z);
8 ^, N4 F7 K+ l- Z& P0 q/ q} |
|