第1章C语言基础与顺序结构 通过本章的学习,应该掌握 (1) 合理选用数据类型 (2) 使用算术运算符和赋值运算符 (3) 控制数据的输入输出 (4) 使用顺序结构以及画顺序结构的流程图 (5) 使用Turbo C集成环境 (6) 单步执行程序的方法 (7) 转换大小写字母的方法 计算机由硬件系统和软件系统组成,其中硬件是物质基础,而软件是计算机的灵魂。没有软件的计算机是什么也干不了的“裸机”。所有软件要用计算机语言编写。 计算机语言是人和计算机交换信息的工具,随着计算机技术的发展,计算机语言逐步得到完善。最初使用的计算机语言是用一串串0和1表达的语言--机器语言,后来使用的计算机语言是用简洁的英文字母或符号串表达的语言--汇编语言。机器语言和汇编语言都是低级语言,用这种语言编写的程序执行效率高,但程序代码长,又都依赖于具体的计算机,因此编码、调试、阅读程序都很困难,通用性也差。 目前使用最广泛的计算机语言是用接近于人们自然语言表达的语言--高级语言。用高级语言编写的程序完全不依赖于计算机硬件,编码相对短,可读性强。C语言属于高级语言。用高级语言编写的程序叫做源程序。第1章 C语言基础与顺序结构C语言程序设计 1.1 认识C语言程序 1.1.1 了解C语言程序的构成 任何一个C语言程序都是由若干个函数构成的,所以编写一个程序的过程: 根据功能要求,按照C语言语法规则逐个编写各函数的过程。下面给出一个较完整的程序,以便读者尽早了解C语言程序。程序中的各行含义将在后续章节中详细介绍。 【实例1.1】 观察下面程序,认识一个完整的C语言程序,了解C语言程序结构。 / 下面3行是预处理命令部分 / #include #include #define PI 3.14159 / 下面两行是函数的原型说明部分 / float sup_area(float r); float volume(float r); / 下面是主函数部分 / main() { float a=-5,b,c,d; b=fabs(a); c=sup_area(b); d=volume(b); printf("c=%f,d=%f\\n",c,d); } / 下面是sup_area函数的定义部分,函数功能是计算球的表面积 / float sup_area(float r) { float s; s=4PIrr; return s; } / 下面是volume函数的定义部分,函数功能是计算球的体积 / float volume (float r) { float v; v=4.0/3.0PIrrr; return v; } 1. 运行结果 c=314.158997,d=523.5983282. 归纳分析 (1) 任何一个C语言程序都是由若干个函数构成的,而且必须有且仅有一个主函数(函数名必须是main) ,其他函数的多少根据实际情况决定,处理简单问题时也可以没有其他函数。本程序包括主函数、sup_area函数和volume函数。 (2) 程序中多处用“/ /”括起来,此部分叫做注释部分。注释部分对程序的运行不起作用。在程序中加注释仅是为了便于阅读。 (3) C语言提供丰富的标准库函数供我们直接使用,但要求在程序的开头加上包含该函数信息的命令行。本程序中使用了库函数printf(功能是输出数据,是输出函数)和fabs(功能是求绝对值,是数学函数). C语言系统将所有输入输出函数的信息存放在“stdio.h”文件中,而将所有数学函数的信息存放在“math.h”文件中,所以程序的开头加了两个命令行“#include ”和“#include " . (4) 程序的开头除了上述两个命令行外,又有了命令行“#define PI 3.14159" 。有此命令行后,程序中用到的所有PI均用3.14159代替。 (5) 程序中编写了3个函数,除了主函数外,在使用其他自定义的函数前,应对这些函数逐一进行函数原型说明。因此程序中加了“float sup_area(float r);”和“float volume(float r);" . 1.1.2 熟悉主函数框架 在C语言中可以编写程序进行算术运算,就像日常生活中人们使用计算器计算一样。 【实例1.2】 编写程序,计算两个数的和与差,要求从键盘输入两个数。1. 编程思路 在C语言中,数据的输入操作使用标准库函数scanf实现,而通过标准库函数printf实现输出功能。加法操作和减法操作分别使用算术运算符“+”和“-" . 2. 程序代码 #include main() { int x,y,a; / 定义3个变量 / printf("Input x and y:"); / 显示提示信息 / scanf("%d%d",&x,&y); / 要求从键盘输入两个整数 / a=x+y; / 计算两个数的和 / printf("The sum of the two numbers:%d\\n",a); / 输出两个数的和 / a=x-y; / 计算两个数的差 / printf("The difference:%d\\n",a); / 输出两个数的差 / } 3. 运行结果 Input x and y:1200 180<回车> The sum of the two numbers:1380 The difference:1020说明: 本书将用户输入的内容均用下划线标出。4. 归纳分析 (1) 本程序只包含主函数,主函数的一般框架是: main() { 定义变量部分 功能语句部分 } 定义变量部分和功能语句部分均可以是多条语句,而且每条语句都以“;”结束。 (2) 在屏幕上显示内容要使用printf函数。此函数有两种形式。参见实例1.8. 语句“printf("Input x and y:");”的功能是屏幕上显示字符串“Input x and y:" ,而语句“printf("The sum of the two numbers:%d\\n",a);”的功能是在显示双引号中字符的同时, "%d”的位置上用a的值替换。 "%d”是格式说明符,在输出整数时使用, "\\n”是换行符。 (3) 从键盘输入数据要使用scanf函数。参见实例1.8. 语句“scanf("%d%d",&x,&y);”的功能是要求用户从键盘输入两个整数,并把它们分别存放在变量x和y中。在输入整数时也要使用格式说明符“%d" . (4) 编写程序后应上机验证。读者可以按照如下顺序尝试上机,更详细的上机方法将在1.6节中介绍。 ① 启动Turbo C 2.0集成环境。 在资源管理器中双击TC.EXE文件,即可启动如图1.1所示的Turbo C 2.0集成环境。图1.1 Turbo C 2.0集成环境 ② 在编辑区中输入本题目中的程序代码。 ③ 按Ctrl+F9组合键运行程序。 如果输入程序有错误,将出现错误信息。例如,输入程序时将“int x,y,a;”误输入成“int x,y,a" ,则出现如图1.2所示的错误信息。这时应修改程序后再重新运行。 图1.2 运行程序时显示的错误信息 如果程序没有错误,出现如图1.3所示的DOS屏幕,并要求用户输入x和y的值。输入1200和180后按回车键,又回到Turbo C集成环境。实际上这时已经运行完毕。 图1.3 DOS屏幕 ④ 查看运行结果。按Alt+F5组合键可以切换到DOS屏幕,并可以查看运行结果,如图1.4所示。按任何键可从回到Turbo C集成环境。 图1.4 程序的运行情况 1.2 合理选用数据类型 在编写C语言程序时,需要处理大量的数据,其中最常用的数据包括整型、实型、字符型,而常用的整型又有基本整型和长整型;常用的实型有单精度实型和双精度实型。不同类型的数据有不同的特性和处理方法,因此编写程序时合理选用相应的数据类型是至关重要的。 基本整型、长整型、单精度实型、双精度实型和字符型是C语言的基本数据类型,其主要特性如表1.1所示。表1.1 基本数据类型的主要特性数据类型类型名所占字节数数据取值范围有效数位格式说明符基本整型 int2-32768~32767%d长整型 long4-2147483648~2147483647%ld单精度实型float4-10-38~10386~7%f双精度实型double8-10-308~1030815~16%lf字符型 char1%c1.2.1 合理选用整型数据 在日常生活中我们经常需要处理整数,即不带小数点的数。例如,计算某人的年龄、统计学生人数等。在C语言中,常用int型或long型变量存放整型数据。 【实例1.3】 编写程序,计算两个正方形铁板的面积,铁板边长分别为150cm和200cm,如图1.5所示。图1.5 两个正方形铁板1. 编程思路 利用公式“面积=边长×边长”计算正方形的面积,而且定义两个变量area1和area2,分别存放两个正方形的面积。由于需要处理的数据是整数,应从int型和long型中选用。根据int型和long型数据的取值范围(参见表1.1) ,变量area1选用int型,变量area2选用long型,因为变量area1中将要存放22500,而变量area2中将要存放40000. 2. 程序代码 #include main() { int area1; / 定义基本整型变量area1 / long area2; / 定义长整型变量area2 / area1=150; / 把150赋给变量area1 / area2=200; / 把200赋给变量area2 / area1=area1area1; / 计算小正方形的面积 / area2=area2area2; / 计算大正方形的面积 / printf("area1=%d,area2=%ld\\n",area1,area2); / 输出两个正方形的面积 / } 3. 运行结果 area1=22500,area2=400004. 归纳分析 (1) 程序中使用了变量area1和area2,所谓变量就是在程序执行过程中其值可以变化的量。C语言将数据分为常量和变量,常量是在程序执行过程中其值永远不变的量。变量的实质是内存中的一个存储单元,因此在使用变量前应向系统申请存储单元,这一过程就是定义变量的过程。本程序分别用“int area1;”和“long area2;”定义了变量area1和area2. 定义变量的一般形式是: 类型名 变量名1, 变量名2, …, 变量名n; 变量名由编程者自己给出,但必须遵循如下变量名的命名规则。 ① 变量名中只能出现数字、大写英文字母、小写英文字母和下划线。 ② 变量名必须以字母或下划线开头。 ③ 变量名与关键字不能相同。 ④ 不提倡使用预定义符。 C语言区分大小写英文字母,所以变量a和A是两个不同的变量。所谓关键字是C语言中已有特定用途的标识符(参见附录A) ,如int、long等。预定义符有: 库函数名(如printf) 、预编译处理命令(如include、define)等。如果把预定义符作为变量名,则该预定义符将失去原有的含义。注意变量必须先定义后使用,定义变量后其中的值是不确定的。 变量如同容器,其中可以存放数据,也可以从中取出数据使用。例如,用“int area1;”定义变量area1后,变量area1中的值是不确定的,但执行“area1=150;”后,area1中的值变为150,再执行“area1=area1area1;”后,area1中的值又变为22500,如图1.6所示。 图16 变量areal的值变化情况 编写程序时经常使用形如“area1=area1area1;”的语句,其特点是运算符“=”两侧均出现相同的变量名。但两侧的变量名所代表的含义是不同的。例如,该语句中,运算符“=”右侧的area1代表变量area1中的值(即150) ,而左侧的area1代表存储单元。该语句的执行过程是先计算area1area1的值(即150×150) ,再把计算结果(即22500)存放在运算符“=”左侧的area1中。在C语言中“=”是赋值运算符,参见1.3.2小节。 (2) 对于整型数据,根据变量中要存放的数据大小和数据类型的取值范围选用数据类型。如果在1个变量中需要多次赋值,那么要保证其中将存放的最大数不超过该类型的取值范围。例如,变量area2中先后存放200和40000,由于其中最大数40000超过int型的取值范围(-32768~32767) ,因此不能选用int型,而选用long型。 (3) 输出基本整型数据时在printf函数中要使用格式说明符“%d" ,而输出长整型数据时使用“%ld" . 【讨论题1.1】 在实例1.3的程序中能否将变量area1定义为long型?该程序为什么没有选用long型而选用int型? 1.2.2 合理选用实型数据 在日常生活中我们也经常需要处理实型数。例如,计算学生的平均成绩,统计1年的销售额等。在C语言中,常用float型或double型变量存放实型数据。 【实例1.4】 编写程序,计算半径为15.67cm的圆面积。要求分别使用单精度型和双精度型数据计算。1. 编程思路 通过求圆面积公式πr2计算。单精度实型变量用float定义,而双精度实型变量用double定义。2. 程序代码 #define PI 3.14159 / 程序中的所有PI均用3.14159代替 / main() { float s1; double s2; s1=PI15.6715.67; s2=PI15.6715.67; printf("s1=%f,s2=%lf\\n",s1,s2); } 3. 运行结果 s1=771.413940,s2=771.4139694. 归纳分析 (1) 在存储整型数据时没有误差,但存储实型数据时就有误差。例如,通过“a=5;”将5赋给整型变量a后,a中存放的就是5,但通过“b=345.6789;”将345.6789赋给单精度实型变量b后,b中存放的值不是345.6789,而是带误差的值(如345678894) 。单精度实型数据的有效位是6~7位,即只保证前6~7位是正确的,而双精度实型数据的有效位是15~16位,它能够保证前15~16位是正确的。从本程序的运行结果中也可以观察。 (2) 在基本整型、长整型、单精度实型和双精度实型中,通常按如下原则选择使用具体数据类型。即 ① 当要处理-32768~32767之间的整数时,选用基本整型(int)或长整型(long) 。选用长整型会浪费存储单元,因为长整型占4个字节,基本整型只占2个字节。 ② 当要处理-2147483648~2147483647之间的整数时,选用长整型。 ③ 当要处理-10-38 ~1038之间的实数时,选用单精度实型(float)或双精度实型(double) 。选用双精度实型会浪费存储单元,因为双精度实型占8个字节,单精度实型只占4个字节。 ④ 当要处理-10-308 ~10308之间的实数时,选用双精度实型。 ⑤ 当要处理的整数超出长整型数据范围时,选用单精度实型或双精度实型。 ⑥ 当要处理的实型数据精度要求高时,选用双精度实型。注意在整型变量中不能存放实型数。若有“int a; a=3.6;" ,则执行后a中存放的值是3,而不是3.6. (3) 输出单精度实型数据时在printf函数中要使用格式说明符“%f" ,而输出双精度实型数据时使用“%lf" 。用“%f”或“%lf”输出数据时,小数点后总是输出6位,若改用“%.3f”或“%.3lf”形式,则小数点后只输出3位,若用“%.0f”或“%.0lf”形式,则不输出小数点后的数据。 1.2.3 合理选用字符型数据 在日常生活中经常遇到一串串字符,如姓名、性别、通信地址等,在C语言中也同样需要处理大量的字符数据,例如,打字练习时计算正确率、连接两篇文章等。单个字符(即字符常量)要用char型变量存放。在程序中将字符常量用单引号括起来,如'a'、'B'等。字符常量可以是ASCII码表(参见附录B)中的任意一个字符,它在内存中占1个字节。 【实例1.5】 假设变量ch中已存放字母'H',编写程序,将ch中的字母转换成小写字母后重新存放在该变量中。1. 编程思路 要处理字符,必须使用字符型类型,用char定义字符型变量。通过'H'+32可以得到字母'H'所对应的小写字母。2. 程序代码 #include main() { char ch; ch='H'; ch=ch+32; printf("ch=%d,ch=%c\\n",ch,ch); } 3. 运行结果 ch=104,ch=h4. 归纳分析 (1) 字符常量在内存中存放的是其ASCII码值,所以像整型数据一样可以直接参与算术运算。如大写字母'H'在内存中存放的是其ASCII码值72,因此'H'+32的值是104,即为小写字母'h'的ASCII码值。实际上,所有大写字母和对应小写字母的ASCII码值都相差32. (2) 按字符形式输出字符型数据时,在printf函数中要使用格式说明符“%c" ,输出字符时不输出单引号。 (3) 字符常量除了单个字符外还有以反斜杠“\\”开头,后跟一个或几个字符组成的转义字符。在表1.2中列出了常用的转义字符。 虽然转义字符书写形式较复杂,但它可以表示键盘上找不到的字符,如“" 、 "”等。用语句“printf("%c%c\\n",'\\17','\\xE');”可以输出“”和“" . 表1.2 常用转义字符转义字符转义字符的意义转义字符转义字符的意义\n 回车换行 \\ 反斜线符"\"\t 横向跳到下一制表位置 \' 单引号字符“'" \v 竖向跳格 \" 双引号字符“"" \b 退格 \a 鸣铃\r 回车 \ddd 1~3位八进制数所代表的字符\f 走纸换页 \xhh 1~2位十六进制数所代表的字符 【讨论题1.2】 执行语句“ch='b'-32;”后,字符型变量ch中存放的是什么?再执行“ch=ch+2”后,变量ch中存放的又是什么? 1.3 学会使用常用运算符 1.3.1 学会使用算术运算符 在日常生活中离不开算术运算。如购物交费时,根据各物品的价格计算总额;再如用饭卡买饭时根据饭菜的价格从卡中扣钱。用C语言编写程序解决这类问题时,同样也离不开算术运算。 【实例1.6】 编写程序,计算函数y=x+2xx-5的值,其中自变量x的值从键盘输入。1. 编程思路 先根据数学表达式x+2xx-5写出C语言表达式。用sqrt函数计算平方根,2x写成2x, 分子和分母分别用“()”括起来。C语言不提供与数学对应的“\”和“{}" ,所以需要时使用嵌套的“()" . 2. 程序代码 #include #include main() { float x,y; printf("Input x:"); scanf("%f",&x); y=(sqrt(x)+2x)/(x-5); printf("x=%f,y=%f\\n",x,y); } 3. 运行结果 Input x:7<回车> x=7.000000,y=8.3228764. 归纳分析 (1) C语言中有5个算术运算符: "+" (加)、 "-" (减)、 "" (乘)、 "/" (除)、 "%" (求余)。运算符“%”要求两侧的运算量必须为整型。 (2) 一个表达式中一般包括多个运算符,所以计算表达式的值时要考虑运算符的先后顺序。确定先后顺序的原则是先按运算符的优先级,对于相同优先级的运算符再根据其结合性确定。参见附录C. 图1.7 统一类型的原则 (3) 在进行算术运算时,经常会遇到运算量的数据类型不一致,这时系统自动将数据类型统一后才进行运算。对于int型、long型、float型、double型和char型,统一类型的原则如图1.7所示。 ① 对于int型、long型或double型,如果运算量的数据类型相同,则系统不进行统一,而直接运算,所得到的结果类型是该数据类型。例如,两个int型的计算结果还是int型。如果运算量的数据类型不同,则系统将其中低级的数据类型统一到高级类型,然后再运算,所得到的结果类型是高级别的类型。例如,对于1个int型和1个double型的运算量进行算术运算时,先将运算量统一成double型,计算结果是double型。 ② 如果有一个运算量是char型,则必须先统一成int型,再按int型的统一原则进行。如果有一个运算量是float型,则必须先统一成double型。 (4) 有时可以采用强制类型转换的方法将运算量的数据类型统一。例如,在计算32767与2的和时,如果直接用表达式32767+2计算,将得到错误的结果-32767(因为超范围,产生数据溢出现象),因此采用表达式(long)32767+2计算,其结果正是预期的数32769。在这里,(long)的作用是把其后的运算量32767的数据类型强行转换为long型,所以在进行加2的操作时,将运算量统一成long型计算,不会出现数据溢出现象。强制类型转换的一般形式是 (类型名)运算量 (5) 编写程序时应考虑程序的健壮性,即当用户输入非法数据时应给出错误信息,使得系统不导致崩溃。由于所学知识的限制,本程序没能考虑健壮性,因此输入负数或5时出现如下错误。 输入负数时: Input x:-3<回车> sqrt: DOMAIN error x=-3.000000,y=0.750000 输入5时: Input x:5<回车> Floating point error: Divide by 0. 通过第2章的学习可以完善本程序。 【讨论题1.3】 进行算术运算时,如果一个运算量是int型,另一个是float型,那么系统应如何统一类型? 1.3.2 学会使用赋值运算符 就像容器中装东西一样,C语言中也经常将数据赋值给变量,这一操作借助赋值运算符“=”实现。 【实例1.7】 假设A、B两个职员的原来工资都是1860.50元,后来经考验决定给A职员加200元,B职员加500元。编写程序,计算两个职员的新工资。1. 编程思路 先定义两个单精度型变量a和b,分别存放原来的工资,再通过它们计算新的工资。2. 程序代码 #include main() { float pay_a,pay_b; pay_a=pay_b=1860.50; pay_a=pay_a+200; pay_b=pay_b+500; printf("pay_a=%.2f,pay_b=%.2f\\n",pay_a,pay_b); / 小数点后输出2位 / } 3. 运行结果 pay_a=2060.50,pay_b=2360.504. 归纳分析 (1) 赋值表达式的一般形式是 变量名=表达式 (2) 赋值表达式的处理过程分3步: ① 计算赋值号“=”右侧表达式的值。 ② 自动将表达式的值数据类型统一成“=”左侧变量的数据类型。 ③ 将所得结果赋给“=”左侧的变量。 如果“=”左侧变量的数据类型不得当,则在系统把表达式的值类型统一成“=”左侧变量的类型时,可能得不到正确的结果。例如,执行“int a; a=32768+1;”后,表达式32768+1的值是32769,但变量a得到的结果却是-32767。这是因为32769超出基本整型变量存放数的范围,出现了数据溢出现象。再如,执行“int f; f=15.67;”后,变量f得到的值是15,而不是15.67,这是因为将实型数据转换成int型的方法是舍去小数点部分。 (3) 赋值表达式的值是“=”左侧变量所得到的值。在1个赋值表达式中,如果出现多个赋值运算符,则从最右侧开始一一处理。例如,本程序中赋值表达式“pay_a=pay_b=1860.50”相当于“pay_a=(pay_b=1860.50)" ,而赋值表达式“pay_b=1860.50”的值为变量pay_b所得到的值1860.50,因此变量pay_a也得到1860.50. 1.4 学会控制输入输出数据 没有输出操作的程序毫无价值,所以任何一个程序都应至少有一个输出操作。没有输入操作的程序缺乏灵活性,因此一般每一个程序都有输入操作。 1.4.1 格式输入输出函数的使用 利用前面接触过的scanf和printf函数可以按指定的格式输入输出数据。 【实例1.8】 编写程序,给小学生出1道100以内2个数的加法题,等学生说出自己的答案后,再告诉学生正确的答案。1. 编程思路 先随机产生2个100以内的整数,再用printf函数给出算术式,用scanf函数使学生输入答案。随机产生1个整数可用标准库函数random ()或rand () . random(n)产生1个0~n-1的随机整数,rand()产生0~32767的随机整数,所以random(100)或rand()%100均能产生1个100以内的随机整数。2. 程序代码 #include #include / 使用随机函数时加此行 / main() { int op1,op2,pupil,answer; op1=random(100); / 产生0~99之间的数 / op2=random(100); printf("%d+%d=",op1,op2); / 显示算式 / scanf("%d",&pupil); answer=op1+op2; printf("The correct answer:%d\\n",answer); } 3. 运行结果 46+30=66<回车> The correct answer:764. 归纳分析 (1) 由scanf函数构成的输入语句一般形式是: scanf("格式控制字符串",输入项表); 由printf函数构成的输出语句一般形式有两种: 形式1: printf("字符串"); 形式2: printf("格式控制字符串",输出项表); 输入项表和输出项表中的各项用逗号隔开。输出项是表达式(含常量和变量),而输入项是变量的地址(用“&变量名”形式表示,有关地址的概念将在第5章介绍). 如果输入多个数值时使用1个scanf函数,则在各数值之间要用空格键或Tab键或回车符分隔。如执行“scanf("%d%d",&a,&b);”时,用“56”或“5回车6”等形式。但是如果输入多个字符时使用1个scanf函数,则在字符之间不加分隔符,而连续输入,因为系统把空格、回车符等都作为合法的字符。如执行“scanf("%c%c",&ch1,&ch2);”时,用we<回车>输入才能使ch1得到“w" , ch2得到“e" ,如果输入成we<回车>,则ch2得到“" . 用于输入输出的常用格式说明符相同。 (2) 使用random或rand函数时,在程序的开头需要加上命令行“#include " . (3) 多次运行本程序可以看到,每次给学生出的算术题是一样的,为了每次出不同的题目,产生数之前加语句“randomize();" ,而且在程序的开头加命令行“#include" . 1.4.2 单个字符输入输出函数的使用 输入输出单个字符,除了可以用scanf和printf函数外,还可以使用getchar和putchar等函数。 【实例1.9】 编写程序,根据输入的一个字母,计算下一个字母并输出。1. 编程思路 用getchar函数可以给某变量输入1个字符,对字符加1得到其下一个字符。输出1个字符用putchar函数。2. 程序代码 #include main() { char ch; ch=getchar(); ch=ch+1; putchar(ch); putchar('\\n'); } 3. 运行结果 B<回车> C4. 归纳分析 (1) getchar函数一般采用如下形式使用: 变量名=getchar(); 其作用是将键盘输入的1个字符赋给“=”左侧变量。 putchar函数一般采用如下形式使用: putchar(变量名或1个字符); 如putchar(ch)、putchar('\\n'),其作用分别是输出变量ch中的字符和换行符。 (2) 语句“ch=getchar();”等价于“scanf("%c",&ch);" ,而语句“putchar(ch); putchar('\\n');”等价于“printf("%c\\n",ch);" . 1.5 画顺序结构的流程图 本章中介绍的所有程序有一个共同特点,那就是程序中的所有语句都从上到下逐条执行,这样的程序结构叫做顺序结构。 图1.8 实例1.10的流程图 【实例1.10】 画出实例1.9中程序的流程图。1. 画流程图的方法 合理选用流程图符号(参见表1.3),每个框要用连接线连接。2. 流程图 流程图如图1.8所示。3. 归纳分析 (1) 流程图是描述问题处理步骤的一种常用的图形工具,它由一些框和流程线组成。用流程图描述问题的处理步骤,形象直观、便于阅读。 (2) 画流程图时必须按照功能使用相应的流程图符号,流程图符号如表1.3所示。表1.3 流程图符号符 号 名 称符 号使 用 场 合起止框 用于开始和结束处 输入输出框用于输入和输出语句处理框 用于各种处理 判断框 用于判断条件 流程线 用于执行方向 连接点 用于流程图的延续 (3) 结构化程序设计有3种基本结构,即顺序结构、分支结构和循环结构。用这3种基本结构可以编写各种复杂程序。在第2章和第3章分别介绍分支结构和循环结构。 1.6 熟悉Turbo C集成环境 1.6.1 在Turbo C集成环境中验证程序的正确性 【实例1.11】 在Turbo C集成环境中验证如下程序的正确性,该程序的功能是计算长方体的体积。 #include main() { int a,b,c; long v; scanf("%d%d%d",&a,&b,&c); v=abc; printf("v=%ld\\n",v); } 1. 启动Turbo C 2.0集成环境 如果已安装Turbo C 2.0集成环境,则在资源管理器中直接双击TC.EXE文件,如果没有安装该环境,将Turbo C 2.0直接复制到C盘TC文件夹中。Turbo C 2.0集成环境是编辑、编译、连接、调试为一体的简单又实用的开发环境。Turbo C 2.0集成环境如图1.1所示。2. 编辑程序 在编辑区中输入本程序。编辑源程序时,经常使用如表1.4所示的快捷键和块操作命令。表1.4 快捷键和块操作命令命 令功 能说 明F2保存程序F6切换开关编辑区和信息区之间的切换F9编译连接Ctrl+F9运行程序F10激活菜单Alt+F5查看结果等价操作是【Run】|【User Screen】Alt+X退出TC等价操作是【File】|【Quit】Ctrl+KB定义块首Ctrl+KK定义块尾Ctrl+KV移动块 一定先把光标移动到需要块移动的位置Ctrl+KC复制块 一定先把光标移动到需要块复制的位置Ctrl+KY删除块 Ctrl+KH取消块 3. 保存程序 按F2键或选择【File】|【Save】命令出现对话框,其中输入d:\\C_Tan\\1_11<回车>,即可在d盘C_Tan文件夹中保存程序,文件名为1_11,默认的扩展名为“.c" 。用【File】|【Write To】命令可更改文件名或路径。4. 编译和连接程序 按F9键进行编译和连接操作。由于计算机只能识别0和1,因此源程序必须通过编译和连接后,才能被计算机执行。编译是将程序翻译成目标程序的过程,连接是将用户编写的程序和系统提供的库函数等连接起来产生可执行文件的过程。如果编译或连接时有警告错误或语法错误,则在信息区中会显示出来,参见图1.2。这时应修改错误后重新进行编译和连接。5. 运行程序 按Ctrl+F9组合键运行程序。运行程序时也有可能出现错误,这时应修改后再进行编译和连接。我们在验证实例1.2中程序时直接按Ctrl+F9键运行了程序,实际上此组合键的功能是一次性地进行编译、连接和运行,但不提倡跳过按F9键编译和连接的过程,因为直接按Ctrl+F9键运行时只能发现语法错误,不能发现警告错误。 运行程序时请输入30 50 80<回车>。预期的结果是v=120000. 6. 查看运行结果并分析 运行结果在DOS屏幕上观察,按Alt+F5组合键或选择【Run】|【User Screen】命令可以看到DOS屏幕。从结果中看到运行结果(v=-11072)与预期的结果(v=120000)不符。因此需要分析,查找原因,修改程序,然后重复修改、编译、连接和运行,直到得出正确的结果为止。 本程序中出现了易犯但难以检查出的错误。执行语句“v=abc;”时,由于a、b和c都是int型,所以计算abc的值时也按int型计算,但计算结果120000超出int型的范围,产生了数据溢出现象。解决的方法是将语句改为“v=(long)abc;" ,这样可以保证按long型计算。 按任何键回到Turbo C集成环境。7. 退出Turbo C集成环境 按Alt+X键或选择【File】|【Quit】命令退出Turbo C集成环境。8. 归纳分析 要得到C程序的运行结果,首先选择一种集成环境,将源程序输入计算机内,然后把源程序翻译成机器能识别的目标程序,再把目标程序和系统提供的库函数等连接起来产生可执行文件,这时才可以运行程序。C程序的编辑、编译、连接、运行过程如图1.9所示。 图1.9 C程序的编辑、编译、连接、运行过程 C程序的编辑、编译、连接、运行过程可以在不同的环境中进行,而本书选用的是Turbo C 2.0集成环境。 1.6.2 在Turbo C环境中观察程序的单步执行过程 【实例1.12】 用单步执行的方法一步一步观察实例1.11中每一条语句的执行过程。1. 打开文件 在Turbo C环境中选择【File】|【Load】命令打开d盘C_Tan文件夹中1_11.c文件。2. 单步执行 按F8键单步执行程序。通过单步执行可以观察每行的执行情况。按一次F8键,出现如图1.10所示的界面。 图1.10 单步执行开始 绿色条所在的行是将要执行的行。按两次F8键,要求用户输入3个数,输入后绿色条停留在语句“v=abc;”上。按3次Ctrl+F7键分别在信息区中添加监视项a、b和c,如图1.11所示。通过【Break/watch】|【Remove all watches】命令删除所有监视项。 图1.11 设置、观察和删除监视项 再按两次F8键,将程序单步执行完毕。3. 归纳分析 当程序的运行结果与预期的结果不符,而且其错误原因不易检查时,常使用单步执行的方法。在单步执行的过程中,可随时观察变量或表达式的值,也可以删除监视项,如图1.3所示。 1.7 贯穿教学全过程的实例--公交一卡通 管理程序总功能 本书分8次介绍公交一卡通管理程序,其目的是通过较大的实例使学习者尽早了解编写应用程序的过程,逐步掌握设计算法的方法。 公交一卡通管理程序是用来模拟实现公交系统一卡通的部分功能。基本功能有添加新卡、注销旧卡、修改卡内的信息、坐车读卡、续钱、显示所有卡的信息、找出续钱最多的用户、删除一卡通的系统数据文件等。每张卡的基本信息包括卡号、用户姓名、卡内所续金额、卡内余额、卡是否被注销的标记。各功能的具体描述如下: