C premier plus Chapter 1

第一章 学习准备

你将会在这一章学到:
1. C的历史以及特点
2. 写程序的步骤
3. 关于代码连接器与编译器的一些知识
4. C标准

欢迎来到C语言的世界!C语言是一种充满活力的高级编程语言,它受到业余与商用编程者的喜爱。
这一章会为你学习与利用这种强大而又受欢迎的语言,而且会向你介绍几种你最有可能搭建C语言基础的环境。

首先,我们看向C语言的来源和它的一些特点(优点以及缺点)。接着,我们会了解编程的起源,查看编程的总体规则。
最终,我们会讨论如何在常见的系统中运行C程序。

1.1 C语言的由来

贝尔实验室的Dennis Richie在1972年创造了C语言,也就在那时,他和Ken Thompson正在致力于设计Unix系统。C语言的想法并不完全是在Richie的脑袋里冒出来的,而是来自Thompson的B语言,B语言来自哪里又是另一个故事了。重点是,C语言是作为工作中的编程人员的工具被创造出来的,所以它的首要目标就是成为一种有用易用的语言。

很多编程语言都有着类似的目标,但是它们又经常会有其他的顾虑,举几个例子,Pascal语言的主要目标,就是为了教授编程规则提供良好的平台。BASIC语言,被设计得与英语很相像,从而可以方便地让不熟悉电脑的学生们学习。这些目标都是很重要的,但是并不与实际使用协调,也并不是普遍都很易用。相比之下,C语言是为了编程人员而生的,而且成功地成为了现代编程语言的一种选择。

1.2 为什么使用C语言?

在过去的30年来,C语言已经成为了最重要与最受欢迎的编程语言。它的成长,就是因为人们经过尝试之后,喜欢使用它。过去的10年里,许多人从C语言转到的更有规模的C++上,但C语言仍然是拥有权重的一种很重要的语言,C++也是从C语言迁移过来的。在学习C语言的过程中,你会意识到C语言的许多长处(见图1.1)让我们预先查看一下。
插图
(上图,左上为强大的控制结构,右上运行速度快,左下小型代码-小程序,右下是可以传输到不同的电脑)

1.2.1设计特点

C语言是一种拥有在理论界以及计算机科学实践中令人满意的控制特色的现代编程语言。它的设计让它很自然地能自上而下地规划程序、结构化编程以及模块化设计,从而设计出的程序也更可靠,更易懂。

1.2.2 效率

C语言是一种高效的编程语言,它的设计很好地利用了现代电脑的性能。C语言编写的程序常常是小型的,并且运行速度很快。事实上,C表现了一些在汇编语言中好的控制方法,(汇编语言是对于特定的中央处理单元(Central Processing Unit,CPU)的内部指令设计的的助记语句,不同的CPU有着不同的汇编语言)。如果你选择C语言,你可以调节你的程序到达最快速度或者让程序对于内存的使用更有效。

1.2.3 可传递性

C语言是一种可传递的编程语言,那意味着在一个系统上的C语言程序也可以在其他系统经过少量的改动或者不改动运行。即使改动是必须的,也只是改动头文件与main程序里的几个词条而已。大多数也打算着有可传递性,但是任何想要把个人电脑IBM里的BASIC程序放到苹果BASIC(它们是近亲)或者尝试把主机上的IBM里的FORTRAN程序在Unix系统中运行都知道传递烦人透顶。C语言是可传递性的领头者。C语言的编译器(把你的C语言代码转换为电脑内部指令的程序)对于40种系统都是可以使用的。从微型处理器到超算。但需要注意的是,一部分程序对于不同的硬件设备是不一样的,比如显示器监控,或者因为在运算系统上的特殊点,比如WinXP与OS X,它们通常是不具有传递性的。

因为C语言与Unix操作系统关系紧密,Unix系统的安装包是自带C语言的编译器的,Linux安装时也通常带有C语言编译器,一些C语言编译器是可以在个人电脑上使用的,包括运行着各种版本的Windows系统的电脑,还有Mac。所以不论你是正在使用着家里的电脑,还是使用专业的工作站或者大型电脑,你都是有很大可能获得一个适用于你的系统的C语言编译器的。

1.2.4能力与灵活性

C语言既强大又灵活(在计算机文献中最受喜欢的两个词)。
举个例子,许多功能强大与灵活的操作系统是用C语言写的。许多的其他编程语言(如FORTRAN、Perl、Python、Pascal、LISP、Logo与BASIC)的编译器与翻译器是用C语言写的。结果,当你在Unix机上使用FORTRAN语言,最后是用C语言程序生成的exe文件。C语言程序被用作解决物理、工程问题甚至在电影如《角斗士》中栩栩如生地重现特殊的现象。

1.2.5 以程序员为方向的

C语言重视于满足程序员的需求,让我们轻松地触达硬件,而且让你独立地操纵内存中的每一个bit。它拥有非常多的运算符,能够让你简洁地表达自己。C语言比起,比如说Pascal语言就在限制着你可以做的事情。这种灵活性既是优势也很危险。优势在许多的任务,像是数据形式转换,在C语言中简单很多。危险就是用C语言,你有可能犯在其他语言中不可能犯的错误。C语言给予了你更大的自由,也让你承担了更多的责任。

另外,大多数C语言的实施都有着大量有用的C语言库函数。这些函数能够应对很多编程人员通常的需求。

