本文所列习题答案均不含解释说明类题目。
第1章 程序设计和C语言
什么是程序?什么是程序设计?
为什么需要计算机语言?高级语言有哪些特点?
正确理解以下名词及其含义: (1)源程序,目标程序,可执行程序。 (2)程序编辑,程序编译,程序连接。 (3)程序,程序模块,程序文件。 (4)函数,主函数,被调用函数,库函数。 (5)程序调试,程序测试。
编写一个C程序,运行时输出 Hello World! 这个程序是一些国外C教材中作为第一个程序例子介绍的,一般称为Hello程序。
1 2 3 4 5 6 #include <stdio.h> int main () { printf ("Hello World!\n" ); return 0 ; }
编写一个C程序,运行时输出以下图形: 1 2 3 4 ***** ***** ***** *****
1 2 3 4 5 6 7 8 9 #include <stdio.h> int main () { printf ("*****\n" ); printf (" *****\n" ); printf (" *****\n" ); printf (" *****\n" ); return 0 ; }
编写一个C程序,运行时输入a,b,c三个值,输出其中值最大者。
1 2 3 4 5 6 7 8 9 10 #include <stdio.h> int main () { int a,b,c,max; scanf ("%d %d %d" ,&a,&b,&c); max=a>b?a:b; max=max>c?max:c; printf ("%d\n" ,max); return 0 ; }
看懂《C程序设计(第五版)学习辅导》第16章中介绍的用Visual Studio 2010对C程序进行编辑、编译、连接和运行的方法,并进行以下操作: (1)建立一个新项目,定名为project1。 (2)建立一个新文件,定名为test1。 (3)向test1文件输入源程序(此源程序为读者自己编写的程序)。 (4)编译该源程序,如发现程序有误,请修改之,直到不出现“编译出错”为止。 (5)连接并运行,得到结果。分析结果。
第2章 算法——程序的灵魂
什么是算法?试从日常生活中找3个例子,描述它们的算法。
什么叫结构化的算法?为什么要提倡结构化的算法?
试述3种基本结构的特点,请另外设计两种基本结构(要符合基本结构的特点)。
用传统流程图表示求解以下问题的算法。 (1)有两个瓶子A和B,分别盛放醋和酱油,要求将它们互换(即A瓶原来盛醋,现改盛酱油,B瓶则相反)。 (2)依次将10个数输入,要求输出其中最大的数。 (3)有3个数a,b,c,要求按大小顺序把它们输出。 (4)求1+2+3+…+100。 (5)判断一个数n能否同时被3和5整除。 (6)将100~200之间的素数输出。 (7)求两个数m和n的最大公约数。 (8)求方程式 $ax^2+bx+c=0$ 的根。分别考虑: ①有两个不等的实根; ②有两个相等的实根。
用N-S图表示第4题中各题的算法。
用伪代码表示第4题中各题的算法。
什么叫结构化程序设计?它的主要内容是什么?
用自顶向下、逐步细化的方法进行以下算法的设计: (1)输出1900—2000年中是闰年的年份,符合下面两个条件之一的年份是闰年: ①能被4整除但不能被100整除; ②能被100整除且能被400整除。 (2)求 $ax^2+bx+c=0$ 的根。分别考虑 $\mathit{d}=b^2-4ac$ 大于0、等于0和小于0这3种情况。 (3)输入10个数,输出其中最大的一个数。
第4题中各题的C程序代码如下: (1)
1 2 3 4 5 6 7 8 9 10 #include <stdio.h> int main () { int a=1 ,b=2 ,t; t=a; a=b; b=t; printf ("A瓶内现在是%d,B瓶内现在是%d。\n" ,a,b); return 0 ; }
(2)
1 2 3 4 5 6 7 8 9 10 11 12 #include <stdio.h> int main () { int a,max=0 ,i; for (i=0 ;i<10 ;i++) { scanf ("%d" ,&a); max=max>a?max:a; } printf ("%d\n" ,max); return 0 ; }
(3)
1 2 3 4 5 6 7 8 9 10 11 #include <stdio.h> int main () { int a,b,c,t; scanf ("%d %d %d" ,&a,&b,&c); if (a<b){t=a;a=b;b=t;} if (b<c){t=b;b=c;c=t;} if (a<b){t=a;a=b;b=t;} printf ("%d %d %d\n" ,a,b,c); return 0 ; }
(4)
1 2 3 4 5 6 7 8 9 #include <stdio.h> int main () { int i,sum=0 ; for (i=1 ;i<=100 ;i++) sum+=i; printf ("%d\n" ,sum); return 0 ; }
(5)
1 2 3 4 5 6 7 8 9 10 11 #include <stdio.h> int main () { int n; scanf ("%d" ,&n); if (n%3 ==0 &&n%5 ==0 ) printf ("%d能同时被3和5整除。\n" ,n); else printf ("%d不能同时被3和5整除。\n" ,n); return 0 ; }
(6)
1 2 3 4 5 6 7 8 9 10 11 #include <stdio.h> int main () { int n; scanf ("%d" ,&n); if (n%3 ==0 &&n%5 ==0 ) printf ("%d能同时被3和5整除。\n" ,n); else printf ("%d不能同时被3和5整除。\n" ,n); return 0 ; }
(7)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #include <stdio.h> int isprime (int n) { int i; for (i=2 ;i*i<=n;i++) { if (n%i==0 ) return 0 ; } return 1 ; } int main () { int i; for (i=100 ;i<=200 ;i++) { if (isprime(i)) printf ("%d\n" ,i); } return 0 ; }
(8)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 #include <stdio.h> #include <math.h> int main () { double a,b,c,x1,x2; scanf ("%lf %lf %lf" ,&a,&b,&c); x1=(-b+sqrt (b*b-4 *a*c))/2 /a; x2=(-b-sqrt (b*b-4 *a*c))/2 /a; if (x1==x2) printf ("x1=x2=%f\n" ,x1); else printf ("x1=%f\nx2=%f\n" ,x1,x2); return 0 ; }
第8题中各题的C程序代码如下: (1)
1 2 3 4 5 6 7 8 9 10 11 #include <stdio.h> int main () { int i; for (i=1900 ;i<=2000 ;i++) { if ((i%4 ==0 &&i%100 !=0 )||(i%100 ==0 &&i%400 ==0 )) printf ("%d\n" ,i); } return 0 ; }
(2)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #include <stdio.h> #include <math.h> int main () { double a,b,c,d,x1,x2; scanf ("%lf %lf %lf" ,&a,&b,&c); d=b*b-4 *a*c; if (d>0 ) { x1=(-b+sqrt (d))/2 /a; x2=(-b-sqrt (d))/2 /a; printf ("x1=%f\nx2=%f\n" ,x1,x2); } else if (d==0 ) { x1=-b/2 /a; printf ("x1=x2=%f\n" ,x1); } else { x1=-b/2 /a; x2=sqrt (-d)/2 /a; printf ("无实根。\n" ); printf ("复数根为:x1=%f%+fi,x2=%f%+fi\n" ,x1,x2,x1,-x2); } return 0 ; }
(3)
1 2 3 4 5 6 7 8 9 10 11 12 #include <stdio.h> int main () { int a,max=0 ,i; for (i=0 ;i<10 ;i++) { scanf ("%d" ,&a); max=max>a?max:a; } printf ("%d\n" ,max); return 0 ; }
第3章 最简单的C程序设计——顺序程序设计
假如我国国民生产总值的年增长率为7%,计算10年后我国国民生产总值与现在相比增长多少百分比。计算公式为 $p=(1+r)^n$ $r$ 为年增长率, $n$ 为年数, $p$ 为与现在相比的倍数。
1 2 3 4 5 6 7 8 9 #include <stdio.h> #include <math.h> int main () { double r=0.07 ,n=10 ,p; p=pow (1 +r,n); printf ("%f\n" ,p); return 0 ; }
存款利息的计算。有1000元,想存5年,可按以下5种办法存: (1)一次存5年期。 (2)先存2年期,到期后将本息再存3年期。 (3)先存3年期,到期后将本息再存2年期。 (4)存1年期,到期后将本息再存一年期,连续存5次。 (5)存活期存款。活期利息每一季度结算一次。 2017年的银行存款利息如下: 1年期定期存款利息为1.5%; 2年期定期存款利息为2.1%; 3年期定期存款利息为2.75%; 5年期定期存款利息为3%; 活期存款利息为0.35%(活期存款每一季度结算一次利息)。 如果 $r$ 为年利率, $n$ 为存款年数,则计算本息和的公式如下:
年期
本息和
$1$ 年期本息和:
$P=1000*(1+r)$ ;
$n$ 年期本息和:
$P=1000*(1+n*r)$ ;
存 $n$ 次 $1$ 年期的本息和:
$P=1000*(1+r)^n$ ;
活期存款本息和:
$P=1000*(1+\frac{r}{4})^{4n}$ 。
说明: $1000*(1+\frac{r}{4})$ 是一个季度的本息和。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #include <stdio.h> #include <math.h> int main () { double P1,P2,P3,P4,P5; double r1=0.015 ,r2=0.021 ,r3=0.0275 ,r5=0.03 ,r0=0.0035 ; P1=1000 *(1 +5 *r5); P2=1000 *(1 +2 *r2)*(1 +3 *r3); P3=1000 *(1 +3 *r3)*(1 +2 *r2); P4=1000 *pow (1 +r1,5 ); P5=1000 *pow (1 +r0/4.0 ,4 *5 ); printf ("第1种方案的本息和为%f\n" ,P1); printf ("第2种方案的本息和为%f\n" ,P2); printf ("第3种方案的本息和为%f\n" ,P3); printf ("第4种方案的本息和为%f\n" ,P4); printf ("第5种方案的本息和为%f\n" ,P5); return 0 ; }
购房从银行贷了一笔款 $d$ ,准备每月还款额为 $p$ ,月利率为 $r$ ,计算多少月能还清。设 $d$ 为300 000元, $p$ 为6000元, $r$ 为1%。对求得的月份取小数点后一位,对第2位按四舍五入处理。
提示: 计算还清月数 $m$ 的公式如下: $m=\frac{\log{p}-\log{(p-d \times r)}}{\log{(1+r)}}$ 可以将公式改写为 $m=\frac{\log{(\frac{p}{p-d \times r})}}{\log{(1+r)}}$ C的库函数中有求对数的函数log10,是求以10为底的对数, $\log{(p)}$ 表示 $\log{p}$ 。
1 2 3 4 5 6 7 8 9 #include <stdio.h> #include <math.h> int main () { double d=300000 ,p=6000 ,r=0.01 ,m; m=log10 (p/(p-d*r))/log10 (1 +r); printf ("%f\n" ,m); return 0 ; }
分析下面的程序1 2 3 4 5 6 7 8 9 #include <stdio.h> int main () { char c1,c2; c1=97 ; c2=98 ; printf ("c1=%c,c2=%c\n" ,c1,c2); printf ("c1=%d,c2=%d\n" ,c1,c2); return 0 ; }
(1)运行时会输出什么信息?为什么? (2)如果将程序第4,5行改为
运行时会输出什么信息?为什么? (3)如果将程序第3行改为
运行时会输出什么信息?为什么?
(1)
第一行输出ASCII码对应的字符,第二行输出其数值。 (2)
char是单字节的,范围为-128~127,其中ASCII码对应的有效值范围为0~127,197和198超过了这个范围,赋给char时按位截断赋值,其对应的二进制码分别为11000101和11000110,取8位反码表示对应的数值为-59和-58。 第一行,对于超出ASCII码范围的值其最高位为1,屏幕会将其和下一个字符连在一起表示,同时该字符是未知的。 第二行,输出了其数值。 (3)
由于int范围大于char,所以不会出现精度损失。
第一行,对于超出ASCII码范围的值其最高位为1,屏幕会将其和下一个字符连在一起表示,同时该字符是未知的。 第二行,输出了其数值。
用下面的scanf函数输入数据,使a=3,b=7,x=8.5,y=71.82,c1=’A’,c2=’a’。在键盘上应如何输入?1 2 3 4 5 6 7 8 9 10 11 #include <stdio.h> int main () { int a,b; float x,y; char c1,c2; scanf ("a=%db=%d" ,&a,&b); scanf ("%f%e" ,&x,&y); scanf ("%c%c" ,&c1,&c2); return 0 ; }
请编程序将“China”译成密码,密码规律是:用原来的字母后面第4个字母代替原来的字母。例如,字母“A”后面第4个字母是“E”,用“E”代替“A”。因此,“China”应译为“Glmre”。请编一程序,用赋初值的方法使c1,c2,c3,c4,c5这五个变量的值分别为’C’,’h’,’i’,’n’,’a’,经过运算,使c1,c2,c3,c4,c5分别变为’G’,’l’,’m’,’r’,’e’。分别用putchar函数和printf函数输出这5个字符。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #include <stdio.h> int main () { char c1='C' ,c2='h' ,c3='i' ,c4='n' ,c5='a' ; c1+=4 ; c2+=4 ; c3+=4 ; c4+=4 ; c5+=4 ; printf ("%c%c%c%c%c\n" ,c1,c2,c3,c4,c5); putchar (c1); putchar (c2); putchar (c3); putchar (c4); putchar (c5); putchar ('\n' ); return 0 ; }
设圆半径 $r=1.5$ ,圆柱高 $h=3$ ,求圆周长、圆面积、圆球表面积、圆球体积、圆柱体积。用scanf输入数据,输出计算结果,输出时要求有文字说明,取小数点后2位数字。请编函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include <stdio.h> #define PI 3.1415926 int main () { double c,s,sq,vq,vz,r=1.5 ,h=3 ; c=2 *PI*r; s=PI*r*r; sq=4 *PI*r*r; vq=4.0 /3.0 *PI*r*r*r; vz=s*h; printf ("c=%.2f\n" ,c); printf ("s=%.2f\n" ,s); printf ("sq=%.2f\n" ,sq); printf ("vq=%.2f\n" ,vq); printf ("vz=%.2f\n" ,vz); return 0 ; }
编程序,用getchar函数读入两个字符给c1和c2,然后分别用putchar函数和printf函数输出这两个字符。思考以下问题: (1)变量c1和c2应定义为字符型、整型还是二者皆可? (2)要求输出c1和c2值得ASCII码,应如何处理?用putchar函数还是printf函数? (3)整型变量与字符变量是否在任何情况下都可以互相代替?如:
与
是否无条件地等价?
1 2 3 4 5 6 7 8 9 10 11 12 #include <stdio.h> int main () { char c1,c2; c1=getchar(); c2=getchar(); putchar (c1); putchar (c2); putchar ('\n' ); printf ("%c%c\n" ,c1,c2); return 0 ; }
(1)二者皆可。 (2)printf函数:
(3)在ASCII码的范围(0~127)内,可以,一旦超出就不可。
第4章 选择结构程序设计
什么是算术运算?什么是关系运算?什么是逻辑运算?
算术运算:+ - * /
关系运算:== != < > <= >=
逻辑运算:|| && !
C语言中如何表示“真”和“假”?系统如何判断一个量的“真”和“假”?
逻辑表达式中,1为真,0为假。系统内部将0视作假,非0视作真。
写出下面各逻辑表达式的值,设a=3,b=4,c=5。 (1)a+b>c&&b==c (2)a||b+c&&b-c (3)!(a>b)&&!c||1 (4)!(x=a)&&(y=b)&&0 (5)!(a+b)+c-1&&b+c/2
(1)0 (2)1 (3)1 (4)0 (5)1
有3个整数a,b,c由键盘输入,输出其中最大的数。
1 2 3 4 5 6 7 8 9 10 #include <stdio.h> int main () { int a,b,c,max; scanf ("%d %d %d" ,&a,&b,&c); max=a>b?a:b; max=max>c?max:c; printf ("%d\n" ,max); return 0 ; }
从键盘输入一个小于1000的正数,要求输出它的平方根(如平方根不是整数,则输出其整数部分)。要求在输入数据后先对其进行检查是否为小于1000的正数。若不是,则要求重新输入。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include <stdio.h> #include <math.h> int main () { int n,m; printf ("Input a positive number less than 1000:" ); scanf ("%d" ,&n); while (n<=0 ||n>=1000 ) { printf ("Input Error! Input a positive number less than 1000:" ); scanf ("%d" ,&n); } m=(int )sqrt (n); printf ("The square root is %d\n" ,m); return 0 ; }
有一个函数: 写程序,输入 $x$ 的值,输出 $y$ 相应的值。
1 2 3 4 5 6 7 8 9 10 11 #include <stdio.h> int main () { double x,y; scanf ("%lf" ,&x); if (x<1 )y=x; else if (x<10 )y=2 *x-1 ; else y=3 *x-11 ; printf ("%f\n" ,y); return 0 ; }
有一函数: 有人编写了以下两个程序,请分析它们是否能实现题目要求。不要急于上机运行程序,先分析两个程序的逻辑,画出它们的流程图,分析它们的运行情况。然后上机运行程序,观察和分析结果。 (1)1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #include <stdio.h> int main () { int x,y; printf ("enter x:" ); scanf ("%d" ,&x); y=-1 ; if (x!=0 ) if (x>0 ) y=1 ; else y=0 ; printf ("x=%d,y=%d\n" ,x,y); return 0 ; }
(2)
1 2 3 4 5 6 7 8 9 10 11 12 13 #include <stdio.h> int main () { int x,y; printf ("enter x:" ); scanf ("%d" ,&x); y=0 ; if (x>=0 ) if (x>0 ) y=1 ; else y=-1 ; printf ("x=%d,y=%d\n" ,x,y); return 0 ; }
均不行。else总是向上找离它最近的if配对,因此(1)和(2)的函数实际如下: 事实上,如果加上一个代码段括号{},就可以正常,修改如下: (1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include <stdio.h> int main () { int x,y; printf ("enter x:" ); scanf ("%d" ,&x); y=-1 ; if (x!=0 ) { if (x>0 ) y=1 ; } else y=0 ; printf ("x=%d,y=%d\n" ,x,y); return 0 ; }
(2)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #include <stdio.h> int main () { int x,y; printf ("enter x:" ); scanf ("%d" ,&x); y=0 ; if (x>=0 ) { if (x>0 ) y=1 ; } else y=-1 ; printf ("x=%d,y=%d\n" ,x,y); return 0 ; }
给出一百分制成绩,要求输出成绩等级’A’、’B’、’C’、’D’、’E’。90分以上为’A’,80~89分为’B’,70~79分为’C’,60~69分为’D’,60分以下为’E’。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include <stdio.h> int main () { int x; scanf ("%d" ,&x); switch (x/10 ) { case 10 : case 9 :printf ("A\n" );break ; case 8 :printf ("B\n" );break ; case 7 :printf ("C\n" );break ; case 6 :printf ("D\n" );break ; default :printf ("E\n" );break ; } return 0 ; }
给出一个不多于5位的正整数,要求: ①求出它是几位数; ②分别输出每一位数字; ③按逆序输出各位数字,例如原数为321,应输出123。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 #include <stdio.h> int main () { int x,a,b,c,d,e; scanf ("%d" ,&x); a=x/10000 ; b=x/1000 %10 ; c=x/100 %10 ; d=x/10 %10 ; e=x%10 ; if (a) { printf ("五位数\n" ); printf ("%d %d %d %d %d\n" ,a,b,c,d,e); printf ("%d%d%d%d%d\n" ,e,d,c,b,a); } else if (b) { printf ("四位数\n" ); printf ("%d %d %d %d\n" ,b,c,d,e); printf ("%d%d%d%d\n" ,e,d,c,b); } else if (c) { printf ("三位数\n" ); printf ("%d %d %d\n" ,c,d,e); printf ("%d%d%d\n" ,e,d,c); } else if (d) { printf ("两位数\n" ); printf ("%d %d\n" ,d,e); printf ("%d%d\n" ,e,d); } else { printf ("一位数\n" ); printf ("%d\n" ,e); printf ("%d\n" ,e); } return 0 ; }
企业发放的奖金根据利润提成。利润 $I$ 低于或等于 100 000 元的,奖金可提成10%;利润高于100 000元,低于200 000元(100 000 $< I \leq$ 200 000)时,低于100 000元的部分按10%提成,高于100 000元的部分,可提成7.5%;200 000 $< I \leq$ 400 000时,低于200 000元的部分仍按上述办法提成(下同)。高于200 000元的部分按5%提成;400 000 $< I \leq$ 600 000元时,高于400 000元的部分按3%提成;600 000 $< I \leq$ 1 000 000时,高于600 000元的部分按1.5%提成; $I >$ 1 000 000时,超过1 000 000元的部分按1%提成。从键盘输入当月利润 $I$ ,求应发奖金总数。 要求: (1)用if语句编程序; (2)用switch语句编程序。
(1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 #include <stdio.h> int main () { double i,sum=0 ; scanf ("%lf" ,&i); if (i>1000000 ) { sum+=(i-1000000 )*0.01 ; i=1000000 ; } if (i>600000 ) { sum+=(i-600000 )*0.015 ; i=600000 ; } if (i>400000 ) { sum+=(i-400000 )*0.03 ; i=400000 ; } if (i>200000 ) { sum+=(i-200000 )*0.05 ; i=200000 ; } if (i>100000 ) { sum+=(i-100000 )*0.075 ; i=100000 ; } sum+=i*0.1 ; printf ("%f\n" ,sum); return 0 ; }
(2)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include <stdio.h> int main () { double i,sum=0 ; scanf ("%lf" ,&i); switch (((int )i-1 )/100000 ) { default :sum+=(i-1000000 )*0.01 ;i=1000000 ; case 9 : case 8 : case 7 : case 6 :sum+=(i-600000 )*0.015 ;i=600000 ; case 5 : case 4 :sum+=(i-400000 )*0.03 ;i=400000 ; case 3 : case 2 :sum+=(i-200000 )*0.05 ;i=200000 ; case 1 :sum+=(i-100000 )*0.075 ;i=100000 ; case 0 :sum+=i*0.1 ;break ; } printf ("%f\n" ,sum); return 0 ; }
输入4个整数,要求按由小到大的顺序输出。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 #include <stdio.h> int main () { int a,b,c,d,t; scanf ("%d %d %d %d" ,&a,&b,&c,&d); if (a<b){t=a;a=b;b=t;} if (b<c){t=b;b=c;c=t;} if (c<d){t=c;c=d;d=t;} if (a<b){t=a;a=b;b=t;} if (b<c){t=b;b=c;c=t;} if (a<b){t=a;a=b;b=t;} printf ("%d %d %d %d\n" ,a,b,c,d); return 0 ; }
有4个圆塔,圆心分别为(2,2)、(-2,2)、(-2,-2)、(2,-2),圆半径为1,见图。这4个塔的高度为10m,塔以外无建筑物。今输入任意一点的坐标,求该点的建筑高度(塔外的高度为零)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #include <stdio.h> #include <math.h> int main () { int h; double d1,d2,d3,d4,x,y; scanf ("%lf %lf" ,&x,&y); d1=sqrt (pow (x-2 ,2 )+pow (y-2 ,2 )); d2=sqrt (pow (x+2 ,2 )+pow (y-2 ,2 )); d3=sqrt (pow (x+2 ,2 )+pow (y+2 ,2 )); d4=sqrt (pow (x-2 ,2 )+pow (y+2 ,2 )); if (d1<=1 ||d2<=1 ||d3<=1 ||d4<=1 ) h=10 ; else h=0 ; printf ("%d\n" ,h); return 0 ; }
第5章 循环结构程序设计
请画出例5.6中给出的3个程序段的流程图。
请补充例5.7 程序,分别统计当“fabs(t)>=1e-6”和“fabs(t)>=1e-8”时执行循环体的次数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #include <stdio.h> #include <math.h> int main () { int sign=1 ,times=0 ; double pi=0.0 ,n=1.0 ,term=1.0 ; while (fabs (term)>=1e-6 ) { times++; pi=pi+term; n=n+2 ; sign=-sign; term=sign/n; } pi=pi*4 ; printf ("pi=%10.8f\n" ,pi); printf ("times:%d\n" ,times); return 0 ; }
“fabs(t)>=1e-6”时执行循环体500000次。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #include <stdio.h> #include <math.h> int main () { int sign=1 ,times=0 ; double pi=0.0 ,n=1.0 ,term=1.0 ; while (fabs (term)>=1e-8 ) { times++; pi=pi+term; n=n+2 ; sign=-sign; term=sign/n; } pi=pi*4 ; printf ("pi=%10.8f\n" ,pi); printf ("times:%d\n" ,times); return 0 ; }
“fabs(t)>=1e-8”时执行循环体50000000次。
输入两个正整数m和n,求其最大公约数和最小公倍数。
辗转相除法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include <stdio.h> int main () { int m,n,t,gcd,lcm; scanf ("%d %d" ,&m,&n); lcm=m*n; while (n!=0 ) { m%=n; t=m;m=n;n=t; } gcd=m; lcm/=m; printf ("gcd=%d,lcm=%d\n" ,gcd,lcm); return 0 ; }
更相减损法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include <stdio.h> int main () { int m,n,gcd,lcm; scanf ("%d %d" ,&m,&n); lcm=m*n; while (m!=n) { if (m<n)n-=m; if (m>n)m-=n; } gcd=m; lcm/=m; printf ("gcd=%d,lcm=%d\n" ,gcd,lcm); return 0 ; }
输入一行字符,分别统计出其中英文字母、空格、数字和其他字符的个数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #include <stdio.h> int main () { int i,zm=0 ,kg=0 ,sz=0 ,qt=0 ; char s[100 ]; gets(s); for (i=0 ;s[i]!='\0' ;i++) { if (s[i]>='a' &&s[i]<='z' ||s[i]>='A' &&s[i]<='Z' ) zm++; else if (s[i]==' ' ) kg++; else if (s[i]>='0' &&s[i]<='9' ) sz++; else qt++; } printf ("zm=%d,kg=%d,sz=%d,qt=%d\n" ,zm,kg,sz,qt); return 0 ; }
求 $S_n=a+aa+aaa+\cdots+\overset{n个a}{aa \cdots a}$ 之值,其中 $a$ 是一个数字, $n$ 表示 $a$ 的位数, $n$ 由键盘输入。例如: 2+22+222+2222+22222 (此时 $n=$ 5)
1 2 3 4 5 6 7 8 9 10 11 12 13 #include <stdio.h> int main () { int a,n,Si=0 ,Sn=0 ,i; scanf ("%d %d" ,&a,&n); for (i=0 ;i<n;i++) { Si=Si*10 +a; Sn+=Si; } printf ("%d\n" ,Sn); return 0 ; }
求 $\sum_{n=1}^{20}n!$ (即求 $1!+2!+3!+4!+\cdots+20!$ )
1 2 3 4 5 6 7 8 9 10 11 12 #include <stdio.h> int main () { long long i,Sn=0 ,Si=1 ; for (i=1 ;i<=20 ;i++) { Si*=i; Sn+=Si; } printf ("%lld\n" ,Sn); return 0 ; }
求 $\sum_{k=1}^{100}k+\sum_{k=1}^{50}k^2+\sum_{k=1}^{10}\frac{1}{k}$ 。
1 2 3 4 5 6 7 8 9 10 11 12 13 #include <stdio.h> int main () { double i,Sn=0 ; for (i=1 ;i<=100 ;i++) Sn+=i; for (i=1 ;i<=50 ;i++) Sn+=i*i; for (i=1 ;i<=10 ;i++) Sn+=1.0 /i; printf ("%f\n" ,Sn); return 0 ; }
输出所有的“水仙花数”,所谓“水仙花数”是指一个3位数,其各位数字立方和等于该数本身。例如, $153$ 是水仙花数,因为 $153=1^3+5^3+3^3$ 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 #include <stdio.h> int main () { int i,a,b,c; for (i=100 ;i<1000 ;i++) { a=i/100 ; b=i/10 %10 ; c=i%10 ; if (i==a*a*a+b*b*b+c*c*c) printf ("%d\n" ,i); } return 0 ; }
一个数如果恰好等于它的因子之和,这个数就称为“完数”。例如,6的因子为1,2,3,而6=1+2+3,因此6是“完数”。编程序找出1000之内的所有完数,并按下面格式输出其因子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include <stdio.h> int main () { int i,j,s; for (i=1 ;i<=1000 ;i++) { s=0 ; for (j=1 ;j<i;j++) { if (i%j==0 ) s+=j; } if (s==i) { printf ("%d its factors are 1" ,i); for (j=2 ;j<i;j++) { if (i%j==0 ) printf (",%d" ,j); } printf ("\n" ); } } return 0 ; }
有一个分数序列 $\frac{2}{1},\frac{3}{2},\frac{5}{3},\frac{8}{5},\frac{13}{8},\frac{21}{8},\cdots$ 求出这个数列的前20项之和。
分母是斐波那契数列,分子是斐波那契数列中分母的下一项数字。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #include <stdio.h> int main () { double fm=1 ,fz=2 ,t,Sn=0 ; int i; for (i=0 ;i<20 ;i++) { Sn+=fz/fm; t=fm; fm=fz; fz+=t; } printf ("%f\n" ,Sn); return 0 ; }
一个球从100m高度自由落下,每次落地后反弹回原高度的一半,再落下,再反弹。求它在第10次落地时共经过多少米,第10次反弹多高。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 #include <stdio.h> int main () { double h=100 ,s=100 ; int i; for (i=1 ;i<10 ;i++) { h/=2 ; s+=2 *h; } h/=2 ; printf ("s=%f,h=%f\n" ,s,h); return 0 ; }
猴子吃桃问题。猴子第1填摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个。第2天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,就只剩一个桃子了。求第1天共摘多少个桃子。
1 2 3 4 5 6 7 8 9 10 11 #include <stdio.h> int main () { int i,s=1 ; for (i=9 ;i>=1 ;i--) { s=(s+1 )*2 ; } printf ("%d\n" ,s); return 0 ; }
用迭代法求 $x=\sqrt{a}$ 。求平方根的迭代公式为 $x_{n+1}=\frac{1}{2}(x_n+\frac{a}{x_n})$ 要求前后两次求出的 $x$ 的差的绝对值小于 $10^{-5}$ 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include <stdio.h> #include <math.h> int main () { double a,x,x1; scanf ("%lf" ,&a); x=x1=a; do { x=x1; x1=(x+a/x)/2 ; }while (fabs (x-x1)>=1e-5 ); x=x1; printf ("%f\n" ,x); return 0 ; }
用牛顿迭代法求下面方程在1.5附近的根: $2x^3-4x^2+3x-6=0$
牛顿迭代法(牛顿切线法)假设一个接近根的值 $x_0$ 求出 $f(x_0)$ ,过该点作切线,交 $x$ 轴于 $(x_1,0)$ ,用 $x_1$ 代替 $x_0$ 重复操作,最后得到的值会慢慢接近真正的根 $x^*$ 。 由 $f’(x_0)=\frac{f(x_0)}{x_0-x_1}$ ,得 $x_1=x_0-\frac{f(x_0)}{f’(x_0)}$ 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include <stdio.h> #include <math.h> int main () { double x0=1.5 ,x1=1.5 ,f,f_; do { x0=x1; f=((2 *x0-4 )*x0+3 )*x0-6 ; f_=(6 *x0-8 )*x0+3 ; x1=x0-f/f_; }while (fabs (x1-x0)>=1e-5 ); x0=x1; printf ("%f\n" ,x0); return 0 ; }
用二分法求下面方程在 $(-10,10)$ 的根: $2x^3-4x^2+3x-6=0$
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #include <stdio.h> #include <math.h> int main () { double l=-10 ,r=10 ,mid,fl=-2436 ,fr=1624 ,fmid; do { mid=(l+r)/2 ; fmid=((2 *mid-4 )*mid+3 )*mid-6 ; if (fmid*fl<0 ) { r=mid; fr=fmid; } else { l=mid; fl=fmid; } }while (fabs (l-r)>=1e-5 ); printf ("%f\n" ,mid); return 0 ; }
输出以下图案:1 2 3 4 5 6 7 * *** ***** ******* ***** *** *
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include <stdio.h> int main () { int i,j; for (i=0 ;i<4 ;i++) { for (j=0 ;j<3 -i;j++) printf (" " ); for (j=0 ;j<2 *i+1 ;j++) printf ("*" ); printf ("\n" ); } for (i=2 ;i>=0 ;i--) { for (j=0 ;j<3 -i;j++) printf (" " ); for (j=0 ;j<2 *i+1 ;j++) printf ("*" ); printf ("\n" ); } return 0 ; }
两个乒乓球队进行比赛,各出3人。甲队为A,B,C 3人,乙队为X,Y,Z 3人。已抽签决定比赛名单。有人向队员打听比赛的名单,A所他不和X比,C所他不和X,Z比,请编程序找出3对赛手的名单。
1 2 3 4 5 6 7 8 9 10 11 12 #include <stdio.h> int main () { char A,B,C,X='X' ,Y='Y' ,Z='Z' ; for (A=X;A<=Z;A++) for (B=X;B<=Z;B++) for (C=X;C<=Z;C++) if (A!=B&&B!=C&&A!=C) if (A!=X&&C!=X&&C!=Z) printf ("A-%c B-%c C-%c\n" ,A,B,C); return 0 ; }
注:本章习题13~15所用的方法,可参考《C程序设计(第五版)学习辅导》第5章习题解答中的介绍。
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。