程序设计基础教程——C语言(txt+pdf+epub+mobi电子书下载)


发布时间:2020-12-04 16:01:50

点击下载

作者:常东超、刘培胜、郭来德 等编著

出版社:化学工业出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

程序设计基础教程——C语言

程序设计基础教程——C语言试读:

前言

2017年2月以来,教育部积极推进新工科建设,先后形成了“复旦共识”“天大行动”和“北京指南”等多项共识,并发布了《关于开展新工科研究与实践的通知》《关于推荐新工科研究与实践项目的通知》,全力探索形成领跑全球工程教育的中国模式、中国经验,助力高等教育强国建设。

为了适应时代发展和人才培养的需求以及计算机技术的发展,在C语言标准及编译技术、集成开发环境不断变化的背景下,本书在作者多年《C语言程序设计》讲义的基础上,结合数位一线教师多年教学实践与研发经验,并考虑到学生的反馈信息,对各个章节的内容、结构等进行了修订、调整、完善和补充。特别在复杂结构的叙述方法上,作者根据多年的心得体会对教学内容进行了重新组织和编排,力求深入浅出、通俗易懂,使广大读者尽早、尽快掌握C语言程序设计方法,具备一定的程序设计能力。

全书分为10章,主要内容有程序设计基础理论和C语言程序的基本组成以及程序开发过程;C语言的基本数据类型、运算符、表达式、数据类型转换及标准的输入输出函数;C语言的基本语句和流程控制语句;数组、函数、指针的概念及用法;C语言的编译预处理功能;C语言结构体与共用体、C语言中文件的相关概念以及文件的各种操作方法;附录部分介绍了C程序设计的常用库函数。尤其值得一提的是,作者在C语言语法结构等基础知识的介绍方面作了进一步的总结和归纳,增加了一些和专业相关的案例内容,从而使读者阅读此书和学习C语言时更能感觉到有章可循。

本书紧紧围绕《全国计算机二级C语言程序设计考试大纲》,采用“案例驱动”的编写方式,以基础语法、语义训练为中心,语法介绍精炼,内容叙述深入浅出、循序渐进,程序案例与实际相结合、生动易懂,具有很好的启发性。每章均配备教学课件和精心设计的习题。本书配套的《C语言程序设计实验指导与习题精选》与教材结合紧密,对教学质量的提高可起到积极的促进作用。

本书与传统教材相比,在下面三个方面进行了改进和强化:(1)结合教学心得对部分知识点的叙述方法做了仔细修改,以使读者更容易理解;(2)为了扩大读者视野和更深入掌握C语言程序设计的方法,本书增加了有关编程的部分新内容并删改了不适应当前编程需要的陈旧内容,创新了部分习题;(3)结合全国计算机等级考试全新编程环境,采用新的标准对全书和例题内容进行了调试。

全书由辽宁石油化工大学常东超、刘培胜、郭来德等编著,参加编写和书稿校对工作的教师有卢紫微、苏金芝、吕宝志、吉书朋、杨妮妮、张国玉、韩云萍、王杨、张凌宇、李会举、张利群、徐晓军、胡玉娥等。辽宁石油化工大学计算机与通信工程学院李艳杰教授对全书内容进行了全面审阅并提出了很多宝贵建议,在此致以诚挚的谢意。全书由辽宁石油化工大学常东超统稿。

限于作者水平有限,书中如有不足之处,敬请读者批评指正,以利作者改进。编著者2019年1月第1章 C语言程序设计概述1.1 程序和程序设计的基本概念

目前计算机的应用已经深入到社会的各个领域,成为人们生活、学习和工作的必备工具。早期的计算机是用来计算的机器,但是目前的计算机尤其是微型计算机已不再是简单的计算机器了,而是具有强大的存储和计算能力、由程序自动控制的智能化电子设备。人与人之间交流需要语言,那么人与机器要进行交流也需要“语言”,这种“语言”就是我们要说的“程序”。程序来自生活,通常指完成某一事物的既定方式和过程。比如,我们常说做什么事情需要什么样的程序,在日常生活中可以看成是对一系列执行过程的描述。以学生去食堂打饭为例,为了完成这件事情需要几个步骤呢?首先,带上饭卡去食堂;其次,到相应的窗口去排队;然后,挑选饭菜并刷卡;接着,食堂职工负责盛取饭菜相应事宜;最后,离开食堂窗口,这样就完成了去食堂打饭的程序。

那么计算机中的程序是怎样定义的呢?它是指为计算机执行某些操作,或解决某个问题而编写的一系列有序指令的集合。这里涉及“指令”的概念,以日常生活中的指令来解释,比如,办公室里的老板对秘书发出指令,需要秘书做口述笔记,键入信函内容、发传真等等,那秘书就需要按照指示逐步完成老板发出的每一条指令,最终完成老板交代的事情。在计算机中,就是由程序员对计算机发出指令,想让计算机解决某个问题,就可将解决问题的过程用计算机能够接受的方式或者选择某一种计算机语言将它一步一步地描述出来,计算机就会按照预先存储在它里面的代码逐步去执行,这就是计算机中的指令,而指令的集合就构成了计算机中的程序,编写程序的过程就称为“程序设计”。

计算机程序就是人与计算机交流的“语言”,也就是程序设计语言。正如人与人交流有不同的语言一样,程序设计语言也有很多种,基本上分为高级语言和低级语言两大类。目前常见的高级语言有Visual Basic、C++、Java、C等,这些语言都是用接近人们习惯的自然语言和数学语言作为表达形式,使人们学习和操作起来感到十分方便。但是,对于计算机本身来说,它并不能直接识别由高级语言编写的程序,只能接受和处理由0和1的代码构成的二进制指令或数据。由于这种形式的指令是面向机器的,因此也称为“机器语言”。