1.2.6 缺点

C确实有一些不足之处。通常,像人一样,不足与长处是同一个特点的两面。例如,我们提到了C语言的自由表达也需要更多的责任。C语言的指针(我们以后会学习到)使用特别地,意味着编程错误会更难跟踪到。曾经也提到了一台没有文字的电脑,解放的代价就是格外的警惕,

有着大量的运算符,C的简明也让有可能让我们写出极其难以理解的代码。你可能并不是必须要写晦涩的代码,但是可能性总在那儿。毕竟,其他语言哪个有每年一次的混乱的编程比赛?

还会有更多的长处,毫无疑问也会有更多的缺陷。与其在这个问题上挖的更深,还不如移到下一个话题。

1.3 C语言的用处

到 1980 年代初,C 语言已经是 Unix 系统小型计算机世界的主导语言了。从那时起,它就已经被传播到个人计算机(微型计算机)和大型主机(大型计算机)了。(参见图 1.2)许多软件公司把C语言作为制作文字处理程序、电子表格、编译器和其他产品的首选语言。它们知道C语言编写的程序代码量小而且高效。更重要的是,他们知道这些程序将易于修改,并易于适应新型号的计算机。
图片
(以上,C语言被用作编程Unix操作系统,被用作电影如Star wars,在电脑游戏、电脑语言处理、嵌入式系统与机器人工程中都有显著的作用)

C语言不仅对公司和老手有好处,对其他用户也有好处。越来越多的计算机用户已经开始使用 C 语言,它的优势也得到了确保。你不必是专业的计算机编程人员就可以使用C语言了。
在 1990 年代,许多软件公司开始转向 C++ 语言进行大型编程项目。C++ 将面向对象的编程工具嫁接到 C 语言中。(面向对象编程是一种思想体系,它试图使语言来适应问题,而不是让问题来适应语言。)C++ 几乎是 C 语言的超集,这意味着任何 C程序也是,或者它几乎也是一个有效的C++程序。通过学习 C语言,您还学习了许多 C++。
尽管 C++ 和 Java 等新型的编程语言很受欢迎,但 C语言在软件公司依然是核心技能,一直排在所需技能的前 10 名。特别的,C语言已成为在嵌入式系统编程中很受欢迎的一种语言,也就是说,它被用于编程越来越多的汽车、相机、DVD 播放器和其它现代便利设施中的常见的微型处理器。此外,C语言已经开始追赶在科技科学编程上具有长久的主导地位的FORTRAN语言。最后,作为为开发操作系统而生的语言,C语言在Linux系统的发展中发挥着重要作用。所以,在二十一世纪的第一个十年, C 语言的影响力仍然在变得更大。

简而言之,C 是最重要的编程语言之一,并将继续如此。如果你想要一份编程软件的工作,这应该是你能够回答“是”的第一个问题中的一个,“嗯,比如说,你会C语言吗?“

1.4 计算机的作用

既然你已经要开始学习如何运行C语言程序了,你很可能需要了解一下电脑是怎么工作的,这些知识能够帮助你了解C语言程序与最终运行程序后发生的事情之间的关联。

现代的电脑有几个组成部分,中央处理器,又叫CPU,做了电脑运转时的大部分工作。随机存取器,又叫RAM,作为保存文件与程序的工作区。永久存储器,比如硬盘,存储程序和文件,即使电脑已经关机。各种外设,比如键盘、鼠标还有显示器,在你与电脑交互中搭建了桥梁。CPU运行程序,所以我们集中于它的作用。

CPU的自始至终的工作,简单来说,其实是非常简单的。它从内存中依次抓取一条条的指令,然后执行它。(千兆赫CPU可以在一秒钟执行这个过程百亿次,所以CPU可以以一种惊人的速度运作),CPU也有自己的小工作区,有几个储存数的寄存器。每一个寄存器保存下一条指令的内存地址,然后CPU就使用这些信息来抓取下一条指令。接下来,CPU再把指令储存在另一个寄存器中,然后把上一个寄存器的命令更新到下一条。CPU能够理解的指令(也叫指令集)是有限的。而且这些指令都是各自分明的。很多指令都是要求电脑去把数字从一个地方移动到另一个地方。—例如,从内存到寄存器。

在这个过程中有几点很有趣。第一,在电脑中任何东西都是以数字的形式储存的,数字是以数字的形式储存的。字符(例如你在文本编辑中的英文字母),也是由数字的形式储存的,每一个字符都有一个数字编码。计算机储存进寄存器的指令也是数字的形式,指令集中的每一条指令都对应着一个数字编码。第二,电脑程序最终会被以数字指令的形式表达,这又叫机器语言

计算机运行的一种结果就是,如果你想让计算机做些事,你需要提供一系列的指令或者是程序,来明确地告诉它要做什么和怎么做。你必须创建一个电脑能够直接理解(使用机器语言)的程序。这是个精细、单调、费劲的任务。一些像两个数相加的简单的任务可能会被分解成几步,可能会像下面几步。

1.从内存区域2000把数字复制到寄存器1
2.从内存区域2004把数字复制到寄存器2
3.用数字二的数值加上数字一,在寄存器1留下答案。
4.把寄存器1中的数据复制到内存区域2008

而且你还得把每一条指令用数字指令表述出来!

