最近,老有的网友提问如何学习C语言,因此从网上搜索了一些文章,希望对大家有所帮助 ! e* a3 e' X7 I! C" J7 R6 }

, C4 b( Q& j6 V   谈及C语言,我想凡是学过它的朋友都有这样一种感觉,那就是让我欢喜让我忧。欢喜的是,C语言功能非常强大、应用广泛,一旦掌握了后,你就可以理直气壮地对他人说我是电脑高手!,而且以后若是再自学其他语言就显得轻而易举了。忧虑的是,C语言犹如少林武功一般博大精深,太难学了。其实就笔者认为C语言并非是“difficult(困难)的,只要你能理清思路,掌握它的精髓,那么自学C语言是一件非常容易且又其乐无穷的事。今天本人就与大家一起谈谈如何学习C语言或者说学习C语言应从哪几方面着手。
( ?, v$ D% \. ]& S. V; t   J7 ^$ h: v& i! A
  了解一些基本知识
* o4 ]- E; x9 A6 K
! Z& v- h  t$ W5 g) D' Z  L   一.C语言的背景 9 ~: t% w) V' V# }  x% g9 k7 }

4 g, C$ V; U: I; R% d   就个人感触,无论学习哪门语言首先应该了解一下自己所学语言的背景,也可以说它的发展史。
2 f1 F4 S2 E, p0 O7 Y9 W9 v( e5 W ! f' k7 J; k5 X
  C语言属于高级程序语言的一种,它的前身是“ALGOL”。其创始人是布朗·W·卡尼汉和丹尼斯·M·利奇。C语言问世时是带有很大的局限性,因为它只能用于UNIX系统上。然而随着科学技术的进步,计算机工业的发展,C语言逐渐脱离UNIX1987年美国标准化协会制定了C语言的国际标准,简称“ANSI C”,从此以后它便成为一种广泛使用的程序语言。C语言的优点很多,主要的有如下四点:
8 q, f) ?* t& z* L" p+ X" P, u ( U2 A" H( O2 @
  1.兼备高级语言与低级语言的优点,属于一种中间语言。 / ]4 A# a: P8 u8 a$ v& O9 W