我们把由高级语言编写的程序称为“源程序”,把由二进制代码表示的程序称为“目标程序”。为了把源程序转换成机器能接受的目标程序,软件工作者编制了一系列软件,通过这些软件可以把用户按规定语法写出的语句一一翻译成二进制机器指令。这种具有翻译功能的软件称为“编译程序”,每种高级语言都有与它对应的编译程序。例如,C语言编译程序就是这样的一种软件,功能如图1.1所示。图1.1 C语言编译程序功能示意图

我们无论采用哪种语言编写程序,经过编译(compile)最终都将转换成二进制的机器指令。C源程序经过C编译程序编译之后生成一个后缀为.obj的二进制文件(称为目标文件),然后由称为“连接程序”(link)的软件,把此.obj文件与C语言提供的各种库函数连接起来生成一个后缀为.EXE的可执行文件。在操作系统环境下,只需点击或输入此文件的名字,该可执行文件就可运行。1.2 算法与程序设计

所谓算法,是指为解决某个特定问题而采取的确定且有限的步骤。

对于一个问题,如果可以通过一个计算机程序,在有限的存储空间内运行有限的时间而得到正确的结果,则称这个问题是算法可解的。但是算法不等于程序,也不等于计算方法。当然,程序也可以作为一种描述,但通常还需考虑很多与方法和分析无关的细节问题,这是因为在编写程序时要受到计算机系统环境的限制。通常程序的编制不可能优于算法的设计。1.2.1 算法的基本特征

作为一个算法,一般具有以下几个特征。(1)可行性

针对实际问题设计的算法,人们总是希望得到满意的结果。但一个算法又总是在某个特定的计算工具上执行的,因此,算法在执行过程中往往受到计算工具的限制,使执行结果产生偏差。例如,在进行数值计算时,如果某计算工具具有7位有效数字,则在计算1212X=10,Y=1,Z=-10

3个量的和时,如果采用不同的运算顺序,就会得到不同的结果,即:1212X+Y+Z=10+1+(-10)=01212X+Z+Y=10+(-10)+1=1

而在数学上,X+Y+Z与X+Z+Y是完全等价的。因此,算法与计算公式是有差别的。在设计一个算法时,必须要考虑它的可行性,否则是不会得到满意结果的。(2)确定性

算法的确实性,是指算法的每一个步骤都必须是有明确定义的,不允许有模棱两可的解释,也不允许有多义性。这一性质也反映了算法与数学公式的明显差别。在解决实际问题时,可能会出现这样的情况:针对某种特殊问题,数学公式是正确的,但按此数学公式设计的计算过程可能会使计算机系统无所适从。这是因为,根据数学公式设计的计算过程只考虑了正常使用的情况,而当出现异常情况时计算机就不能适应了。(3)有穷性

算法的有穷性,是指算法必须能在有限的时间内完成,即算法必须能在执行有限个步骤之后终止。数学中的无穷级数,在实际计算时只能取有限项,即计算无穷级数数值的过程只能是有穷的。因此一个数的无穷级数表示只是一个计算公式,而根据精度要求确定的计算过程才是有穷的算法。

算法的有穷性还应包括合理的执行时间的含义。因为,如果一个算法需要执行千万年,显然就失去了实用价值。(4)输入

一个算法可以有零个或多个输入。由于在计算机上实现的算法是用来处理数据对象的,因此在大多数情况下这些数据对象需要通过输入来得到。(5)输出

一个算法有一个或多个输出,这些输出是同输入有着某些特定关系的量。

一个算法是否有效,还取决于为算法所提供的情报是否足够。通常,算法中的各种运算总是施加到各个运算对象上,而这些运算对象又可能具有某种初始状态,这是算法执行的起点或依据。因此,一个算法的执行结果总是与输入的初始数据有关,不同的输入将会有不同的结果输出。当输入不够或是输入错误时,算法本身也就无法执行或导致执行出错。一般来讲,当算法拥有足够的情报时,此算法才是有效的,而当提供的情报不够时,算法可能失效。

综上所述,所谓算法,是一组严谨的定义运算顺序的规则,并且每一个规则都是有效的,且是确定的,此顺序将在有限的次数下终止。1.2.2 算法的基本要素

一个算法通常由两种基本要素组成:一是对数据对象的运算和操作,二是算法的控制结构。(1)算法中对数据对象的运算和操作

每个算法实际上是按解题要求从环境能够进行的所有操作中选择合适的操作所组成的一组指令序列。因此计算机算法就是计算机能处理的操作所组成的指令序列。

通常,计算机可以执行的基本操作是以指令的形式描述的。一个计算机系统所能执行的所有指令集合称为该计算机系统的指令系统。计算机程序就是按解题要求从计算机指令系统中选择合适的指令所组成的指令序列。在一般的计算机系统中,基本的运算和操作有以下4种。

①算术运算:主要包括加、减、乘、除等运算。

②逻辑运算:主要包括“与”“或”“非”等运算。

③关系运算:主要包括“大于”“小于”“等于”“不等于”等运算。

④数据传输:主要包括赋值、输入、输出等操作。(2)算法的控制结构

一个算法的功能不仅仅取决于所选用的操作,还与各操作之间的执行顺序有关。算法中各操作之间的执行顺序称为算法的控制结构。

算法的控制结构给出了算法的基本框架,它不仅决定了算法中各操作的执行顺序,还直接反映了算法的设计是否符合结构化原则。描述算法的工具通常有传统流程图、N-S结构化流程图、算法描述语言等。一个算法一般都可以用顺序、选择、循环3种基本控制结构组合而成。1.2.3 算法描述的方法

算法是描述某一问题求解的有限步骤,而且必须有结果输出。设计一个算法,或者描述一个算法,最终是由程序设计语言来实现的。但算法与程序设计又是有区别的,主要是一个由粗到细的过程。算法是考虑实现某一个问题求解的方法和步骤,是解决问题的框架流程;而程序设计则是根据这一求解的框架流程进行语言细化,实现这一问题求解的具体过程。

一般可以使用下面几种类型的工具描述算法:(1)自然语言