如果你是喜欢以这种方式写程序的,你会很难过地了解到机器语言编程的黄金时期已经远远地过去了。但是如果你更喜欢那些更愉快的编程,那就对高级编程语言打开怀抱吧!

1.5 高级计算机语言与编译器

高级编程语言,比如C语言,以很多方式简化了你的编程。
第一,你不需要用数字的形式来表达你的指令。
第二,你使用的指令与你对于程序的思考而不是与电脑使用的精确的指令

与其关心某一个CPU为了完成某一个任务进行的某一步。你可以以一种更复杂的形式来表达你想做的事情,例如,你也许会写下面的东西。

1
total = mine + yours;

看到这样的代码,你能够很明白它是干啥的,
而看着机器语言以数字构成的替代指令,那就太不易读了。

不幸的是,机器语言才是适合电脑的,对于电脑来说,高级语言完全无法理解。这就到了编译器上场的时候了,编译器是把高级语言程序详细地翻译成电脑需要的机器语言指令的程序。你以高级的方式思考,编译器做这些令人生厌的工作。

编译器方法还有另一种好处。每台电脑都设计了各自的机器语言,所以比如说英特尔PentiumCPU的机器语言对于摩托罗拉PowerPC CPU可能没有任何意义,但是你可以根据特定的机器语言搭配编译器。所以,使用一系列的编译器或者合适的编译器,你就可以把同样的高级编程语言转化成一系列不同的机器语言程序。你只需要解决这个问题一次,然后让编译器把这个解法翻译成一系列机器语言程序。

简短地说,高级的编程语言,比如C语言、Java还有Pascal,它们以一种更加抽象、与特定的CPU并不绑定的方式来表述程序行为。而且,对于机器语言来说,高级语言学习起来简单而且也更容易编程。

1.6 使用C语言的七步走

C语言,如你所见,是一种编译型的语言,如果你习惯于使用如Pascal或者FORTRAN的编译型语言,你应该已经对组成C语言程序的基本步骤很熟悉了。如果你的基础语言是如BASIC,或者面向接口的计算机图形语言(如Visual Basic)的翻译型语言,或者你还没有编程基础,你需要学习如何编译。我们一会就会研究那个过程,你会认识到这是很合理简单的。首先,为了让你宏观、大体上了解编程,让我们把编写C语言程序分解成7个步骤(见图1.3)。值得注意的是,这只是理想化的步骤,在编程实践中,你需要在步骤中来回切换,用后面一步了解到的来使之前的一步得到优化。
七步走

1.6.1 确定程序目的

很自然的,你需要明确地知道你想让程序做什么,思考你的程序需要什么信息,需要在计算与控制上完成什么样子的事情,而且程序内的信息需要对你有所反馈,在这一步的规划中,你应当以大体出发,而不是根据特定的编程语言来思考。

1.6.2 设计程序

在有了对于你的程序应该干啥的印象之后,你应该选择程序如何来运行它,用户的交互界面会是什么样子的?程序应该如何被组织起来?程序的目标人群是?你需要多长时间来做完这个程序?

你还要决定在程序中呈现数据,而且很可能的,在辅助文件里也要。要决定用什么方式来处理数据。在刚开始学习C语言时,可能选择会很简单,但是随着你应对更多复杂的情况后,你就会知道这些选择是需要更多的思考的。选择一种好的方式来呈现数据经常会让设计程序与处理数据简单很多。

再一次,你需要在大体层面上思考而不是在特定的代码上,但是有些选择可能是基于编程语言的大体特点的,举个例子,C语言编程人员就比,比如说,Pascal编程人员在数据呈现上拥有更多的选择。

1.6.3 编写代码

既然你已经对于你的程序有个清晰的设计了,你就可以通过写代码的方式来实现它了。也就是说,你可以把你的程序设计翻译为C语言。这就是你需要用上C语言知识的地方了,你可以在纸上画出你的想法,但最后你还是要把你的代码输入电脑。这个过程主要取决于你的编程环境,我们一会会呈现更多的常见的编程环境。总体上,你会使用文本编辑器来创造一份源码文件,它包含了你程序设计的C语言翻译,例1.1给出了C语言源码的一个例子。

图例1.1
在这一步,你应该记录你的工作,最简单的方式是使用C语言的注释功能,它包含着你对于源码的解释,我们会在第二章详细讲到如何注释你的代码。

1.6.4 编译

下一步就是编译源码,再一次,细节上的问题是与你的编程环境相关的,我们马上会研究几种常见的环境了。现在,让我们以更概念化的方式看看发生了什么。

我们已经知道编译器的工作就是把源码转化成可执行文件。可执行文件是以我们电脑的自然语言(或者说机器语言)写成的,这种语言是以精细的数字代码形式呈现的。而且你之前也了解到了,不同的电脑的机器语言是不一样的。C语言的编译器也包括着C语言库中的代码。C语言库包含着很多的基础的、日常使用的东西,比如Printfscanf函数。(更精确地说,一个叫做连接器的程序把C语言库中的一组代码带到编译器,但是编译器在大多数系统都是可以运行连接器的),最终结果就是包含着电脑可理解的可执行文件的程序,你可以直接运行。

编译器还会检查你的程序是不是使用了符合语法的C语言,如果编译器发现了错误,它就会汇报给你,而且不会生成可执行文件,理解编译器提示的错误信息也是你会很快习得的另一项技能。

1.6.5 运行程序

