前言:从C开始的步伐 当前已经有很多书籍阐述C语言。这本书希望与众不同。它一方面想向读者展现作者学习该门编程语言的心路;另外一方面,它希望作为一本入门性的,提纲挈领性的教材,能够 全面引导读者走进编程世界。C语言作为一门非对象型的编程语言,在计算机编程语言具有非常重要的地位。首先C语言是真正意义的高阶编程语言,这体现在C语言隐藏了大部分(当然不是全部)编程理论中对硬件原理的理解,程序员可以尽可能的以符合人类逻辑思维习惯的方式编写程序。其次C语言是一门“规模”非常小的语言,这意味着我们的教材可以以非常小的篇幅介绍他的语法和文法。相比更加高阶的编程语言,如Java,C++,C#,GO,python等等编程语言来说,C语言的缺点是过程性而不具备对象性特征。这意味着用C语言编写程序相对更加繁琐,客观上也决定了C语言确实不很适合编写大型程序,因为编程的规模会相对更加繁重而庞大。 但是C语言却绝非原始的编程语言。在笔者看来,C语言的重要性体现在它是一些更加“现代”,更加适合编写大型应用程序的编程语言的本源。从某种角度上说,使用java或者C++编写程序,其实只是站在C语言的肩膀上编程。因为C++或者java的编译器或解释器本身就来自于C,我们见到的大多数面向对象的编程语言的编译器或者解释器都是用C语言实现的。这本身足以说明C语言的广泛适用性。也正因为C语言是一门非常适合编写计算机操作系统和其他与硬件通信,强调效率性的程序,所以它几乎可以称为现代计算机编程语言的鼻祖。我们设计编程语言很难摒弃C语言。这不是说,每一位程序员都应该具备设计编程语言的能力,而是充分揭示当我们使用Java和C++之类的更庞大的编程语言编程的时候,我们无法超越C语言。在效率性方面,C语言理所当然会超越它们。 C语言的另一重要特点在于它的可移植性。程序代码的可移植性体现在,一种程序的源代码,在不同处理器编译,所需要付出的工作量大小。比如说,我们在X86系列处理器上编写的程序源代码,是否能以最小的劳动量在Arm架构的处理器上运行。对于Java来说,这通常不是难题。因为运行java的虚拟机本身已经完成了可移植性工作。java程序员完全可以不必关心底层的兼容问题。但是这本身其实仍然是C语言的优点。因为底层的可移植性难题,本身就是用C语言作为工具处理的。通常来说,针对不同处理器的特性编写的代码,是无法移植的,因为不同处理器对应的指令集不可能完全一样。C语言的优点在于它尽可能集中处理不同处理器的难题,将通用性的问题通用性处理,这才是C语言可移植性良好的关键所在。也是java程序员或者诸如python之类的编程语言可移植性良好的关键。java程序员不必关注可移植性问题,因为java平台已经为他们处理了。 我们学习C语言的重要意义在于C语言在编程语言占据着极为重要的地位。当前C系列的编程语言为现代编程语言的绝大多数,C语言堪称构建现在编程语言大厦的基石,它是java,C++,C#的鼻祖。笔者认为,一名合格的程序员如果不能了解底层,如果不能熟悉代码运行背后究竟发生了什么,他就很难真正领会程序设计的本质意义。C语言是程序员了解程序底层哲学的重要桥梁。 很多程序员认为,我们学习一门编程语言,目的在于完成既定的工作目的。比如说,我们学习java,目的在于设计通用性的,可移植性的大型应用软件。C语言在完成同样的工作上,是逊色于java的。在他们看来,编程语言只是一种工具,我们的工作内容决定了我们对工具的选择。然而在笔者看来,并不是如此。因为从另外一个维度上说,我们学习编程语言,目的还在于更好的完成既定的工作。同样是设计软件,我们理应心存能不能更快,更好,更优质。C语言在完成同样的工作,在工作量上可能确实逊色java。逊色的原因并非C语言在设计哲学上比java差,而是因为java平台已经完成了很多工作了,简化了必要的工作环节。java程序员设计大型应用程序,就好像是拿着菜刀切肉;而C程序员设计大型应用程序,则是先像一个铁匠一样完成菜刀的制造,再去切肉。我们通常不会用C语言设计大型应用程序,但是对于有个有着深厚的C语言功底的程序员,它既然有铁匠的技术水准,当然可以定制一把菜刀,也可以定制一把宝剑。不懂C语言的java程序员或许只能拿着菜刀切菜,而懂C语言的程序员则不仅可以拿着菜刀切菜,还可以拿着宝剑比武。 因此C语言不仅仅是一门工具意义的编程语言,它更加接近编程语言的哲学。这难道还不能说服大量编程初学者选择C语言作为进入编程殿堂的理由吗? 计算机软件行业是一个非常庞大的行业,编程语言多如牛毛,编程书籍汗牛充栋。单纯学java或者汇编语言,很难窥见全局,容易使初学者只见树木不见森林。而学习C语言的重要意义在于它贯穿着软件行业诸多技术细节。它培养着一名程序员新手对软件绝大部分技术的全面性理解,从而建立一个体系化的软件知识。笔者认为一名想在软件行业有所建树,渴望走的更远的程序员,理应从C语言作为学习的第一步。任何一名程序员显然不能只接触一门编程语言。首先掌握了C语言,就有了对编程语言的整体印象,在以后学习java,C++等更“高阶”的语言,就有了事半功倍的可能。从某种意义上说,编程语言不过就是编程语法和API(API是一种编程接口,读者可以理解为是一种编程工具,用于和编译器或者解释器通信,相当于英文中的单词)的集合,所以每种编程语言的设计哲学都有相似性,他们的不同体现在编程平台之上。编程平台才真正决定了编程语言的不同。任何编程平台底层都是汇编或者C语言写成的。而汇编本身就是处理器的“方言”,C语言相当于处理器的“世界语”。 相对于java和C++等大型面向对象的编程语言来说,C语言规模非常小。笔者甚至可以用不到50页的篇幅介绍它,再通过不到50页的篇幅介绍这门语言的API。但是众所周知的是,C语言是一门公认较难的程序语言。它的难点来自于它的灵活性非常强,而灵活性来自于C语言的精华甚至是全部:指针。大多数编程语言隐藏了指针的概念。C语言的指针,是C语言能够作为硬件设计的重要原因。而要理解指针,必然要充分理解计算机的硬件。大多数现代编程语言隐藏了指针的概念,就对程序员隐藏了计算机底层硬件原理。这有他的优点,那就是程序员能够将他们的精力集中在程序设计方面,把其他工作交给更高的高手,也就是编译平台设计者本身来处理;这同样也是缺点,因为程序员的程序性能基本已经由编译平台设计者决定,至少无法超越他。C语言给了程序员们最大的自由,他们可以充分的运用计算机的性能,以指针的方式。 指针的概念和计算机硬件原理息息相关。掌握硬件原理,是一名程序员新手应该有的基本功,除非他只是想成为一名普通的应用程序员,而对成为一名计算机专家毫无兴趣。这也正是众人认为C语言学习曲线非常陡峭的关键。然而笔者要说的是,软件行业本身是技术密集性行业,C语言的难点在于硬件理解的难点,而理解硬件是非常有必要的。忽略硬件原理,就无法走的更远。而如果程序员理解了硬件的基本原理,那么C语言的难点就成了他的优点。他最终能够成功的运用这门灵活,强大的语言。 C语言确实很难,但是这种难是非常有必要的。一旦你掌握了它,你就有了成为软件大咖的基本素质,你就和那些只会下载java平台jre编写代码的程序员有着本质不同。在java程序员的工具箱里,他们只有菜刀和木棍,而这些菜刀和木棍还是别的编程高手恩赐的;而C程序员的工具箱,应有尽有,并且C程序员可以信手拈来,自己创造自己想要的工具。 C语言当然也有自己的编译工具。有读者或许会问,C语言的设计者是如何设计C语言的?答案是汇编语言。而汇编语言是不可移植的。那么由汇编语言直接设计的C语言究竟有什么优点能让C语言强大至今,无法摧毁呢?汇编语言,通常也有一个工具用于编译,那就是汇编器。汇编器将汇编语言转化为机器语言,即计算机可以直接识别的语言,通常是1和0的组合。设计C语言的计算机科学大师(只能如此膜拜),充分考虑了C语言语法的自然逻辑性和硬件之间的关系,取得了一个良好的平衡点,允许C语言的编译器可以充分运用计算机的性能,对应生成的计算机语言贴合实际目标,产生了更少的无用代码段。才构建了C语言卓越的本质。 C语言的强大和灵活来源于C语言的编译器和编译器的设计哲学。因此笔者认为,不结合具体的编译器讲解C语言,可以称之为空中楼阁。单纯的程序语言讲解起来并没有多少意义。我们学习C语言的实质不在于语法,而在于培养对程序设计的宏观认识,对硬件原理的基础理解,对设计程序的精准把握。这当然也是本教材讲解C语言的出发点。 本教材题为《C语言导论》,而其实有着更加宏大的目标,那就是培养读者对程序设计的全面性的认识和把握,是一本讲解内功而非外功的教材。深入而再深入,将一切问题尽可能讲述透彻,是笔者写作的基本目标。笔者不希望读者心存任何疑惑,而以刨根问底的精神将一切问题解释清楚。笔者认为,这是一名伟大的程序员应该有的素质。 题外,中国的软件行业非常发达,但是我们可知的是大多数重要的工程领域的软件都是国外设计。比如操作系统的重要部分,Linux/Unix,windows,都来自欧美国家。中国实际没有成熟商业运作的现代操作系统;再比如说,Photoshop,matlab,VisualStudio等等大型应用软件,也都是欧美国家设计出来并得到广泛运用;而大多数流行的编程语言,也是国外发明创造出来,众所周知的C++,Java,Python,C#等等,包括本教材中所要讲述的C语言,无一例外不是国外设计。这本身让我们感到汗颜。有着十四亿人口的中国在基础软件技术领域存在巨大的空白,几乎全然依靠国外的基础性技术!更不要说,在硬件领域,各类芯片的国产缺失。这些缺失本身说明了我们国家在信息科技领域缺少人去从事基础性的工作。而之所以存在如此之大之多的空白,本质还是我们信息科技行业十分浮躁,很少有人愿意深入钻研信息科技的本质问题。笔者希望能够有更多的朋友同我一样,有着高度的钻研热情研究基础信息科技领域。中国信息科技的进步,不能建立在缺少原创的基础上。如果中国缺少自己的芯片,缺少自己的操作系统,就可以认为中国缺少自己的信息文化,就无法认为中国是一个真正意义的信息强国。这既不合理,也十分危险。