自然语言即人们日常进行交流的语言,如英语、汉语等。自然语言用来描述算法,分析算法,作为用户相互之间进行交流,是一种较好的工具。但是将自然语言描述的算法直接在计算机上进行处理,目前还存在许多困难,包括有诸如语音语义识别等方面的问题。(2)专用工具

要对某一个算法进行描述,可以借助于有关图形工具或代码符号。20世纪50~60年代兴起的流程图几乎成了程序设计及算法描述的必用工具,是描述算法很好的形式。

人们已经提出了多种描述算法的流程图。这种方法的特点是用一些图框表示各种类型的操作:圆角矩形表示起止框,在算法开始和结束的时候使用;菱形表示判断框;矩形表示处理框;平行四边形表示输入/输出框;带点不封闭矩形表示注释框;基本图形用流程线连接起来,通过流程线反映出它们之间的关系;小圆圈表示连接点,大型系统中流程线和基本图形连接起来时,通常用小圆圈表示。图1.2为一般流程图所用的基本符号图形。图1.2 流程图所用的基本符号图形

流程图这里主要介绍传统流程图和N-S流程图。

传统流程图的优点是形象直观、简单方便,根据流程线能很直观地看出程序的走向;缺点是它对流程线的走向没有任何的限制,导致谁都可以修改流程的走向,使流程随意转向,而且它在描述复杂算法时,所占篇幅较多。

N-S流程图是在1973年,由美国学者I.Nassi和B.Shneiderman提出的一种新的流程图形式,这种流程图完全去掉了流程线,算法的每一步都用一个矩形框来描述,把一个个矩形框按执行的次序连接起来就是一个完整的算法描述。这种流程图用两位学者的第一个英文字母命名,因此称为N-S流程图。在下一小节中将结合结构化程序设计中的三种基本结构来介绍这种流程图的基本结构。(3)部分常用的算法

在程序设计时,常常要通过一些特定的算法来求解。现在比较常用的算法有下列几种:

①迭代法 一般的一元五次或更高次的方程,以及几乎所有的超越方程、微分方程问题都无法用解析方法通过求根公式来求解,人们只能用数值方法求其近似解。用事先估计的一个根的初始值X,通0过迭代算式X+1=G(X)求出另一个近似值X,再由X求出X,从KK112而获得一个求解的序列{X,X,X,…,X,…}来逼近方程f(x)012n=0的根。这种求解的过程称为迭代。

②枚举法 枚举法的基本思想是首先依据题目部分条件确定答案的大致范围,然后逐一验证所有可能的情况,这种算法也称为穷举法。

③递归法 递归是指一个过程直接或间接地调用它自身,递归过程必须有一个递归终止条件。

如:

④递推法 算法从递推初始条件出发,应用递推公式对问题进行求解。如Fibonacci数列存在递推关系:F(1)=1,F(2)=1,F(n)=F(n-1)+F(n-2),(n>2)

若需求第30项的值,则依据公式,从初始条件F(1)=1、F(2)=1出发,可逐步求出F(3)、F(4)……,直到求出F(30)。

除此之外,还有回溯法(一种基本策略)、分治法(问题分解成较小部分,求解再组合)等其他的常见算法,在此不一一阐述。1.2.4 程序设计(1)程序设计

程序设计的过程一般包含以下几个部分:

①确定数据结构:是指根据任务书提出的要求、指定的输入数据和输出结果,确定存放数据的数据结构。

②确定算法:针对存放数据的数据结构来确定解决问题、完成任务的步骤。

③编码:根据确定的数据结构和算法,使用选定的计算机语言编写程序代码,输入到计算机并保存在磁盘上,简称编程。

④调试:目的是验证代码的正确性,用各种可能的输入数据对程序进行测试,消除由于疏忽而引起的语法错误或逻辑错误;使之对各种合理的数据都能够得到正确的结果,对不合理的数据能进行适当的处理。

⑤整理并写出文档资料。

这就是编写程序的五个步骤。(2)结构化程序设计

对于任何一个程序来说,都有自身的结构。就像我们读文章一样,我们说文章的结构是顺叙的、倒叙的或是插叙的等,结构化的程序设计由三种基本结构组成。

①顺序结构 在本书第3章中将要介绍的如赋值语句,输入、输出语句都可以构成顺序结构。当执行由这些语句构成的程序时,将按这些语句在程序中的先后顺序逐条执行,没有分支,没有转移。顺序结构可用图1.3所示的流程图表示,其中图(a)是一般的流程图,图(b)是N-S流程图。图1.3 顺序结构流程图

②选择结构 在本书第4章中将要介绍的if语句、switch语句都可以构成选择结构。当执行到这些语句时,将根据不同的条件去执行不同分支中的语句。当判断表达式满足条件时,执行语句1,否则执行语句2。选择结构用图1.4所示的流程图表示,其中图(a)是一般的流程图,图(b)是N-S流程图。图1.4 选择结构流程图

③循环结构 在本书第5章中将要介绍不同形式的循环结构,它们将根据各自的条件,使同一组语句重复执行多次或一次也不执行。循环结构的流程图如图1.5和图1.6所示,每个图中图(a)是一般的流程图,图(b)是N-S流程图。图1.5是当型循环流程图。当型循环的特点是:当指定的条件满足(成立)时,就执行循环体,否则就不执行。图1.6是直到型循环流程图。直到型循环的特点是:执行循环体直到指定的条件满足(成立)时就不再执行循环体。图1.5 当型循环流程图图1.6 直到型循环流程图

已经证明,由三种基本结构组成的算法可以解决任何复杂的问题。由三种基本结构所构成的算法称为结构化算法;由三种基本结构所构成的程序称为结构化程序。(3)模块化程序设计

当计算机在处理较复杂的任务时,程序代码量非常大,通常会有上万条语句,需要由许多人来共同完成。这时常常把这个复杂的任务分解为若干个子任务,每个子任务又可分为很多小的子任务,每个小的子任务只完成一项简单的功能。在程序设计时,用一个个小模块来实现这些功能,每个程序设计人员分别完成一个或多个小模块。我们称这样的程序设计方法为“模块化”的方法,由一个个功能模块构成的程序结构为模块化结构。