通常的,可执行文件是你可以运行的程序,你可以在很多常见的环境中,包括MS-DOS、Unix、Linux控制台、只需要打字写下可执行文件的名称。其他的环境,比如VMX、VAX可能需要一些运行指令或者其他的机制方法。集成开发环境(IDE),像很多在Windows系统或者Mac系统上的,使你能够在IDE内部通过菜单选项或者按几个按键来编辑与运行你的C语言程序。最终生成的文件也可以通过双击文件名或者图标的方式从你的操作系统直接运行。

1.6.6 测试与Debugging

你的程序能够运行是个好迹象,但是有可能你的程序并没有正确地运行。因此,你应该检查下是否它做到了它应该做的事情。你会发现有些程序是会有问题(在计算机领域内的行话叫bugs)的。调试是查找与修复程序错误的过程,学习的过程中犯错误是自然且正常的。看起来编程“天生”需要调试,所以当你把学习到的与编程实际结合起来的时候,你最好准备好在犯错的时候提醒自己。随着你成为一个更加强大与巧妙的编程人员,你也会不断地犯错,但你也因此不断地变得更加强大与巧妙。

你会有很多机会犯错,基础的设计层面错误,实现过程出错,忽略了可能会搞砸你的程序的输入。你可能会不恰当地使用C语言,你可能会拼写错误,可能会把括号放错了位置等等等等。你会有自己的错误方式来丰富这一列的。

幸运的是,这种情况并不是无望的,即使有时候你会这样认为啦。
编译器会捕捉到很多种类的错误,而且还会有工具来帮助你找到许多种编译器没有办法捕捉的错误。继续读下去,这本书也会给到你一些调试的建议。

1.6.7 维护与修改程序

当你为自己或者别人创造了一个程序,你可能会发现程序是可以有更多的用处的。如果是的,你可能会发现是有理由做出些修改的。可能有个小bug只有别人把名字以Z/z开头的时候才会发生,或者你会想出一种能够解决问题的更好的方式,可以聪明地加入一些的新功能,你可能需要改写程序以便它能够在不同电脑系统中运行。如果你明确地注释了这些程序,所有这些任务都会被极度地简化。

1.6.8 注释

编程的过程并不总是像这个过程描述的那样线性。有的时候你需要在步骤中前后切换。例如,当你在写代码的时候,你有可能发现你的计划并不实际。你有可能发现了一种更好的方式来做事,或者在看到程序是怎么运行的之后,你会想要改变你的设计,记录你的工作能够帮助你在不同的等级之间前后切换。

许多学习者通常会忽略掉第一步与第二步(确定程序目的与设计程序)直接进入第三部(写程序),你写的第一个程序或许可以直接在脑中看到完全的流程,如果犯错也很好定位错误。但是随着你编写的程序越来越复杂,越来越冗长,心智的视觉化就开始失效了,而且错误也会更难以发现。最终,那些忽略了规划步骤的人就陷入数小时的时间浪费、困惑还有沮丧,因为他们写出的丑陋的,无法实现功能而又深奥的程序。这项工作越是复杂,需要的规划工作就越多。

道理就是你需要养成在写代码之前做规划的习惯,使用这种古老但是可敬的笔尖技术来记下你程序的目的,给程序设计做出大纲。如果你这样做的话,你最终会收获节省时间与满足感的巨大红利。

1.6.9 编程技术

你生成程序的明确步骤是取决于你的电脑系统的,因为C语言是可传输的,它是可以适用于很多的系统环境的,包括Unix,Linux,MS-DOS(是的,很多人仍然在用),Windows与Mac OS,其实还有很多只不过没有足够的空间留给它们了,这尤其是因为各自的产品不是演化、消亡,就者被取代。

首先,即使如此,让我们先来研究许多C语言运行环境的共有特点,包括我们刚才已经提到的五种系统,你不需要明确地知道是什么引导了C语言程序的运行,但这是良好的基础,它也能够帮助你更好地理解为什么你需要经历一些特定的步骤来得到一个C语言程序。

当你在写C语言程序的时候,你会在源码文件中储存你在文本文件中写下的东西。大多数由C语言编程的系统,也包括我们提到的那一些,需要以.c结尾的文件(举个例子,wordcount.cbudget.c)在.c之前的那部分名字叫做基准名(Basename)
在这一段后面的名称叫做拓展名(Extension),因此,budget是基准名,.c是拓展名。它们的混合就是文件名。文件名也必须要复合特定的电脑操作系统的需要。例如,IBM-PC与[克隆机?]上的MS-DOS系统,它就要求你的文件名不能多于8个字符长。所以,wordcount.c在DOS系统中就不是合法的文件名。一些Unix系统在整个文件名上有14个字符的限制,包括拓展名,其他Unix系统也允许更长的名称,不多于255个字符即可。Linux、Windows与MacOS也允许更长的文件名。

让我们假设我们拥有一份名字叫Concrete.c的源文件储存着例1.2的C语言源码。
Concrete.c
不需要担心在源码文件中的一些细节,在第二章你会学到的。

1.7.1 目标代码文件、可执行文件和库