6 a2 O! H) V* a) O0 u   2.它是一种结构化程序设计语言,非常适合结构化程序设计。 . X% t2 A/ M5 a( \( p! h

/ |& i8 x. G3 k4 }' L! U  N   3.有较丰富的数据类型、运算符以及函数供以选用。
6 c7 {. a8 `5 h
1 i, f7 y/ c- h   4.直接与内存打交道,使修改、编辑其他程序与文档变得轻松,简单。
. J7 M7 Z0 J/ @2 A  u3 A9 T" N4 }0 }   u$ i, ]( I, B' k) z  Y
  二.二大语系二种不同的学习方法
2 e3 K+ Z+ ?# I. @& B" o: h: v) J! { $ U# ?2 a: A# s# G
  笔者学习过很多程序语言,例如:CC++(C语言的扩展),QBASICVBBASIC的可视化),JAVASCRIPTJSCRIPT VBSCRIPTJAVAASPFOXPROPERL等等,就本人实践所得,其实高级程序语言分为两大语系。一路是以C为主的程序语言,例如:JAVASCRIPTJAVA等,这类语言在函数的调用,程序语句的书写,循环的控制都极为相似。另一路是以BASIC为首的程序语言,例如:FOXPROVBSCRIPT等,此类语言同样具有相似的函数调用,程序语句书写以及循环控制,但与C语系是不同的。因此若是您以前是从QBASIC起家的,那么在学习C语言前最好是先洗洗脑,千万不要把学习BASIC的方法以及思路用在C身上。 # E* Y0 c3 ^0 }- n2 @" u, F( M$ D
+ V  e; @; w+ }: @- I
  讲到这里,我想大家对C语言一定有了感性认识吧!下面让我们再升华一下,全方位亲密接触它。学习C语言必须从以下四点入手,也就是说,只要你能掌握这四点的内容,那么基本上就大功告成了。 3 w$ Q, r. t1 H# s) Z2 k
4 w4 |1 ]2 c1 {2 K4 N
* P+ N4 ]: X, _" G& U, \! V9 |
7 [0 y0 l+ R+ {7 u! S, G
亲密接触C语言
( ^" @& L9 N" U, V6 B% {
% v! c  X; h4 F8 _. P   一.输入输出
8 \. ?8 @9 n& V; l; c
% k9 k* ^  C# M/ I5 M/ J   C语言的输入输出是非常严格的,或许在其他程序语言中我们可以不关心这个问题,但在C语言中,我们必须要彻底了解它。由于篇幅有限,因此笔者不能详谈,有兴趣的朋友可以参考由著名程序语言教授谭浩强先生主编,由清华大学出版社出版的《C程序设计第二版》。不过这里笔者还是有几点要谈一下。
8 d# U0 ~/ s5 ^, f 1 I# T% c7 {' I# H. C
  1.二维浮点数数组的输入
( V/ H- i% i. ~# M- S
6 l! y; b2 W8 L5 b   二维浮点数数组的输入(即:通过键盘给二维浮点数数组赋值)在很多专业书中都没有详细讲过这个问题。在给二维浮点数数组赋值时一定要先声明一个变量,接着把数值赋予这个变量,最后把变量数值赋予二维浮点数数组赋值。实例如下: 2 w& A1 }7 Z! {. p% l4 g+ k
9 G: L: q7 H5 v3 L- v
# include "stdio.h"   m& _1 `. k% n" I, r
main() ) `# u0 C4 C7 R* T- R- _
{ ! p6 U, m, @! ]8 S- q
 float a[2][3],x ; " S$ n$ h- X7 V  Y- l
 int i,j; " _" G+ K+ b& k4 T( H0 V3 {8 @% a. m( ]
 for(i=0;i<2;i++) 7 G8 T6 s, M* O
  for(j=0;j<3;j++) 0 h3 s# E4 _7 g" F# V( r% R  r/ M
   {scanf("%f",&x); ! A7 G5 {- K8 @/ n
    a[j]=x;} 3 n+ X! W* @) B+ C' ]- R4 T
   } , x$ n* O1 W' c$ y
不能写成:
  C! K" H" @: ~  G, v
' [! u' z( B# O' k. c5 b3 s+ l # include "stdio.h" - U& V; W7 N% K- \) [1 K& _
main() 4 V( m) u4 p) D' b/ G
{ 3 g( a9 y9 K6 v, z
 float a[2][3] ; 5 X- s1 z8 D' k* k
 int i,j; ; K, x" A: ?0 t2 k2 h
 for(i=0;i<2;i++) 3 K1 N! l; \9 Q( X- m4 y3 i( [0 W
  for(j=0;j<3;j++) 2 q( z) T; ]7 m0 P! r3 [* v* a
   scanf("%f",&a[j]);
2 W$ V1 b. l0 `* U- ~& M( N } / g8 a- E+ i3 T2 V+ k) v) U! I; ~
2 K1 I) \2 |8 e3 h/ P) d
  同样道理,在结构性浮点数组变量中也一定要按照这种格式输入。实例如下:
) ^7 v3 o6 n) f( B ' T$ y" d. a4 N5 k& M) G
# include "stdio.h"
$ j0 U+ i4 d$ ^" O: }+ Q  struct student 6 R+ o& j5 S% t, n% _4 Q" Q
 {float b[3]; / m6 r: Q, t& v2 N6 F3 i  g/ O7 g
  int x;
: v# }/ [' T- i( S7 {* Q2 L  }a[2]; ; H  ]" T3 F" ]0 `; t  Y
 main()
% I* b7 G! Z4 _5 N$ g' o  {
# l. D( f) U3 }   float x ;
' _) C( ~- Z2 _& b   int i,j; : q& v/ F0 m' C
  for(i=0;i<2;i++) # [  g* ~$ ?4 @' }( h
   for(j=0;j<3;j++)
& D: X( X& ^5 j5 b+ k- P5 N6 l     {scanf("%f",&x); : R- e( o9 I" l: j& P
     a.b[j]=x;} $ Q& o3 i$ V4 Q% z
    } * [* ~+ [8 L4 H" R' M
" B" a- Q; K- Z6 G/ s9 w% ]3 c
  2.注意输出格式中后的字符
! ]1 v' t* E/ _4 }, U+ x2 p- Q, ^) a
" x( u. A' c" l  V! B. `8 ~   C语言的输出说复杂不复杂,因为常用的都很简单。可说不复杂也未必,记得曾在一次等级考前辅导我们C语言的教授讲道:如果C语言要考得很难的话,根本不用考什么指针,只要专考输出格式,我想百分之九十九的学生都不及格。当时我们无不认同。从这则事例中可以看出C语言的输出格式之复杂程度。因此大家在学习它时千万要学会辨别输出格式中后的字符,每个字符都有其意义,也都有其作用。
1 d3 E6 J6 j4 ^7 X7 c' x8 D
6 x2 L5 ~& Q7 D% b   二.优先级 8 Y4 {0 y5 V5 `
; C0 h+ v7 y2 i2 A6 H& q
  说道优先级,有很多朋友都不是很了解或说很模糊。为此笔者想先通过一个例子让各位有个概念。什么叫优先级?比方说,我们在公交车终点站排座队时总会遇到70岁以上的老人不需要排队就能上车的情景,这就是优先级的涵义。C程序在运行时也象排队坐车一样,首先照顾那些优先级高的运算符,若是优先级相同,那么就象遇到两位(或两位以上)70岁以上的老人那样,让他们依次上车。但是C语言中的优先级的运算并不是千篇一律的,只能说是在大多数情况下,有些运算符的优先级有其自己的特点,因此这点大家要注意。例如条件表达式:条件?结果1:结果2,这种表达式很多朋友都知道,它的作用与IF…ELSE…条件判断语句很雷同,它运算时的优先级就不是按照C语言的规则来完成的。所以说对于优先级各位编程爱好者一定灵活掌握,不要死记硬背。
) }4 j% s2 z' y# o. R8 j 5 }6 \" I3 l4 c: s3 b, J- U
  三.指针
, m3 m' M6 |/ B: _. M5 l3 m ! q. ]7 N5 c, I8 n8 k8 Y8 ]$ t$ M' O
  就个人认为,C语言中的指针是最有特色的,当然也是最难学的。指针说穿了,其实是变量的一种表现形式,只不过这种变量记载的不是数值而是地址。就象一个人可以用姓名来表示自己,也可以用×××号码来表示自己一样。笔者涉足编程已经有三年多了,在这期间曾经收到过很多网友的电子邮件询问学习指针的方法。就本人感触,学习指针最好是先学些计算机硬件工作的原理,例如:直接寻址,间接寻址等,只有了解了这些内容以后,你再学指针就比较容易理会,毕竟C语言是一门介于机器语言与高级语言中间的语言,没有一些硬件工作知识是很难领悟它的真谛的。然而事事并非绝对,如果你没有这些知识也不要紧,只要清楚知道以下笔者总结的二点再加上多练习便可:
$ B- C, Q+ h' Q' F6 l) Z6 _ 6 G3 I; ~# X8 n; D5 J: d- v
  1.指针是地址变量:它的值有两种:其一是地址,其二是内容。不同的表达方式可以取不同的值,这有点象一个家庭地址在不同的场合标识的人物也不同。例如:父母亲在他们的单位所登记的家庭地址就代表他们自己,而你在学校中登记的同样的家庭地址就代表你自己。 ' U( z0 Y2 r3 S6 ?; [