在划分模块时需要注意的是模块与模块之间的独立性,尽量使一个模块能够完成一个功能,减少与其他模块之间的耦合性,提高模块的内聚度,这是模块化设计的基本思想。

由于把一个大程序分解成若干相对独立的子程序,每个子程序的代码一般不超过一页纸,因此对设计人员来说,编写程序代码变得不再困难。这时只需对程序之间的数据传输做出统一规范,同一软件可由一组人员同时进行编写,分别进行调试,这就大大提高了程序编制的效率。

结构化程序设计的基本原则是,自顶向下、逐步细化、模块化设计、结构化编码。软件编制人员在进行程序设计的时候,首先要从宏观上去把握,再逐步进行局部的细化。即应当集中考虑主程序的算法,写出主程序后再动手逐步完成子程序的调用。对于这些子程序也可用调试主程序的同样方法逐步完成其下一层子程序的调用。1.3 C语言简介1.3.1 C语言的发展历史

C语言是当今社会应用广泛,并受到众多用户欢迎的一种计算机高级语言。它既可用来编写系统软件,也可用来编写应用软件。

早期的系统软件设计均采用汇编语言,例如大家熟知的UNIX操作系统。尽管汇编语言在可移植性、可维护性和描述问题的效率等方面远远不及高级程序设计语言,但是一般的高级语言有时难以实现汇编语言的某些功能。那么,能否设计出一种集汇编语言与高级语言的优点于一身的语言呢?这种思路促成了UNIX系统的开发者——美国贝尔实验室的Ken Thompson在1970年设计出了既简单又便于硬件操作的B语言,并用B语言写了第一个在PDP-7上实现的UNIX操作系统。

以历史发展的角度看,C语言起源于1968年发表的CPL语言(Combined Programming Language),它的许多重要思想来自于Martin Richards在1969年开发的BCPL语言,以及以 BCPL 语言为基础的B语言。Dennis M.Ritchie在B语言的基础上,于1972年开发了C语言,并用C语言写成了第一个在PDP-11计算机上实现的UNIX操作系统(主要在贝尔实验室内部使用)。以后,C语言又经过多次改进,直到1975年用C语言编写的UNIX操作系统第6版公诸于世后,C语言才举世瞩目。1977年出现了独立于机器的C语言编译文本《可移植C语言编译程序》,从而大大简化了把C语言编译程序移植到新环境所需做的工作,这本身也就使UNIX操作系统迅速地在众多的机器上实现。例如VAX、AT&T等计算机系统都相继开发了UNIX。随着UNIX的使用日益广泛,C语言也迅速得到推广。1978年以后,C语言先后移植到大、中、小、微型计算机上,它的应用领域已不再限于系统软件的开发,而成为当今最流行的程序设计语言之一。

以1978年发布的UNIX第7版的C语言编译程序为基础,Brian W.Kernighan和Dennis M.Ritchie合著了影响深远的名著《C程序设计语言》(The C Programming Language),这本书中介绍的C语言成为后来广泛使用的C语言版本的基础,它被称为标准C。

1983年美国国家标准化协会(ANSI)根据C语言问世以来的各种版本,对C语言的发展和扩充制定了新的标准,称为ANSI C。1987年ANSI又公布了新标准,称为87 ANSI C。

目前流行的C语言编译系统大多是以ANSI C为基础进行开发的,不同版本的C编译系统所实现的语言功能和语法规则基本部分是相同的,但在有关规定上又略有差异。本书的叙述基本上以ANSI C为基础。1.3.2 C语言的特点

C语言是一种通用的程序设计语言。C语言的通用性和无限制性使得它对于程序设计者来说都显得更加通俗、更加有效。目前,C语言程序设计已应用于各个领域,无论是设计系统软件(操作系统、编译系统)或应用软件(图形处理),还是用于数据处理(如企业管理)或数值计算等方面都可以很方便地使用C语言。

C语言与其他高级语言相比具有以下特点:

①C语言具有结构语言的特点,程序之间很容易实现段的共享。它具有结构化的流程控制语句(如if…else语句,switch语句,while语句,do-while语句,for语句),支持若干种循环结构,允许编程者采用缩进书写形式编程。因此,用C语言设计出的程序层次结构清晰。

②C语言的主要结构成分为函数,函数可以在程序中被定义完成独立的任务,独立地编译成代码,以实现程序的模块化。

③C语言运算符丰富,运算符包含的范围很广泛。C语言把赋值、括号、强制类型转换都当作运算符处理。灵活地使用各种运算符可以实现在其他的高级语言中难以实现的运算。

④C语言数据类型丰富。数据类型有整型、实型、字符型、数组型、指针型、结构体型、共用体型等,能用来实现各种复杂的数据结构(如链表、树、栈等)的运算。尤其是C语言的指针型数据的运算,更是灵活、多样。

⑤C语言允许直接访问物理地址,即可直接对硬件进行操作,实现汇编语言的大部分功能。C语言这一特点,使得它成为编制系统软件的基本语言(UNIX的绝大部分就是由C语言写成的)。

⑥C语言语法限制不太严格,程序设计自由度大。这样使C语言能够减少对程序员的束缚。“限制”与“灵活”是一对矛盾。限制严格,就易失去灵活性;而强调灵活,就必然放松限制。从这个角度来看,使用C语言编程,要求编程者对程序设计技巧要更加熟练一些。

⑦用C语言编程,生成的目标代码质量高,程序执行效率高。同时用C语言写的程序可移植性好。

⑧C语言很容易被其他领域接受。单片机领域首选C语言作为开发工具,嵌入式系统和数字信号处理(Digital Signal Processing,DSP)领域也将C语言作为自己的开发工具。