C语言编程的一个基本本领就是把你的源代码文件转化成保存着即时就可运行的可执行文件。要实现这个过程需要两个步骤:编译与连接。编译器可以把源代码转换成中间代码,然后连接器再把中间代码与其他代码组合,由此创造出可执行文件。C语言利用这两部分结合的方法让程序易于模块化生成。你可以把每一个模块分开来编译,再用连接器把每一个编译过的模块结合起来。以那种方式,如果你想改变其中的一个模块,你就不需要再重新编译其他的模块,而且连接器也会把你的程序与预先编译好的库代码结合起来。

要生成中间文件的方法还有几种,最流行的而且能够实施的在这里已经提到了,就是把源代码文件转化成机器语言代码,把结果放在目标代码文件中或者简短地说,目标文件。(假设你的源码是由单一文件组成的),虽然目标文件包括了机器语言代码,它还没准备好运行。目标文件包含了对于源代码的翻译版本,但是它还不完整。

缺失的第一个部分就是起始代码,它作为你的程序与操作系统的接口。举个例子,你可以在在DOS或者Linux之下协调地运行BM PC,它们的硬件都是类似的,所以同样的目标文件对于两种系统都是可以起作用的,但是你需要在DOS与Linux不同的起始代码,因为不同的系统是以不同的方式处理程序的。

第二个缺失的部分就是常用库的代码。几乎所有的C语言程序都需要利用C语言的库函数。比如Concrete.c使用的printf()。目标代码文件并不包括这个函数的代码。它只包含了printf函数的声明指令,实际的代码是在另一个文件中储存的,它叫库文件。库文件包含了很多函数的代码。

连接器的作用就是把这三个部分连接在一起-你的目标代码、起始代码和库代码,然后把三者整合为一个文件,即可执行文件。对于库代码,连接器只提取需要使用的函数在C语言库中对应的代码。
(见图1.4)
图1.4
(可见,上图中,由源代码经过编译器生成目标代码文件,再由目标代码文件与起始代码、库代码通过连接器转化为可执行文件concrete.exe).

简短来说,一份目标文件与可执行文件都由机器语言指令组成。然而,可执行文件只把你使用的代码翻译为机器语言,但可执行文件还由常用库与起始代码的机器语言翻译组成。

在一些系统中,你必须把编译与连接的过程分开。另外的一些系统中,编译器会自动启动连接器,所以你只需要编译即可。

现在我们就针对于特定的系统来研究一下。

1.7.2 Unix系统

因为C的流行始于Unix系统,我们就从它开始。

在Unix系统中进行编辑

Unix系统并没有独立的C语言编译器。你反而需要一些多功能的Unix编辑器,例如emacs、jove、vi或者一个X Window系统文本编辑器。

你的最主要的两个目的就是正确地书写程序,并且为储存程序的文件起个名字。正像已经提到的,文件的名称必须以.c。注意到Unix系统会以大小写来区分文件,所以BUDGET.cbudget.c还有Budget.c是三个各自不同的C源文件名称,但是BUDGET.C是不合法的,因为它的扩展名使用了大写。

使用vi编辑器,我们把下面的程序保存在名叫inform.c的文件中。
inform.c
这些文本就是源代码,而inform.c是源文件,重点就在源文件只是一个过程的起点,而不是结尾。

在Unix系统中进行编译

我们的程序,虽然已经不可否认地很精致了,对于电脑仍然是一派胡言,电脑是不理解什么是#includeprintf的(现在你可能也不理解,但是我们很快就会学习,然而电脑并不会),正像我们之前讨论过的。我们需要编译器的帮助来把我们的代码(源代码)翻译为电脑的代码(机器语言)。这些工作的结果就是可执行文件,它会包含所有可以让电脑完成工作的代码。

UnixC编译器叫cc,为了编译inform.c程序,你需要把下面的指令打下来。

1
cc inform.c

几秒之后,Unix系统的命令提示符就会给出反馈,告诉你这件事已经做完了,如果你没有正确地编写代码的话可能会得到警告或者错误信息,但我们先假设一切都是正确的。(如果你的编译器对于void这个词进行报错,那是你的编译器还没有更新到 ANSI C 的编译器,我们会在不久提到更多的标准,即使这样,你从例子中删掉void就好)。如果你使用ls指令来把你的文件列出来的话,你会发现产生了一个新文件叫a.out(见图1.5)这就是包含了程序中翻译后指令(或编译后指令)的可执行文件。想要运行的话直接打下a.out即可。

然后,文件中的指令执行,智言倾泻而出。

1
A .c is used to end a C program filename.

如果你想要吧可执行文件保存下来,你需要重新命名它,
否则,这个文件在你下一次编译时就会被新的同名文件代替。
The process
(从源码到程序的过程)

Linux 系统

Linux也是个很受欢迎的开源的,与Unix类似的多平台操作系统,它包括IBM与Mac的兼容。在Linux上设计程序与Unix系统的过程大部分是相似的,除了你需要使用公用C语言编译器,它叫gcc,是由GNU提供的,在那里面,编译的指令是这样的:

1
gcc inform.c

注意到在Linux安装的时候安装gcc的时候可能是可选的,所以你(或者其他人)有可能如果之前没装的话必须得自己安装gcc。通常这会让cc成为gcc的一个别名,所以你喜欢的话可以用cc来代替gcc。

你可以在下面的网站中获取关于gcc获取更多的信息,包括最新的版本。
http://www.gnu.org/software/gcc/gcc.html.

集成开发环境(Windows)