% X- w6 x4 T: H; f4 m
  2.指针是可以运算的,它的运算法则与变量是一致的。 : J4 n& J8 c0 m% ?  k) t
: M2 Q0 Y8 ?& x$ i2 H3 y2 ?5 O
  另外,在编写一个程序时,除非万不得已,一般不要使用指针变量。因为指针是比较复杂的,用不好就当机。所以笔者建议各位对于指针只要能看懂就行,当然如果你是准备参加考试的就另当别论了。 7 I* |, U/ i# k! |9 _; q# c5 z7 t1 `

% s) C  b6 i! l% w5 k, J
. A3 @6 K3 R& b: ?+ h* L 四.函数
* W  O( v( @% p# ~/ N- g
, ~* Z7 t* }# m8 R5 F6 }* z9 k, s   虽说很多程序语言都有函数这一内容,但笔者觉得C语言的函数是最有魅力的。如果你能完全掌握C语言的函数,那么学习C++就不成问题了(C++是一门建立在C语言上,但又不同于C语言的高级程序语言,它增添了很多函数。)。学习函数的方法是比较简单的,只有两个字牢记,即:牢记函数的功能,牢记函数的用途以及如何输入输出。有些朋友认为,程序语言中的函数没有多大用处,其实这并不正确,函数从本质上讲是一段通用程序,用它可以帮助我们节约很多编程的时间,一个聪明的编程者在编写程序前往往总是先找自己所编写的程序中有多少是可以用函数来代替的。笔者曾经作过一个比较字符串的实验,用C语言中的strcmp()函数只要一句话,而自己编写的话30句话都摆不平,可想而知函数是多么实用呀! ; |( w3 f( f. D9 g
- z( C" R8 k# B' Q) K
  写到这里笔者该告一段落了,下面送一个本人自己用C 语言编写的注册表比较程序给诸位。此段程序的注释请看“/*…*/”后的文字,程序运行时(在DOS模式下)输入的方式如下:compare xx1.reg xxx2.reg xxx3.txt,注意字段与字段之间是有空格的。(compare是程序名)
: x3 F% {+ o% ]+ I# ?) \ 0 {$ n2 r9 O1 a8 s8 y3 k2 ]
  程序代码:
. ?  s, Y4 d1 L  E8 ?3 x" R4 B' @
/ E, K: n  X- i2 A0 C3 o' Z6 v& g  # include "stdio.h" /*定义头文件或说包含文件*/
& {' W1 T6 l: H! _6 C0 ]" B2 u
5 j( }7 Y4 |) z7 W$ W  main(argc,argv) /*定义带参数的主函数*/ ) \. o8 d1 M! @( b' N/ `0 g7 G5 t

! M- Q, p* u- `, p& w   int argc; /*定义参数类型*/ ( y2 f* ?, ^, j
  char *argv[]; /*定义第二参数类型*/
! k- k/ J$ F& F3 m   { FILE *fp1,*fp2,*fp3; /*定义文件指针*/ % n- v7 r# A6 u$ `
   char a,b; /*定义字符变量*/
! i/ |) k: o+ k; ~( {    if((fp1=fopen(argv[1],"r"))==NULL)
5 Q2 f' q4 Z" t1 D" A# d. Y: C! x     /*打开第一的注册表备份文件,如果不存在则跳出程序并显示“The file don`t open!”*/
+ ~/ |1 ^7 Q2 E+ o2 [5 Y     { printf("The file don`t open!");
( E7 l0 l' k4 x( B% A' f      exit(0); }
' S6 E; g' [" z/ Y3 S7 U    if((fp2=fopen(argv[2],"r"))==NULL) /*打开第二的注册表备份文件,如果不存在则跳出程序并显示    “The file don`t open!”*/
! _0 ^+ s" D; B0 ~     { printf("The file don`t open!"); 6 D; W" B) n% a
     exit(0);} 6 [- K& V& {+ Z
   if((fp3=fopen(argv[3],"w"))==NULL) /*建立新的文本文件,用于存放比较结果。*/ % t+ }  @7 |+ B% Z8 G3 ~
    {printf("The file don`t open!");
9 M3 S+ C! S5 ]/ N+ w( _( G3 z      exit(0);} , _0 _! K! T' [" X+ w$ ^
   rewind(fp1); /*规定文件指针fp1指向第一个注册表文件头部*/
# y' Z4 y! _( u( s2 A4 m" Q9 J! f. l% E    rewind(fp2); /*规定文件指针fp2指向第二个注册表文件头部*/
0 [' d4 M* Z- ~    while(!feof(fp1)||!feof(fp2)) /*开始比较*/
( L0 T& Y$ K* F' G; K+ }& h) C     { a=fgetc(fp1); /*读取第一个注册表文件内容并赋予给字符变量a*/ + i4 l7 }, n$ F0 T2 q' j% Y* R
     b=fgetc(fp2); /*读取第二个注册表文件内容并赋予给字符变量b*/
$ D0 H1 N. z- d      if(a!=b) fputc(b,fp3);
+ J+ ?7 h5 h! t& r- Q/ g       /*字符变量ab不相同的话,那么把不同之处写入新建的文本文件中*/
, D) R; |4 b9 s$ S' Z; V8 m       if(feof(fp1)) fputc(b,fp3); ! ?# y. t- V* c! Y
        /*如果第一个注册表文件已经读完,第二个文件还有未读取部分,那么把第二个文件的剩余部分全部写入新建文件中*/
% a. [. K5 A: |" W/ B" u       if(feof(fp2)) fputc(a,fp3);} /*如果第二个注册表文件已经读完,第一个文件还有未读取部分,那么把第一个文件的剩余部分全部写入新建文件中*/ 3 g% j' c+ t. O% A
      fclose(fp1); /*关闭第一个注册表文件*/ ! ?0 s) }4 @; C: H! p+ G
      fclose(fp2); /*关闭第二个注册表文件*/
/ [# q. G+ I( l( B3 e3 V      fclose(fp3); /*关闭新建文件*/
* ?$ X* T( X1 E }
4 }  P6 X% e/ m9 u$ b+ O) c 6 W1 h+ \0 U: C
  对于高深莫测的C语言来说,寥寥3千字并不能说清楚的什么问题。但只要您看了此文后,我想对于您学习此语言一定有很大的帮助,同时也能了知晓如何用最短的时间学会C语言以及掌握C语言的精髓所在。另外,此文中所涉及的知识点都是笔者通过实践得出的,因此若是其他专业书籍没有讲到过的问题可以参考本文。最后祝大家学习C语言顺利!