C语言优点很多,但是它也存在一些缺点,如运算优先级太多,不便记忆;数值运算能力方面不像其他高级语言那样强,语法限制不严格等。尽管C语言目前还存在一些不足之处,但由于它目标代码质量高、使用灵活、数据类型丰富、可移植性好而得到广泛的普及和迅速的发展,成为一种深受广大用户欢迎的程序设计语言,同时也是一种在系统软件开发、科学计算、自动控制等各个领域被广泛应用的程序设计语言。1.3.3 C语言程序的基本结构及书写规则(1)C语言程序的基本结构

在学习C语言的具体语法之前,我们先通过一个简单的C语言程序示例,初步了解C语言程序的基本结构。【例1.1】  编写程序,输出文字:Hello C! #include  main() {  printf("Hello C!\n"); }

运行这个程序时,在屏幕上显示一行英文:

Hello C!

这是一个仅由main函数构成的C语言程序。main是函数名,C语言规定必须用main作为主函数名,函数名后面一对圆括号内是写函数参数的,本程序的main函数没有参数,故圆括号中间是空的,但圆括号不能省略。程序中的main()是主函数的起始行,一个C程序总是从主函数开始执行。每一个可执行的C程序都必须有且仅有一个主函数,但可以包含任意多个不同名的函数。main()后面被大括号{ }括起来的部分称为函数体。一般情况下,函数体由“说明部分”和“执行部分”组成。本例中只有执行部分而无说明部分。执行部分由若干语句组成。“\n”是换行符,即在输出“Hello C!”后回车换行。

程序中的“#include ”通常称为命令行,命令行必须用“#”号开头,行尾不能加“; ”号,它不是C程序中的语句。一对括号“<”和“>”之间的stdio.h是系统提供的头文件,该文件包含着有关输入输出函数的说明信息。在程序中调用不同的标准函数,应当包含相应的文件,以使程序含有所调用标准库函数的说明信息。至于应该调用哪个文件,将在以后的章节中陆续介绍。

 【例1.2】  已知两个整型数8和12,按公式s=ab计算矩形的面积,并显示结果。#include            /*标准输入输出头文件*/ void main() {  int a,b,s;           /*定义三个整型变量*/  a=8;b=12;           /*将两整数值分别赋给两边长a和b*/  s=a*b;           /*计算面积并存储到变量s中*/  printf("a=%d,b=%d,s=%d\n",a,b,s);   /*输出矩形的两边长和面积*/ }

执行以上程序的输出结果如下:

a=8,b=12,s=96

此例题函数体内由定义(说明)部分、执行语句部分两部分组成,程序中的“int a,b,s;”为程序的定义部分;从“a=8;”到“printf("a=%d,b=%d,s=%d\n",a,b,s);”是程序的执行部分。执行部分的语句称为可执行语句,必须放在定义部分之后,语句的数量不限,程序中由这些语句向计算机系统发出操作指令。

定义语句用分号“; ”结束。在以上程序中只有一个定义语句,该语句对程序中所用到的变量a、b、s进行定义,说明它们为int类型的变量。程序中“a=8;”和“b=12;”的作用是分别给矩形的两条边赋值,“s=a*b; ”的作用是计算出矩形面积并赋给变量s,“printf("a=%d,b=%d,s=%d\n",a,b,s);”的作用是按格式把a、b和s的值输出到屏幕。C程序中的每一条执行语句都必须用分号“; ”结束,分号是C语句的一部分,并不是语句之间的分隔符。

在编写程序时可以在程序中加入注释,用来说明变量的含义、语句的作用和程序段的功能,从而帮助人们阅读和理解程序。因此一个好的程序应该有详细的注释。在添加注释时,注释内容必须放在符号“/*”和“*/”之间。“/*”和“*/”必须成对出现,“/”与“*”之间不可以有空格。注释可以用英文,也可以用中文,可以出现在程序中任意合适的地方。注释部分只是用于阅读,对程序的运行不起作用。按语法规定,在注释之间不可以再嵌套“/*”和“*/”,比如:/*/*……*/*/这种形式是非法的。注意:注释从“/*”开始到最近的一个“*/”结束,其间的任何内容都被编译程序忽略。【例1.3】  求两个整数中的大数。#include"stdio.h"int sum(int x,int y){ int s2; s2=x+y; return s2;}main(){  int num1,num2,s1;  scanf("%d,%d",&num1,&num2);  s1=sum(num1,num2);  printf("sum=%d\n",s1);}

运行这个程序时,输入3,5↙   (输入3和5给num1,num2)

在屏幕上显示:

sum=8

本程序是由main函数和一个被调用的函数sum构成的。sum函数的作用是返回num1和num2的和,通过return语句将num1和num2的和s2返回给主调函数main中的变量s1。返回值是通过函数名sum带回到main函数的调用处。main函数中第3行为调用sum函数,在调用时将实际参数num1、num2的值分别传送给sum函数中的形式参数x、y。经过执行sum函数得到一个返回值,然后输出这个值。printf函数中双引号内“sum=%d\n”在输出时,其中“%d”将由sum的返回值代替,“sum=”原样输出。(2)书写程序时应遵循的规则

从书写清晰,便于阅读、理解、维护的角度出发,在书写程序时应遵循以下规则:

①一个说明或一个语句占一行。

②用{} 括起来的部分,通常表示了程序的某一层次结构。{}一般与该结构语句的第一个字母对齐,并单独占一行。

③低一层次的语句或说明可比高一层次的语句或说明缩进若干格后书写,以便看起来更加清晰,增加程序的可读性。

在编程时应力求遵循这些规则,以养成良好的编程风格。1.3.4 C语言的基本标识符(1)C语言的字符集

字符是组成语言的最基本的元素。C语言字符集由字母、数字、空白符、标点和特殊字符组成。在字符常量、字符串常量和注释中还可以使用汉字或其他可表示的图形符号。

①字母。大小写英文字母共52个。

②数字。0~9共10个。

③空白符。空格符、制表符、换行符等统称为空白符。空白符只在字符常量和字符串常量中起作用,在其他地方出现时,只起间隔作用,编译程序对它们忽略不计。因此在程序中使用空白符与否,对程序的编译不发生影响,但在程序中适当的地方使用空白符将提高程序的清晰度和可读性。