C编译器并不是Windows安装包中的一部分,所以你也有可能需要安装一个C语言编译器。很多供应商,比如Microsoft, Borland, Metrowerks, 还有Digital Mars, 提供了以Windows系统为基础的集成开发环境(IDE)(近来,很多已经把C语言与C++编译器结合在一起了。)它们都有快速且集成的环境,可以方便地生成C语言程序。值得注意的是,每一个程序都有一个嵌入式的编辑器,你可以用它来编写C语言程序。都有可以让你命名、保存、编译、运行的菜单。每一次编译运行如果编译器发现错误了你都可以回到编辑器,而且出错的代码行都会被突出显示出来,并搭配上适当的错误信息。

Windows IDE通常是可以一同处理C与C++的,你需要声明你需要一个C++程序。使用一些产品,比如Metroworks或者CodeWarrior里你需要用项目类型来区分你使用的语言。其他的产品比如Visual C++你是使用.c的扩展名来表示你想要使用C语言而不是C++。然而,大多数C语言程序也作为C++程序运作,可以参考“Differences Between C and C++”,那里对C与C++进行了比较。

你有可能遇到的一个问题是当程序停止的时候程序运行的窗口也随之关闭,如果你也遇到这种情况,你可以让程序直到你输入一个字符再结束。只要在代码结尾,return语句前加上一行代码即可。

1
getchar();

这一行代码读取一个键盘输入,所以直到你输入下一个字符之前程序都是暂停着的。一些时候,受到程序运行方式的影响,可能在最后已经有一个键入数据等待了,这种情况下你就得输入两次。

1
2
getchar();
getchar();

例如,如果程序做的最后一件事是要求你输入你的体重,你已经输入完体重了然后输入enter来输入数据,程序会读取你的体重,第一个getchar会读取回车符,第二个getchar直到你再打一个字符才会有,如果你现在还不太能够理解,你学习完C语言输入就会明白了。

即使多种多样的IDEs普遍有着比较类似的标准,但是细节方面还是各自不同的,不仅在一行程序内,还在编译器的不同版本。你需要做些实验,来获知你的编译器是怎么工作的,你还有可能需要阅读使用手册或者尝试网上教程。

IBMPC上的DOS编译器

对于很多人来说,在个人电脑上运行DOS是很过时的事情,但是它对于那些电脑资源与预算受限、喜欢更简单的,没有[响铃、哨音]与令人分心的事物的操作系统。很多Windows IDEs额外提供了命令行工具,这就然你能够在DOS命令行环境下编程。Comeau的C/C++编译器在很多系统中是适用的,包括几种Unix、Linux的变体,它就拥有一个命令行DOS的版本。并且,它还有免费与共享的DOS系统编译器,例如,GNU gcc编译器就有一个以DOS为基础的版本。

源码文件应该以文本文件形式存在,而它们并不是文字处理文件。(文字处理文件包括了很多额外信息,比如字体和格式)你应该使用一个文本编辑器如Windows Notepad或者与一些版本的DOS一同发布的EDIT程序。文件的扩展名需要是.c,一些处理器会自动在文本文件后面加上.txt的扩展名。如果你遇到了这种情况,你需要改变文件名,把.txt改为.c

电脑上的C语言编译器通常,但并不总是,生成带有.obj后缀的中间目标代码,不像Unix编译器,C语言编译器通常不会在编译完成之后删除这些文件。有些编译器也会生成带有.asm扩展名的汇编语言文件,或者使用它们自己的特殊形式。

Mac上的C语言

最广受闻名的Mac C/C++编译器就是Metrowerks CodeWarrior 编译器(Windows与Mac版本的CodeWarrior有相似的界面),它提供了与Windows编译器相似的以项目为基础的IDE。从文件菜单选择新文件开始,一系列的项目类型选择将会陈列在你眼前。在最新的CodeWarrior版本中,使用Std C控制台即可(不同的发布版本需要经过不同的步骤才到达选择这一步),你还有可能在68KB版本(适于摩托罗拉 680 * 0 系列的处理器),PPC版本(适于PowerPC处理器)或者Carbon版本(适于OS X系统)

新的项目在最初项目中会有一个很小的源码文件,你可以尝试编译或者运行它来获知你的系统是否设置好了。

1.8 语言标准

现在,很多C语言实例都是可行的,理想化情况下,当你在写C语言程序时,在任何的实例中都是一样运作的(假设你没有使用特殊机器来编程),为了这件事情能够实现,不同的实例需要有一个确定的、可识别的标准。

最初,C语言官方并没有语言标准,但是,由Brian Kernighan和Dennis Ritchie(1978)编纂的最初一版的C Programming Language确立了被接受的标准,它通常被称作为K&R C或者classic C。特别的是,那本书附录中的“C Reference Manual”作为了C语言实例的指导。但是,比如编译器,就会要求一个完整的K&R实例,因为即使附录中定义了C语言,它还没有定义C语言库。C比其他的大多数语言都要更加依赖于C语言库,所以库标准还需要确立。没有任何的官方标准的情况下,Unix实例中提供的库就成为了实际的标准。

第一个ANSI/ISO C语言标准

