《新概念c语言案例教程__何勤.docx》由会员分享,可在线阅读,更多相关《新概念c语言案例教程__何勤.docx(199页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、新概念C程序设计教程上册版权所有第一章C语言的基本概念1. 1 c语言程序的构成成分:例题1.11) ttinclude /编译预处理命令,将标准输入输出函数2)作为头文件包扩到用户源程序文件中/3) include /编译预处理命令,将系统提供的数学函数4) 作为头文件包扩到用户源文件中/5) int main() 函数名为main的主函数的函数首部6) 函数体开始7) float x , y :定义部分.定义变量及其类型8) x=45.2;语句部分.赋值语句9) y=sqrt (3*x+5. 6);语句部分.赋值语句10) printf( fn” , y ); 语句部分.输出语句11) r
2、eturn 0J/语句部分.返回语句12) 函数体结束注意:最左边的行号是为了说明方便而加上的,实际C语言程序中是不能有的。1. C语言的源程序的主要构成成分是函数定义(从第5到第12行)。个C语言源程序文 件一般由多个函数定义顺序组成(直到第5章讨论由两个以上函数构成的C语言源程 序),但是其中必须有一个main函数。程序的运行都是从系统调用main函数开始的。2. 函数定义由函数首部(第5行)和函数体(第6到第12行)组成。函数体必须用大括号 “和“”括住。3. C语言源程序的次要构成成分是:编译预处理命令(第1、3两行的左边部分)、注释(每 一行右半部以开始的内容,或以/开始,以/结束的
3、内容)和声明(见第5章)。编译预 处理命令和注释是不以分号结束的。4. C语言程序中,(任何函数的)函数体的主要构成成分是:定义序列(第7行的左半部) 和语句序列(第8行到第11行的左半部)。这两种成分都要以分号结束(复合语句除外)。 C语言函数体中,所有定义必须位于语句序列之前(注)。注:这是C89标准,其它高级编程语言不一定有此先后顺序要求。C99标准放宽了要求, 可以在复合语句的前半部定义仅在复合语句中有效的局部变量,但目前不少编译器并不支持 C99标准。所以,为了获得较好的程序可移植性,本书的论述以较老的C89标准为主。深入步:定义序列被编译程序翻译成了内存中的数据序列(包括对存放数据
4、的内存空间的事先 安排),而语句序列则被翻译成了指示如何加工这些数据序列的机器语言的指令序列。将 要运行的程序的指令序列也是位于内存中的。所以在运行某个程序前,程序用户必须借助 于操作系统将位于外存文件中的这两部分内容加载到内存中。*5.在正式进行编译之前,编译预处理程序将根据源程序中的编译预处理命令対源程序文件 进行一些辅助性的文本插入(include命令)、替换(#define命令)和编辑工作。编译预处 理命令都是以“#”开始,不以分号结束。每条编译预处理命令必须书写在同一行上。6.注释以“/*”开始,以“”结束。注释会被编译程序首先删除掉。但良好的注释使程 序更易被人们读懂。不要忘记书写
5、注释的结束符号“*/ 。注释有两种常用方式:一种是 注释内容独自占据多行,对注释以下的一段程序或整个源程序文件进行说明;另一种是出现 在一行的右边,对该行左边的内容进行说明。(注释部分在VC+6.0中是以绿色字体显示出 来的。)单行注释以“ ”开始,它用起来比较方便,但它不是C语言标准规定的。1. 2 C语言程序的语法要素1 .正文部分:除了格式控制串(见1.4节printf()和scanf()函数)和注释部分以外的C语 言源程序的其它部分,称为C语言的源程序的正文部分。(正文部分在VC+6.0中是以黑色 字体显示出来的。)2. C语言的字符集,26个大小写英文字母:AZ, az;阿拉伯数字字
6、符:9;特殊字符:!#%,&*_ + = 丨/:., ()?:空格字符(对应键盘上的最长键Space) 换行符(对应 Enter键) 制表符(对应Tab键)以上所有这些字符构成了 C语言的字符集。书写C语言的源程序的正文部分,只能使 用C语言字符集中的字符,其它任何字符不得使用。字符集中的任何字符,只能用英文半 角方式来进行输入。3. 标识符是以26个大小写英文字母、阿拉伯数字。到9和下划线构成的字符序列;其中从 左边开始的第一个字符不能是数字。在C语言中,只能使用符合标识符规定的名字,来对 变量、符号常量、函数、语句标号命名。C语言对标识符的大小写敏感,也就是说main与 Main, pri
7、ntf与Printf都是不同的标识符(main和printf都是C语言中的已经规定的函数名, 所以,我们不能用来作为自定义的标识符)。4. 关键字是被编译程序保留下来的特殊标识符;主要分为两大类:用于定义(或声明)的 关键字和用于构成语句的关键字。(C89标准中的)关键字都是由小写英文字母组成的。关 键字(还包括预处理明令)在VC+6.0中是以蓝色字体显示出来的。所有关键字列表如下:在ANSI C89标准中共有32个关键字auto break case char const continue default do double else enum extxrn float for goto i
8、f int long register return short signed sizeof static struct switch typedef union unsigned void volatile while在ANSI C99标准中增加了 5个关键字Bool _Complex _Imaginary inline restrict5. C语言源程序中可使用的分隔符有三个:空格、回车/换行、逗号。同类项之间要用逗号 分隔,关键字和标识符之间要用空格或回车/换行来分隔,不能用逗号(比如int m,n;)。 在C语言中,合理地使用多余的空格和空行,可以使得程序更清晰、易懂、优美。6. C语
9、言中常量分为数值常量(又称为字面常量)和符号常量两种。应当多使用符号常量, 尽量少用数值常量。最常用的数值常量有以下儿种:1),整型常量 567, -425 , 0 等,是没有小数分量的数值。2).实型(浮点型)常量:由正负号、数字、小数点构成。0.543、543.、543.0、0.0都是十进制的小数形式。在 数的左边还可以加上正负号。比如543.0。3),字符型常量匕,K 85 , n,等,是用单引号括起来的ASCH码表中的字 符,包括键盘上的可显示(或可打印)的字符和不可显示的些控制字符(字符n就是表 示个控制字符Enter键,详见附录ASCH码表)。深入步:字符型量的本质字符常量在编写程
10、序时,要用两个单引号括住它。它属于种从表面上看来是非数值型 的量.但其实在计算机的内存中,它就是以ASCH码的形式存储的,占用个字节内存空间 的一个二进制正整数(取值在一一127之间).字符型量是用计算机进行文字处理的基础。符号常量一般由大写英文字母组成的标识符构成,用#define来进行定义,比如: #definc PI 3.1416 。源程序中所有出现的记号PI都会被编译预处理程序用3.1416替代。修改常量的值变得非常方便,程序的可读性也更好。7 .变量定义变量的作用:要求系统为存放(其数值可以变化的)数据事先分配内存单元,变量 名作为内存单元的得号展。定义变量的形式是:类型名变局列表;
11、定义变量只能使用标识符。多个变量之间用逗号隔开,构成变量列表。C语言中各种常用的变量类型是int (整型)、float (单精度浮点型)、char (字符型)、 double (双精度浮点型)、long(长整型)。通过变量名score ,可以找到(即映射为)相应的内存单元地址。假设地址为2000,语句:seore=38.0;的含义和作用是:将数值38.0存放在地址为2000的内存单元中。变量的值是可以变化的。而变量名所对应的内存地址是不变的。8 .变量一定要先进行定义,定义后一定要进行初始化(即存入一个初始值在变量对应的内 存单元中,参见P页),然后才能在表达式中使用或进行输出。否则,变量所对
12、应的内 存单元中的坟圾藝理就会在程序中(的表达式或输出语句)被误用。9 .运算符是用来告诉编译程序对运算量要做何种运算的抽象形式。由编译程序转化成具体 的运算类指令。最常用的运算符分为三大类:算术运算符、关系运算符(见下一章)、逻辑 运算符(见下一章)。各种算术运算符见下表表2. x各种算术运算符运算符运算举例结果+正号+88-负号-a (a的值为3)-3+加11+516-减11-56*乘法11*555/除法11/52 (这是整数除法)/除法11.0/52.2 (这是实数除法)%取模(取整除的余数)11%51 (11除以5的余数)乘法运算符最容易漏写(比如:将2*x*y ,误写为2xy ),不
13、要把实数除法运算符误用 为整数除法(比如:错把1.0/3写成1/3。1/3的值是)。10 .所谓表达式,是用运算符将运算量(常量、变量、函数调用)连接起来的有意义的式子。 其中还可使用圆括号来改变运算符固有的先后运算顺序圆括号内的部分优先进行运 算。单个常量、变量和函数调用是最筒単的表达式。在初学编程时,表达式极易出现多种 书写错误。在命令型高级语言中,实际上只能用表达式和语句这种抽象的、形式化的方式, 来命令计算机为你进行数据处理工作(由编译程序转化为系列的取数指令和运算指令)。单个常量、单个变量和单个函数调用是最简单的表达式(比如x,可以看成是表达式 x+0 )。深入一步:普通的(指没有副
14、作用的,见本章提高部分)表达式中出现变量的含义表达式x+y中,出现变量的含义是:根据变量名(这对应着个内存单元的地址)到 内存中去取该变量的值(取到CPU的某个寄存器中去),然后(在运算器中)进行指定的运 算.该变量的值依然不变。11 .赋值语句的形式是:变量=达式:。赋值语句先计算出赋值号“=”右边表达 式的值,然后将此值存放在赋值号左边的变量(所对应的内存单元)之中。注意:赋值号的左边不能是表达式,只能是单个变量。赋值语句中变量值的变与不变:“左边改变,右边不变”赋值号右边表达式中的变量(如果有的话)仅仅是取出它的值来参与表达式规定的运算, 变量的值仍然未变.而赋值号左边变量(所对应的内存
15、单元中)的原来值,将被表达式算出 的新值存入而“覆盖“掉。12 .形式如 二包含方至x的港父,(x可以是任何简单类型的变量) 的赋值语句,大量的出现在程序中。它表示的是种邙住去不:即指明了如何由变量x的 个老值(取出来参与表达式所规定的运算),最终得到了变量x的个新值(最终存入到赋 值号右边的变量x中)。专题讨论:库函数和库函数调用库函数:编译程序(又称为编译器)附带的,批可以被任何别的C语言程序“调用”的, 通用的、命名了的子程序。所有这些库函数组成了一个标准函数库,与编译程序一道打包发行。安装了 C编译程序 后,我们就能在编写程序时,调用这些库函数.函数调用(function cal 1
16、):在我们编写的C语言源程序中,可以调用库函数为我们的程 序做些复杂的(通常是辅助性的)运算和处理工作,函数的调用方式为:库函数名(参数列息)其中参数列表中的参数如果多于个,参数之间就要用逗号隔开.比如要求出5. 6的4 次方是多少,就要调用库函数pow ( 5. 6 , 4 );将2开平方,就要调用库函数:sqrt (2)。调用库函数时千万不要忘记包含相应的头文件。参数可以是常量、变量、表达式。参数 必须要用圆括号括住。比加pow(x, 3.7)、sin( alfa*3.1416/180); C语言中的各种常用 库函数的调用方法说明,请见附录。编程时调用了库函数,这些事先编译好的、命名了的子
17、程序,就可以通过“编译”步骤 之后的“链接”这步骤,“链入”到你所编写的程序之中,共同组成一个可执行的机器语 言程序(可执行程序文件的扩展名是.exe ).这样就可以大大减少编写程序的工作量。以下仅列出常用的数学库函数(要包含头文件 math, h):sin (x)x为弧度,正铉函数cos (x)X为弧度,余铉函数exp (x)ex以e为底的指数函数log (x)logcX以e为底的对数函数loglO (x)logioX以10为底的对数函数fabs (x)X 求X的绝对值函数fmod (x, y)整除x/y的余数floor (x)求不大于X的最大整数pow(x, y)xy幕函数,sqrt (x
18、)xI/2开平方函数1. 3数据输出与输入:1.3. 1数据(变量或表达式的值)输出可调用格式化输出库函数:printf 函数。调用的一般形式为printf (参数1,参数2,参数3,参数n)其中参数1是格式控制串。参数2,参数3,参数n是输出项列表 例题1.2#ncludemain()(int num ;float x ;num = 123:x=34. 678printf(*%d %f”, num, x):程序运行结果为:123 34. 678000 格式控制串是用双引号括起来的字符串。%d是第一个输出项num的格式说明,以有符号的卜进制形式输出整数(正数不输出符号) %f是第二个输出项x的
19、格式说明,以小数形式输出单、双精度实数,默认输出6位小数显然,%d是控制整数num的,%f是控制实数x的。为了清晰起见,格式控制串中除了格式说明之外,还可以有按照原样输出的普通字符例如:printf ( “num=%d x=%f”, num , x ):输出结果为:num=123 x=34. 678000如果num是车牌号,而x是车速的话,则以下的语句更为优秀:printf(车牌为d号,车速是%f千米/小时、n”, num ,x );输出结果为:车牌为123号,车速是34. 678000千米/小时在格式控制串中,还可以有换行符号n(这是种转义字符) 例:printf( num=%dnx=%f
20、, num , x );输出结果为:num=123 x=34. 678000域宽和精度%m. nf :对于实数,要想改变默认的小数点后面显示6位。可改为%, nf例如:printf ( x=%. 2f” , x);输出结果为:x=34. 68/4 舍 5 入printf ( x=%7. 2f” , x);输出结果为:x= 34. 68说明:34.68左边多出两个空格,整个变量x的输出域宽(包括小数点)占了 7位。 如果指定域宽小于输出项的实际宽度,则指定的域宽不起作用。L4. 2数据(变量)输入,可调用格式化输出库函数:scanf()函数格式化输入库函数scanf的调用,可以使得程序运行暂停下
21、来,等待用户的输入,程序 用户可以通过键盘输入一个数值到变量(所对应的内存单元)中。不过在函数调用时,第一 个参数是相应的占位符d, %f或c,它们与要输入的变量类型的对应关系如下表:占位符输入变量的类型%dint%ffloat%cchar库函数scanf ()的调用通过键盘输入个变量值的最简单形式是:scan或占位符,&变量名);变量左边的符号&“是个取地址符号。这个取地址符号,在scanf ()函数调用时,初 学者最容易漏写。注意:占位符中的转换说明一定要与后面存储输入数据的变量类型相匹配。深入步:格式化库输入函数scanf ()的工作原理简述等待程序用户从键盘上榆入字符串,在用户按下回车
22、键后,按照占位符中的转换说明, 对输入字符串进行数值数制转换,变成二进制的整数、实数或ASCH码,然后将此二进制的 整数、实数或ASCII码,存入到由后个参数(即“&变量”)指定了地址的变量所对应的内 存单元中。不必感到吃惊,你在PC机或笔记本电脑的键盘上的任何多次(或一次)击键产生的榆 入,系统其实都是当作一串(或个)字符来对待的。功能强大、复杂而又容易用错的格式化输入库函数scanf ()的比较详细的讲解请参见 本章提高部分。1. 5用计算机求解问题的一般步骤:到目前为止,我们学了不少有关c语言的基础语法知识。但是在进行编程工作时,其实 只有变量、表达式、赋值语句、输入数据到变量和输出变量
23、或表达式的结果,这些要素是 我们需要重点考虑的。其中的变量,成为我们编程解决实际问题时的核心和主线。要考虑的关键问题是:需要定义哪些变量;需要输入哪些己知的变量;如何根据己知的 变量构造出合适的表达式,从而用赋值语句来求出未知变量的值;最后将求出的变量(或表 达式)的值输出。用计算机求解问题,解决问题的一般过程是;1 .用普通语言简要并尽可能精确地叙述问题;2 .问题中已知的量有几个,其中有几个量随求解的具体应用场合会发生变化?(这些量应当 定义为变量)有哪几个不会发生变化(这些量可用数值常量或符号常量来表示)?其中会变 化的已知量一般应当在程序中用到此数据前,用输入函数调用(有的高级语言用输
24、入语句) 进行数据输入。3 .问题中要求出的有几个量?4 .从已知的量如何得到要求出的量?有何公式可以利用?有何方程式可以利用?如果是公式, 就可以直接将其转换为赋值语句,只需把公式右边的数学表达式转换为高级语言的算术 表达式即可。如果是方程式,则需你自己亲自将方程式求解得到最后的公式,然后将其 转换为赋值语句,只有到了这步,可以将工作交给计算机做。5 .如果从已知的到要求的最终结果需要一些中间变量,则需要在程序中说明这些中间变 量,并且得到怎么从已知的量到中间变量的值的公式,最终山已知量,中间变量得到所 要求的结果的公式,将所有这些公式转换为赋值语句。6 .将结果输出。其中最为困难的往往是第
25、4步和第5步。这两步通常又被称为寻找求解问题的算法。1. 6逐步求精的伪代码表示算法:表示问题求解的算法有多种方法,其中最为常用的是伪代码和流程图。但由于流程图只 适合解决规模较小的、比较简单的问题。虽然初学者易于理解和掌握,但在程序员和编程高 手中并不流行因为它不利于对算法的构思、修改和调整(仅适用于比较清晰地表达算 法)。所以木书不作介绍(养成了用流程图来表示算法的习惯后,人们很难再转变成用其它 更好的方式去构造算法,所以还不如一步到位,采用伪代码)。本书使用的是用逐步求精的 伪代码来表示算法。所谓伪代码没有严格的规范(所以也比较灵活),但其中有一些结构要 素,可以用些比较规范的方式来表述
26、对问题的计算和处理流程。级算法只是解决问题的个轮廓。有些复杂问题,只根据级算法还难以直接写出C 语言的源程序。这时可对级算法进步求精(称为二级求精),将它其中的某些步骤,扩 展成更详细的步骤,. .直到可以很容易写出c语言程序的语句时为止。对于某些人是很显然的算法描述,对于其他人可能并不显而易见。因此,算法求精的 过程和步骤是因人而异的。你的编程经验越丰富,算法求精的步骤就可能越少。不过,算法 求精的步骤太少也不一定是好事。因为程序员的个良好习惯,就是把伪代码表示的级算 法(最多到二级求精),转变为源程序中的注释。注释太过简洁,会加大别人和自己阅读程 序的困难。学习体会:学习用伪代码来表达自己
27、的编程思路和算法,笔者的体会是没有什么捷径让你能够迅速 掌握它,开始只能是去模仿,去领悟.时间长了,看的、模仿的、写的算法多了,慢慢就会 了。类似于学游泳和学骑自行车.在大量地模仿和大量地实践过程中,你就会不知不觉地掌 握它。第1讲大小写字符之间的转换编写个程序,运行时接受用户输入的小写英文字母,程序将其转换为大写英文字母 并显示在屏幕上。类型必修题趣味性难度分析:此程序主要是要考虑如何由输入的任意个小写的英文字母,得到所对应的大写英文 字母。查看ASCII码表,发现所有小写英文字母的ASCII码值都比相应的大写字母ASCII 码值大32。即存在以下等式关系:大写英文字母的ASCII码=小写英
28、文字母的ASCI!码32于是编写C语言程序如下:1 #include2 main()3 4 char chi, ch2;5 printf (“请键入个小写英文字母并按回车键n”);6 scanf C*%c”, &chl);7 ch2=chl-32;8 printf (“相对应的大写英文字母为枇、n”,ch2);9 )程序说明:在C语言中,字符变量其实就是占有一个字节内存的种小整型变量,它的取值 一般就是在0127之间的整数值,对应着标准ASCI!表上的128个字符。细节问题请参 考本章提高部分:对字符变量的进步说明。问题1:是否可以将第4行与第6行互相调换?答:不可以。在C语言中,定义(序列)
29、必须放在语句(序列)的前面。问题2:是否可以漏掉第4行到第8行中的任意一行最后面的分号?答:不可以。在C语言中,任何定义或语句,都必须以分号作为结束符。只有一个例外一 那就是复合语句,参见下一章。问题3:如果将第8行改写为:printf (“相对应的大写英文字母为dn”, ch2);程序将会出现什么问题?答:这时输出的是该字符所对应的ASCII码(其实也是字符变量在内存中的真正值转换成 的十进制数)。第2讲求三个数的和及平均值类型必修题趣味性难度变量安排:3个已知的数要用3个变量al, a2, a3:三个数的和用1个变量sum,平均值用1个变量ave, 所有变量都为实型变量。级算法:1 .输入
30、这三个数al, a2, a3;2 .求这三个数的的和sum及平均值ave;3 .输出 sum, ave;其中第二步由于不能直接转化成语句而需要进一步求精根据求和及求平均值的公式sum=al+a2+a3ave=sum4-3只需将其转化为赋值语句即可第2步的二级求精:2.1 sum=al+a2+a3;/*求这三个数的和2.2 ave=sum/3;/*求这三个数的平均值转化成C语言程序:/求三个数的和及平均值/1 #include2 int main()3 (4 float al, a2, a3;/三个已知数,说明为实型变量/5 float sum, ave;/两个未知数,说明为实型变量/6 /输入
31、这三个数al, a2, a3*/7 printf(“请输入3个数,3个数之间用空格隔开n);8 scanRf%f%,&al, &a2, &a3);910 /求这三个数的的和sum及平均值ave*/11 sum=al+a2+a3;12 ave=sum/3;1314 /输出 sum, ave*/15 printfi(ttsum=%f, ave=%f, sum, ave);16 return 0;17 注意:运行此程序时,要用键盘输入三个数值给变量al, a2, a3,三个数之间要用空 格隔开。输完后,按下回车键,程序会继续运行下去(其中的道理参见9.5节)。点评将算法的伪代码,转化为程序中的注释:
32、注意,伪代码形式的级算法,在程序中转变为注释,使得程序的可读性比较好。这 是种良好的编程习惯。问题:如果将第8行改为scanfill%f;%f,%f, &al ,&a2 ,&a3);数据应当如何输入? 答:输入的数据之间现在不能用逗号隔开,而要用逗号隔开了。练习:请将程序第7行删掉再编译运行,感受一下程序是否不友好了?第3讲已知三角形的两边夹角,求对边长度及面积类型必修题趣味性难度级算法1 .输入三角形的两边x, y及夹角alfa2 .求三角形对边长度length3 .求三角形面积area4 .输出三角形的对边长度及面积其中第2、第3步需要进步求精C语言的库函数中,有一批数学库函数,其中包含正
33、弦函数sin()及余弦函数cos()(注意, 库函数名都是小写的)。不过对这些库函数的调用,首先要包含头文件:#include 其次,这两个三角函数所要用到的角度是以弧度作为单位的,而不是度,因此,如果输入的 角度是以度为单位的,还必须转化位弧度为单位的角度。然后,才能利用公式来求三角形的 对边长度和面积。sqrt函数,是用来求一个数的平方根的数学库函数。length=sqrt(x*x+y*y-2*x*y*cos(alfa*PI/180)area=x*y*sin(alfa* 180/3.1416)*1/2转化成C语言的程序1 #include2 #include3 #define PI 3.1
34、4164 int main()5 (6 float x, y, alfa;7 float length ,area;89 /输入三角形的两边x,y及夹角alfa*/10 printf(“请输入三角形的两边及夹角n);11 scanRf%f%F, &x,&y,&alfa);1213 /求三角形对边长度/14 length=sqrt(x*x+y*y-2*x*y*cos(alfa*PI/l 80);1516 /求三角形面积/17 area=x*y*sin(alfa*PI/l 80)/2;1819 /输出三角形的对边长度及面积/2021 printf(三角形的对边长为f,面积为f n”,length,
35、area );2223 return 0;24 问题1:第2行是否可以不要?第不行,只要调用库函数中的数学函数,必须包含此头文件。小结:对变量进行初始化的三种方式1 .在变量定义时,立即给它个初值(比如int i=0;);2 .用赋值语句,将表达式计算出来的值,赋给变量;i=0;3 .采用输入函数,将数据由外部(键盘或文件等输入设备)存入变量所代表的内存中(比 如 scanH%d , &i); ): 任何变量,在定义后,你都必须采用上述三种方式之一,对其进行初始化。没有进行初 始化的变量,是决对不能出现在表达式中的。第4讲 将一个三位整数反向后输出类型必修题趣味性难度*级算法1 .输入个三位整
36、数-n2 .通过利用学过的算术运算符整除、和取余数%进行分解,分别求出此 三位整数n的百位数n3,十位数n2和个位数nl3 .反向后的三位整数为num=n 1 * 100+n2* 10+n34 .输出此三位数其中第2步由于不能立即写出C语言的语句,需要进步求精:5 .1求出n的百位数:n3=n/1006 .2 求出 n 的十位数 n2=(n-n3*100)/107 . 3求出n的个位数nl=n%10算法验证:假设将一个任意指定的三位整数比如315fn (即存入变量口中),用于验证 上述算法过程的正确性;由2. 1可得到百位数n3的值为:315/100即等于3:由2. 2可得到 十位数n2的取值
37、为:(315-3X100)/10等于1;由2. 3可得到个位数nl的取值为:315%10 等于5。再通过算法的第3步,反向后的值num为:n 1 * 100+n2* 10+n3=5*100+1*10(H3=5130 最终值num确实等于513算法验证是正确的(验证算法的其他重要方法请看第 讲洗扑克牌算法P页)。转化为C语言程序:1 #include2 int main()3 (4 int n;/输入变量/5 int n3, n2, nl;/中间变量/6 int num; /结果变量/7 /输入个三位整数n*/8 printf(“请输入个三位整数、n);9 scanfT%d, &n);1011
38、/分别求出它的百位数n3,十位数n2,个位数nl*/12 n3=n/100;13 n2=(nn3* 100)/10;14 nl=n%10;1516 /反向后的三位整数为/17 num=n 1 * 100+n2* 10+n3;1819 /输出此三位数/20 printfCnum=%d”, num);21 return 0;22 问题1 :第8行起什么作用?是否可以删掉这句?答,这一句起到提示的作用。可以删掉,但程序对使用者不友好(不好用),使得用户要面 对黑屏进行数据输入,很容易出现输入错误。问题2 :是否可以将第17行和第20句合并为下面这一句并删掉第6行? printf(num=%d, nl
39、*l00+n2* 10+n3 );答:可以。printflf)函数调用时,格式串后的输出项参数,既可以是常量或变量,也可以 是个表达式。直接输出值时可以不定义变量,直接将表达式(的计算结果)作为输出参数。问题3:是否可以用赋值语句n=315,取代输入变量n的第9句scanf(d, &n);?答:可以,赋值语句n=315,和输入函数调用语句scanfT%d”, &n);都可以使变量n能够 得到初始化(即得到有用的初值)。但用前者,程序失去了灵活性,它只能将一个固定的三位 整数315反向输出。如果想要将别的三位整数反向输出,则需要编程者重新修改程序。输 入函数调用语句scanf(d”,&n),则可
40、以使得程序用户输入任何的三位整数。只需将程序 重新运行遍即可,不需要修改程序。问题4:将第12行和第13行颠倒次序是否可以?答:不可以,变量n3会出现初始化错误。因为颠倒次序以后,赋值语句n2=(n-n3*100)/10;中,的表达式:(n-n3*100)/10中的变量n和n3,是要到相应 变量的内存空间中去取出数值来,参与表达式所给定的运算的。变量n的值没有问题,但变 量n3因为没有得到初始化,其内存中是垃圾数据。也就是说,13行的赋值语句:n2=(n n3*100)/10J的执行,依赖于12行的赋值语句:n3=n/100;的执行,变量n3的值得以 初始化。问题5:将13行与14行互换是否可
41、以?答:可以,因为两条赋值语句之间的变量并没有依赖关系。问题6:第10条语句是否可改为printf(num=%d”, &num);答:不可以,这样打印出来的一般是变量num的内存地址,而不是在这个地址的存储单 元中存放的(变量的)数据。也就是说,如果变量num的内存地址是123456,而变量num 的值是546,那么,此句运行后,得到的是:num= 123456这显然是错的。问题7:是否可以将所有变量n, n3, n2, nl都用实型float来定义?答:不可以;程序12行、13行的赋值语句的表达式,都要求是整除运算。14行的n%10 , 运算符%也要求变量n是整型,而不是实型。问题8:是否可
42、以将4, 5, 6行,用一行来表示?答:可以。但不好,最好是将已知变量(要初始化的)、结果变量(求出的结果)和中间(临 时)变量分开写,这样有利于检查程序:已知变量是否初始化了,结果变量是否输出了。习题1.将一个两位整数反向输出;习题2.将一个4位整数反向输出;第5讲鸡兔同笼问题类型必修题趣味性*难度题目,已知鸡和兔的总头数和总脚数,求鸡有多少只,兔有多少只?级算法1 .输入总头数heads,总脚数fbet2 .求鸡的只数chicken和兔的只数rabbit3 .输出变量chicken和rabbit的值其中只有第二步需要求精根据二元次方程组可知四个变量heads, feet, chicken,
43、 rabbit之间的关系为 heads=chicken + rabbitfeet=2 X ch i cken+4 X rabb it解此方程组可得到如下两个公式: chicken=(4X heads-feet)/2 rabbit=(feet-2 X heads)/2将此公式转化为赋值语句,考虑到输入的总头数和总脚数不一定能得到整数解,因此将变 量chicken(表示鸡的只数),rabbit(表示兔的只数),定义为实型变量。二级求精2.1 chicken=(4*heads-feet)/2. 02.2 rabbit=(feet-2*heads)/2.0转化为C语言程序1 #include2 int
44、 main()3 (4 int heads, feet;5 double chicken, rabbit;6 /输入总头数heads,总脚数feet*/78 printfT请输入总头数和总脚数,两数间用空格隔开n);9 scanft佻d%, &heads, &feet);1011 /求鸡的只数chicken和兔的只数rabbit*/1213 chicken=(4. 0*heads-feet)/2.0;14 rabbit=(feet-2.0*heads)/2.0;15 /输出变量chicken和rabbit的值1617 printfi“鸡的只数f只,兔的只数f只,chicken, rabbit)
45、;18 return 0;19 )问题1:如果不解方程组,而直接将其转变为赋值语句,也就是用heads =chicken+rabbit;feet=2*chicken+4*rabbit;取代第5和第6句,结果会如何?答:赋值语句右边的表达式中出现的变量,必须是已经是经过初始化的变量(参见P 页)。赋值语句是用赋值号右边的表达式求出的值,存放到赋值号左边的变量表示的存储单 元中。所以,这两句是不正确的,但大多编译程序不会报错。程序运行时会用内存存储单元 中不确定的变量chicken,和rabbit的值(垃圾数据),经过运算得到两个错误数值,去改 变变量heads和feet的原来值。换言之,方程式不能直接转变为赋值语句,只有公式可 以直接转变为赋值语句(公式是等号左边为个要求值的变量,等号右边是个数学代数式, 数学代数式中出现的变量的值都是已知的)。点评:所谓计算机的智能此题程序一旦编好,由另一个用户来使用计算机运行这个程序,他会觉得计算机很聪明, 竟然会求解鸡兔同笼的方程式,得到正确答案。“深蓝”计算机为什么能够战胜人类的国际 象棋世界冠军卡斯帕罗夫,其道理是类似的。人类的智能转变成了程序存存放在了计算机中, 与计算机的强大计算能力(普通pc机目前每秒可运
限制150内