④标点和特殊字符。(2)标识符的命名规则

在C语言中,有许多符号的命名,如变量名、函数名、数组名等,都必须遵守一定的规则,按此规则命名的符号称为标识符。合法标识符的命名规则是:标识符可以由字母、数字和下划线组成,并且第一个字符必须是字母或下划线。在C语言程序中,凡是要求标识符的地方都必须按此规则命名。以下都是合法的标识符:

month,day,_pi,x1,YEAR,li_lei

以下都是非法的标识符:

¥100,123.5,li-lei,x>y

在C语言的标识符中,大写字母和小写字母被认为是两个不同的字符,例如year和Year是两个不同的标识符。

对于标识符的长度(指一个标识符允许的字符个数)在C语言中是有规定的,规定是标识符的前若干个字符有效,超过的字符将不被识别。不同的C语言编译系统所规定的标识符有效长度可能会不同。有的系统允许取8个字符,有的系统允许取32个字符。因此,在写程序时应了解所用系统对标识符长度的规定。为了程序的可移植性以及阅读程序的方便,建议变量名的长度最好不要超过8个字符。(3)标识符的分类

C语言的标识符可以分为以下三类。

①关键字 C语言已经预先规定了一批标识符,它们在程序中都代表着固定的含义,不能另作他用,这些标识符称为关键字。关键字不能作为变量或函数名来使用,用户只能根据系统的规定使用它们。根据ANSI标准,C语言可使用以下32个关键字:

auto   break   case   char   const   continue   default   do

double  else  enum  extern  float  for  goto  if

int  long  register  return  short  signed  sizeof  static

struct  switch  typedef  union  unsigned  void  volatile  while

②预定义标识符 所谓预定义标识符是指在C语言中预先定义并具有特定含义的标识符,如C语言提供的库函数的名字(如printf)和编译预处理命令(如define)等。C语言允许把这类标识符重新定义另作他用,但这将使这些标识符失去预先定义的原意。鉴于目前各种计算机系统的C语言都一致把这类标识符作为固定的库函数名或预编译处理中的专门命令使用,因此为了避免误解,建议用户不要把这些预定义标识符另作他用。

③用户标识符 由用户根据需要定义的标识符称为用户标识符,又称自定义标识符。用户标识符一般用来给变量、函数、数组等命名。程序中使用的用户标识符除要遵守标识符的命名规则外,还应注意做到“见名知义”,即选择具有一定含义的英文单词(或其缩写)作标识符,如day、month、year、total、sum等,为了增加程序的可读性,一般不要用代数符号,如a、b、c、x、y等做标识符(简单数值计算程序例外)。

如果用户标识符与关键字相同,则在对程序进行编译时系统将给出错信息;如果用户标识符与预定义标识符相同,系统并不报错,只是该预定义标识符将失去原有含义,代之以用户确认的含义,这样有可能会引发一些不必要的错误。习题

一、选择题

1.1 下列叙述中错误的是(  )。

A)C语言源程序经编译后生成后缀为.obj的目标程序

B)C程序经过编译、连接步骤之后才能形成一个真正可执行的二进制机器指令文件

C)用C语言编写的程序称为源程序,它以ASCII码形式存放在一个文本文件中

D)C语言中的每条可执行语句和非可执行语句最终都将被转换成二进制的机器指令

1.2 C语言源程序名的后缀是(  )。

A).exe

B).c

C).obj

D).cpp

1.3 计算机能够直接执行的程序是(  )。

A)源程序

B)目标程序

C)汇编程序

D)可执行程序

1.4 以下选项不合法的用户标识符是(  )。

A)abc.c

B)file

C)Main

D)PRINTF

1.5 下列叙述中错误的是(  )。

A)算法正确的程序最终一定会结束

B)算法正确的程序可以有零个输出

C)算法正确的程序可以有零个输入

D)算法正确的程序对于相同的输入一定有相同的结果

1.6 算法的有穷性是指(  )。

A)算法程序的运行时间是有限的

B)算法程序所处理的数据量是有限的

C)算法的长度是有限的

D)算法只能被有限的用户使用

二、填空题

1.7 在VC6.0环境中用RUN命令运行一个C程序时,这时所运行的程序的后缀是    。 

1.8 C语言源程序文件名的后缀是    ;经过编译后,生成文件的后缀是    ;经过连接后,生成文件的后缀是    。 

1.9 结构化程序由    、    、    三种基本结构组成。 第2章 数据类型、运算符与表达式2.1 C语言的数据类型

数据是计算机程序处理的所有信息的总称,数值、字符、文本等都是数据,而数据又是以某种特定形式存在的,不同的数据其存储形式是不一样的,例如,年龄19,那么19就是个整数,圆周率3.14159就是实数,英文的26个字母就是字符型数据等等。C语言提供了十分丰富的数据类型,每种数据类型是对一组变量的性质及作用在它们之上的操作的描述,它包括该数据在内存中的存储格式和该类型的数据能进行的运算。所谓数据类型是按被定义变量的性质、表示形式、占据存储空间的多少、构造特点来划分的,可以说一种语言的数据类型丰富与否是衡量这种语言是否强大的一个重要标准。在C语言中,数据类型可分为基本类型、构造类型、指针类型、空类型四大类,如图2.1所示。图2.1 C语言的数据类型

由图2.1可见,C语言的数据类型非常丰富,但无论使用哪种数据类型都必须先说明类型再使用。在本章中,我们先介绍基本类型(包括整型、实型和字符型等)和指针类型,其余类型在以后各章中陆续介绍。2.2 整型常量与变量2.2.1 常量与变量的概念

所谓常量是指在程序运行过程中其值不能改变的量。在C语言中常量分为:整型常量、实型常量、字符常量、字符串常量和符号常量。如:15是整型常量,3.14159是实型常量,'a'是字符常量,"abc123"是字符串常量,符号常量将在2.4节中介绍,前四种常量称为直接常量。