随着C语言的进步与在不同系统中的广泛使用,C语言社区意识到它需要一个更加综合、与时俱进并且严格的标准。为了满足这种需求,美国国家标准研究院在1983年成立了X3J11委员会,开发了一种新的标准,它在1989年被正式使用,这种新型标准(ANSI C)不仅定义了语言而且还定义了基础的C语言库,国际标准化组织采用了在1990年一种C语言标准(ISO C)。ISO C与ANSI C本质上是一样的标准。ANSI/ISO标准的最后一种版本通常被称作C89(因为那是ANSI同意的时候)或者C90(那是ISO同意的时候),而且因为ANSI版本是先推出的,人们更经常用的是ANSI C。

这个协会有几项指导准则,可能最有趣的就是这一项:保持C语言的精神
委员会在阐述这种精神的时候列出了以下的几点。

  • 相信编程人员。
  • 不要阻止编程人员做需要做的事情。
  • 保证简单、小型地使用这种语言。
  • 一项操作只提供一种方式。
  • 即使传输性会下降,也要尽力让C语言程序运行变快。

在最后一点中,委员会的意思是实例必须界定一种对于目标电脑的运转最好的操作,而不是试着强加抽象的、统一的定义。在学习语言的同时,你也会体会到这种哲学的。

C99标准

在1994年,他们开始重新审视这个标准,这也导致了C99标准的产生,一个ASIO/ISO联合委员会,也被称作C9X委员会批准了C90标准的准则,包括保持语言的小型与简洁,委员会的目的并不是向语言中添加新的特性,而是按需去达到新的目标。其中一个主要目标就是,通过比如提供解决国际字符集的方法,来支持国际编程。另一个目标就是“把现存的实践编程化来解决明显的缺陷”。因此,当在达成把C语言移植到64位的处理器上的需要时,委员会 以在真实生活中应对过这种问题的人的经验为基础来添加标准。第三个目标就是改善C语言执行科学与工程项目时做关键数字运算时的合适度。

这三点-国际化,纠正缺陷与对于计算可用度的改善是最主要的以改变为方向的目标,其他的改变计划自然更加保守,例如,把与C90与C++的不协调降到最低,并且让这个语言概念上是简洁的。用委员会人员的话来说,“委员会在让C++变得更加重要,更加有发展动力。

C99改变的结果,就是它保持了C语言的必要的基本特征,C语言仍然是一个小型的,简洁并高效的语言,这本书指出了很多C99的变化,因为现在的大多数编译器还没有完全实现所有的C99的改变,你可能会发现有些在你的系统上不能实施,或者你会发现一些C99特征只有你改变了一些编译器的设置才可以实现。

#注意
这本书将会使用ISO/ANSI C这些词来表示这些特征来表示均为两种标准均适用的特征,使用C99来指明新的特征。偶然的,当一种特性是第一次加入C语言时,它也指C90标准。

1.9 本书的组织架构

组织信息的方式有很多。其中一种最直接的方式就是把每一个话题的所有相关信息全部列出来,这对于参考书是极其实用的,因为你就可以在一个地方找到所有关于给定主题的信息。但是它对于学习项目并不是最好的顺序。例如,如果你从开始学习名词开始学习英语,你的表达能力就会被严重地限制。当然,学习好了名词你随便找到某个东西就能说出它的名字,但是如果你能够学一些名词、动词、形容词等等,还有一些关于这些部分如何相互连接的规则,你就会有更大的能力来表达自己。

为了让你能够更均衡地消化信息,这本书使用了一种螺旋上升的方式,在初期的时候先提到这个主题,然后在后文给予更充分的讨论。例如,对于理解C语言,理解函数是极其关键的,因此,在前面的几章就会包括对于函数的一些讲述,以便于你能够在第九章全面讲述函数的时候,已经能够使用函数获得到一些轻松了。相似的早期的篇章也会预先讲述字符串和循环,那样你就可以在还没有细致地地了解它们之前,在你的程序中先使用那些有用的工具。

1.10 例子的使用

我们已经差不多要开始学习C语言了,这一单元已经包括了我们在陈述材料的时候的一些例子了。

字体 Typeface

对于呈现文字的程序与电脑的输入输出,我们使用你很可能在屏幕上或者在输出的时候看到的相似的字体。我们已经使用过几次了。为了防止你没有注意到,字体看起来是下面这样的

字体示例

相同的等宽字体也被用作是与编程相关的词汇,比如main(),也用作文件名,比如stdio.h,对于用来替换特殊词汇的占位字符,我们是用斜体的等宽字符来写的,比如下面的描述。
type_name variable_name;
例如,你有可能用type_name来替换int,用variable_name来替换zebra_count

程序输出 Program Output

电脑中的输出是以与我们书中相同的形式被印出来的,但输入是以粗体字被显示出来的。例如,下面就是在14章“结构体与其他数据类型”中的输出。

输出示例

以正常电脑字体打印出来的是程序的输出,黑体字是用户的输入。
你与你的电脑交互的方式有很多,我们假设你是用键盘在键入指令的,在屏幕上阅读反馈。

特别的按键 Special Keystrokes

通常,你会通过一个标签为Enter的按键,c/r,返回或者其他的方式输入一行指令,我们在文中称这些按键为Enter key,自然也就会默认你会在每一行输入之后按下Enter键。然而,为了阐明特定的观点,一些例子可能会明示出Enter键,以[enter]的形式来呈现它,这个括号就表示你需要按下一个按键而不是打字enter

控制字符中的特殊按键,比如CTRL+D,这种标记指在你按下Ctrl标志的按键(或者可能是Control)时按下D键。