变量是指在程序运行过程中其值可以改变的量。如:y=2x+3中的x和y都可以看作是变量。变量实质上就是内存中的一个存储单元,在程序中对某个变量的操作实际上就是对这个存储单元的操作,在程序中使用变量要注意以下几个方面。

①用户定义的变量名字要符合标识符的命名规则;

②程序中的所有变量必须先定义后使用;

③变量定义的位置应该在函数体内的前部、复合语句的前部或函数的外部;

④在定义变量的同时要说明其类型,系统在编译时根据其类型为其分配相应的存储单元。

上述定义C语言变量时的注意事项恰恰符合我们做事的规律,就像如果要很好地完成一项任务我们要做许多准备工作一样,准备工作做得好,完成任务时就非常顺利!2.2.2 整型常量

整型常量即整数,按照不同的进制区分,整数有三种表示形式。

①十进制:以非0开始的数,数码取值范围是0~9,可以是正数、负数,如25、-36、+23等。

②八进制:以0开始的数,数码取值为0~7,如037、0123等。

③十六进制:以0x或0X开始的数,数码取值为0~9、A~F或a~f,如0x2a、0Xad、0x123等。

注意:在C语言中只有十进制可以是负数,八进制和十六进制只能是正数。

另外,可以在一个整型常数的后面添加一个L或l字母,来说明该数是长整型数,如25L、037l、0x3dl等。还可以在一个整型常数的后面添加一个U或u字母,来说明该数是无符号整型数,如25U、037u、0x3du等。2.2.3 整型变量(1)整型变量的分类

整型变量分为以下四种类型:

基本型:以int表示,在内存中占2个字节(在VC++环境下占4个字节)。

短整型:以short int或short表示,所占字节和取值范围均与基本型相同(在VC++环境下占2个字节)。

长整型:以long int或long表示,在内存中占4个字节。

无符号型:以unsigned表示。

无符号型又可与上述三种类型匹配而构成:

①无符号基本型:类型说明符为unsigned int或unsigned。

②无符号短整型:类型说明符为unsigned short。

③无符号长整型:类型说明符为unsigned long。

各种无符号类型量所占的内存空间字节数与相应的有符号类型量相同,但由于省去了符号位,故不能表示负数。如图2.2所示为整型数据在内存中的存放方式。图2.2 整型数据在内存中的存放方式

有符号短整型变量:能够存储的最大数值32767,最小数值-32768。

无符号短整型变量:能够存储的最大数值65535,最小数值0。

不同的编译系统或计算机系统对这几类整型数据所占用的字节数有不同的规定。表2.1列出了在VC++环境下各类整型变量所分配的内存字节数及数的表示范围。表2.1 在VC++中定义的整型变量所占的内存字节数和数的范围注:[ ]里的内容可以省略。

如果在定义整型变量时不指定(unsigned),则隐含为有符号(signed)。(2)整型变量的定义

变量定义的一般形式为:

变量的存储类别 变量的类型名,变量名的标识符,…;

例如:auto int a,b,c;        /*定义三个动态的整型变量*/static long x,y;        /*定义两个静态的长整型变量*/regisiter unsigned p,q;         /*定义两个寄存器型的无符号整型变量*/

在进行变量定义时,应注意以下几点:

①允许在一个类型说明符后,定义多个相同类型的变量。各变量名之间用逗号间隔。类型说明符与变量名之间至少用一个空格间隔。

②最后一个变量名之后必须以“;”号结尾。

③变量定义必须放在变量使用之前。一般放在函数体的开头部分、复合语句的开头部分或函数体外。

④“变量的存储类别”可以省略,当省略时默认的存储类别是auto型。【例2.1】  整型变量的定义与使用。#includevoid main(){ int x,y,z;         /*定义三个整型变量*/  x=3;         /*变量x的值为3*/  y=5;         /*变量y的值为5*/  z=(x+y)*10;         /*计算表达式的值,然后赋给变量z*/  printf("z=%d\n",z);         /*输出z的值*/}

运行结果:z=802.3 实型常量与变量2.3.1 实型常量

实型常量又称为实数或浮点数,一般用小数形式和指数形式来表示。实型常量分为以下两种形式:(1)小数形式

由数字、小数点以及正负号组成,如1.23、-23.46、0.0、.234、223.等都是合法的实数。(2)指数形式

在C语言中,用“e”或“E”后跟一个整数来表示以10为底的幂。如1.23e-2、345E+3、3.5e2等都是合法的指数形式,而e2、1.3E2.5、e、2e 、3.6 e-2等都是不合法的指数形式。

使用指数形式要注意以下两个方面:

①“e”或 “E”前后必须有数,并且“e”或 “E”的后面必须是整数。

②“e”或 “E”与其前后的数字之间不允许有空格存在。2.3.2 实型变量

实型数据与整型数据在内存中的存储方式不同,实型数据是按指数形式存放的,系统把一个实数分成小数和指数两个部分存放,指数部分采用规范化的指数形式,如-12.3456在内存中的存放形式如图2.3所示。图2.3 实型数据在内存中的存放形式

①小数部分占的位(bit)数愈多,数的有效数字愈多,精度愈高。

②指数部分占的位数愈多,则能表示的数值范围愈大。(1)实型变量的分类

实型变量分为以下三种类型:

①单精度浮点型:以float表示,在内存中占4个字节。

②双精度浮点型:以double表示,在内存中占8个字节。

③更高精度浮点型:以long double表示,在内存中占16个字节。表2.2列出了在VC++环境下各类实型量所分配的内存字节数及数的表示范围。表2.2 在VC++中定义的实型变量所占的内存字节数和数的范围

实型变量的存储单元是有限的,因此提供的有效数字是有限的,单精度实数只能保证7位有效数字,双精度实数只能保证15位有效数字,在有效位以外的数字是没有意义的,因此会产生一些误差。

例如:一个单精度型变量a等于12345.678,其有效数值是12345.67。

由于实数存在舍入误差,在使用时应注意:

①根据实际需要来选择单精度或双精度。

②避免用一个实数来准确表示一个大整数。

③由于实数在存储时会有一些误差,因此实数一般不能直接进行“相等”判断,而是进行“接近”或“近似”判断。

④由于在Turbo C或VC++环境下进行实数输出时限制了小数点后最多保留6位,因此在进行输出时有效数值范围内的其余部分要进行四舍五入。

⑤实型常数不分单、双精度,都按双精度double型处理。(2)实型变量的定义

变量定义的一般形式为:

变量的存储类别 变量的类型名,变量名的标识符,…;

例如:float a,b,c;        /*定义三个单精度型变量*/double x,y;        /*定义两个双精度型变量*/【例2.2】  实型变量的定义与使用。#includevoid main(){ float x,y;         /*定义两个单精度型变量*/  double z;         /*定义一个双精度型变量*/  x=12345.678;         /*变量x的值为12345.678*/  y=12345.673;         /*变量y的值为12345.673*/  z=12345.33333378999;         /*变量z的值为12345.33333378999*/  printf("x=%f\ny=%f\nz=%lf\n",x,y,z);   /*输出x,y,z的值*/ }

 运行结果: x=12345.677734 y=12345.672852 z=12345.3333342.4 字符型常量与变量2.4.1 字符常量(1)基本字符常量

字符常量是用单引号括起来的一个字符。

例如:'a'、'A'、'='、'+'、'1'

都是合法字符常量,注意'a'和'A'是不同的字符常量。

一个字符常量占一个字节的存储空间,在相应的存储单元中存放的是该字符的ASCII值,即一个整数值,因此在后续内容中将会看到,字符常量可以像整数一样参加数值运算。

例如'a'的ASCII值是97,在内存中的存储形式如下:

所以也可以把它们看成是整型量。C语言允许对整型变量赋以字符值,也允许对字符变量赋以整型值。在输出时,允许把字符变量按整型量输出,也允许把整型量按字符量输出。但由于整型量为2个字节或4个字节,字符量为单字节量,因此当整型量按字符型量处理时,只有数值的低八位参与处理。(2)转义字符常量

除了上述形式的字符常量以外,C语言还定义了一些特殊的字符常量是以“\”开头的字符序列,称为转义字符,转义字符是一种具有特殊的含义的字符常量,由于改变了字符的原有意义,故称“转义”,如“\n”中的n不代表字母n,而转义成“换行”符,常用的转义字符如表2.3所示。表2.3 常用的转义字符及其含义

广义地讲,C语言字符集中的任何一个字符均可用转义字符来表示。表中的\ddd和\xhh正是为此而提出的。ddd和hh分别为八进制和十六进制的数码。如'\101'表示字母'A','\141'表示字母'a','\134'表示反斜线,'\012'表示换行等。

注意:

①字符常量只能用单引号括起来,不能用双引号或其他符号。

②字符常量只能是单个字符,不能是字符串。

③字符可以是字符集中任意字符。但数字被定义为字符型之后就不能按原数值参与运算了,而是以其ASCII值参与运算。如'6'和6 是不同的。'6'是字符常量,而6是整型常量,参与算术运算时前者数值是54,后者是原值。【例2.3】  转义字符的使用。#includevoid main(){ printf("\'A\'的ASCII值是:%d\n",'\101'); }

 运行结果: 'A'的ASCII码值是:652.4.2 字符串常量

字符串常量使用英文双引号限定的字符序列,这个字符序列包括的字符个数称为字符串的长度,其长度允许为0,每个字符串在存储时都占用一段连续的存储单元,每个字符占用一个字节,系统自动在每个字符串的尾部附加一个结束标识符'\0',因此长度为n个字符的字符串常量在内存中要占用n+1个字节的空间,下列都是合法的字符串常量。"CHINA""12345""This is a C program!"" "       /*表示一个空格符*/""       /*表示什么字符也没有*/"\n"               /*表示一个转义字符换行*/"ab"

字符串常量"CHINA"在内存中的存储形式如下:

注意:字符常量'A'与字符串常量"A"在内存中的存储方式的不同。

说明:在C语言中,没有专门的字符串变量,字符串常量如果要存放在变量中,要用字符数组来处理。

字符常量与字符串常量的区别:

①定界符不同。字符常量使用单引号,而字符串常量使用双引号。

②长度不同。字符常量的长度固定为1,而字符串常量的长度可以为0,也可以是某个整数。

③存储要求不同。字符常量存储的是字符的ASCII码值,而字符串常量除了要存储字符串常量的有效字符外,还要存储一个字符串的结束标识符'\0'。2.4.3 符号常量

在程序设计中,有时需要多次用到某些常数,或者有些值在程序中特别关键,就可以将这些常量值定义为符号常量,这样在阅读和修改程序时就特别方便,C语言中定义符号常量的方法是在函数体外专门定义的,也只有在定义之后才能使用。定义符号常量的一般格式如下:#define 符号常量名 常量

例如:#define PI 3.14159

该命令定义了符号常量PI,它表示常数3.14159。

注意:PI是一个常量,其值是不能改变的。【例2.4】  符号常量的使用。#include#define PI 3.14159void main(){ float r,s,l;  r=3.6;  l=2*PI*r;  s=PI*r*r;printf("l=%f s=%f\n",l,s);}

输出结果:l=22.619448  s=40.715004

本例中在main()外部使用命令#define PI 3.14159定义了符号常量PI,它相当于常量3.14159,其值在函数体中不可以被改变。2.4.4 字符型变量(1)字符型变量分类

一个字符型变量只能存储一个字符,占用内存的一个字节,在这个位置存储的是该字符的ASCII码值,是一个8位二进制的整数,例如,当一个变量存储字符'A'时,实际上是存储了该字符的ASCII码值65,由于整数存在有符号和无符号之分,因此字符型变量分为有符号字符型变量和无符号字符型变量,分别用signed char和unsigned char来说明,通常只用char来说明字符型变量,它相当于signed char,即它将转换成有符号的整数,数值范围是-128~+127,而unsigned char型变量的数值范围是0~255。

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载