准备学习这本书使用的系统

Systems Used in Prepare This Book

C语言的一些部分,比如储存数字时使用的空间,是取决于系统的。当我们举例子并且指的是我们的系统,“我们提的是一台在WinXP专业版下有奔腾处理器的电脑,并且使用Metrowork的CodeWarrior开发工作室9.2版本和微软的Visual C++ 7.1(这个版本Microsoft Visual Studio .NET 2003也开发完成),或者gcc 3.3.3。在编写的时候,对C99的支持并不完全,而且没有编译器能够支持C99的全部特性。但是,在它们之间,这些编译器已经包含了许多的新标准下的东西了。大多数实例是在Mac G4上通过Metrowerks CodeWarrior Development Studio 9.2来测试的。

这本书有的时候也参考在Unix系统中运行的结果,Unix系统是在Berkley’s BSD 4.3 version的Unix系统中,在VAX 11/750电脑上运行的。而且,一些程序也是在Linux系统下使用gcc 3.3.1与Comeau 4.3.3在奔腾处理器的电脑上测试的。

样本代码,对于在这本书中陈述的完整程序是可以在Sams网址 (www.samspublishing.com) 中找到的,搜索这本书的ISBN号(不带连字号)就会显示这本书的昵称,点击昵称,进入网址,你就可以下载代码了。你还可以在这个网站上找到编程训练的解决方法。

你的系统-你需要的 Your System

你需要有一个C语言编译器,或者至少可以使用一个。C可以在很多中电脑中运行,所以你有很多的选择。一定要确保使用的编译器是专门为了你的系统而设计的。这本书中的一些实例需要C99标准支持,但是大多数实例在C90标准下的编译器都是可以运行的。如果你使用的是在ANSI/ISO标准之前的,你就需要做出一些调整了,很可能得通常鼓励你去找寻些新的东西了。

大多数编译器的供应商会为学生与教育者特价,如果你是那类人,那就看看供应商的网站。

特殊元素 Special Element

这本书包含了几部分特殊元素,强调了特别的重点:补充、建议、警告、笔记。

四种特殊信息类型

  • Sidebar(补充)
    为阐明内容提供了更深刻的见解或者更多的背景信息
  • Tip(建议)
    对于特定的编程情况提供了简短,使用的建议。
  • Caution(警告)
    警告潜在的陷阱
  • Note(笔记?)
    提供了综合的注释,不符合其他的特殊类型的信息。

总结

C语言是一种强大、简洁的编程语言。
因为提供了使用的编程工具、对于硬件设备的控制良好,
并且是最容易从一种设备传输到另一种设备的语言,
它受到很多人的欢迎。

C语言是一种编译型的语言,
需要C语言编译器与连接器来把C语言源代码转化成可执行程序。

C语言的编程可能是费力、困难甚至令人沮丧的,
但是它也可以是有趣的、令人振奋与满足的。
我们希望你能够像我们一样找到C语言的乐趣与魅力。

回顾问题

你会在附录A-回顾问题答案中找到问题的答案。
(以下为我本人的想法)

1.在编程中,传输性指的是什么?
编程得到的文件在不同类型的操作系统中几乎不需要修改或者只需要修改一点就可以顺利地进行转移。
2.解释源码文件、目标代码文件与可执行文件。
源码文件是我们通过编辑器输入的代码,目标代码文件是源码文件经过编译器处理之后生成的包含库文件函数声明与我们输入的代码的机器语言翻译的文件,一般是asm的汇编文件或者obj,不具有执行的能力。
可执行文件是把库文件与目标代码文件结合起来之后翻译成的最终文件,它包含了程序运行需要的一切函数声明、变量、指令的翻译。
3.编程的七步走。
首先在纸上想这个问题可以怎么解决,然后结合具体的语言来想实现方法,然后写代码,然后编译,然后运行,然后检查正误,进行修改与调试。
×
第一步,明确程序目的,你想要程序做什么
第二步,设计程序,包括目标人群,用户界面与交互方式,实现时间,数据处理方式
第三步,使用C语言知识写代码
第四步,编译
第五步,运行程序
第六步,通过输出过程量等方法来调试,输入多个值来测试。
第七步,维护与修改程序。
4.编译器做了什么工作?
把源码文件中你输入的代码转变为机器语言。
5.连接器做了什么工作。
把你代码中缺少的库函数内容补充完整,并且针对系统添加起始代码。

编程训练

我们现在还不期望你开始写C语言代码,所以这一次锻炼就集中于编程过程的早期阶段吧。

1.你被MacroMusic公司录取了,这个公司正在进入欧洲市场,想要一个能够把英尺换算成厘米的程序(1 inch = 2.54cm)公司想要让这个程序能够提示使用者去输入一个英尺值,你的任务就是找出这个程序的目的,并且设计这个程序。

程序目的:我想要设计一个通过乘除法来把输入的数值变作2.54倍的程序,输入是英尺值,2.54倍是厘米值。

程序设计:
首先输出一行:请输入英尺值
然后向用户获取输入值。
接着经过把值 * 2.54来获取厘米值
然后在屏幕上输出数值。

交互方式就是输入输出,因为目标人群是欧洲人,所以需要英语,需要更多的UI设计等。

END..

打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2023-2024 大学生暮暖
  • 访问人数: | 浏览次数:

请我喝杯奶茶吧~

支付宝
微信