本文所列习题答案均不含解释说明类题目。
第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)求方程式 a x 2 + b x + c = 0 的根。分别考虑: ①有两个不等的实根; ②有两个相等的实根。
用N-S图表示第4题中各题的算法。
用伪代码表示第4题中各题的算法。
什么叫结构化程序设计?它的主要内容是什么?
用自顶向下、逐步细化的方法进行以下算法的设计: (1)输出1900—2000年中是闰年的年份,符合下面两个条件之一的年份是闰年: ①能被4整除但不能被100整除; ②能被100整除且能被400整除。 (2)求 a x 2 + b x + c = 0 的根。分别考虑 d = b 2 − 4 a c 大于0、等于0和小于0这3种情况。 (3)输入10个数,输出其中最大的一个数。
第4题中各题的C程序代码如下: (1)
(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)
(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>
第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>
(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 + r 4 ) 4 n 。
说明: 1000 ∗ ( 1 + 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 = log p − log ( p − d × r ) log ( 1 + r ) 可以将公式改写为m = log ( p p − d × 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 ≤ 200 000)时,低于100 000元的部分按10%提成,高于100 000元的部分,可提成7.5%;200 000 < I ≤ 400 000时,低于200 000元的部分仍按上述办法提成(下同)。高于200 000元的部分按5%提成;400 000 < I ≤ 600 000元时,高于400 000元的部分按3%提成;600 000 < I ≤ 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个整数,要求按由小到大的顺序输出。
有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”时执行循环体的次数。
【例 5.7】
【例 5.7】用公式 π 4 ≈ 1 − 1 3 + 1 5 − 1 7 + ⋯ 求 π 的近似值,直到发现某一项的绝对值小于 10 − 6 为止(该项不累加)。
编写程序:
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 sign= 1 ; double pi= 0.0 ,n= 1.0 ,term= 1.0 ; while ( fabs (term)>= 1e-6 ) { pi=pi+term; n=n+ 2 ; sign=-sign; term=sign/n; } pi=pi* 4 ; printf ( "pi=%10.8f\n" ,pi); 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> # 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 + a a + a a a + ⋯ + n 个 a a a ⋯ 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 ; }
求 ∑ 20 n = 1 n ! (即求 1 ! + 2 ! + 3 ! + 4 ! + ⋯ + 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 ; }
求 ∑ 100 k = 1 k + ∑ 50 k = 1 k 2 + ∑ 10 k = 1 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 ; }
有一个分数序列2 1 , 3 2 , 5 3 , 8 5 , 13 8 , 21 8 , ⋯ 求出这个数列的前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 = √ a 。求平方根的迭代公式为x n + 1 = 1 2 ( x n + 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>
用牛顿迭代法求下面方程在1.5附近的根:2 x 3 − 4 x 2 + 3 x − 6 = 0
牛顿迭代法(牛顿切线法)假设一个接近根的值 x 0 求出 f ( x 0 ) ,过该点作切线,交 x 轴于 ( x 1 , 0 ) ,用 x 1 代替 x 0 重复操作,最后得到的值会慢慢接近真正的根 x ∗ 。 由 f ′ ( x 0 ) = f ( x 0 ) x 0 − x 1 ,得 x 1 = x 0 − 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 ) 的根:2 x 3 − 4 x 2 + 3 x − 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章习题解答中的介绍。
第6章 利用数组处理批量数据
用筛选法求100之内的素数。
①先把1挖掉; ②把2标记为素数,将2的其他倍数挖掉; ③把3标记为素数,将3的其他倍数挖掉; ④4被挖掉,跳过; ⑤……
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 # include <stdio.h> int main () { int notprime[ 105 ]={ 0 },i,j; notprime[ 1 ]= 1 ; for (i= 2 ;i<= 100 ;i++) { if (!notprime[i]) { printf ( "%d\n" ,i); for (j= 2 ;i*j<= 100 ;j++) notprime[i*j]= 1 ; } } return 0 ; }
用选择法对10个整数排序。
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> int main () { int a[ 10 ],i,j,t,min; for (i= 0 ;i< 10 ;i++) scanf ( "%d" ,&a[i]); for (i= 0 ;i< 9 ;i++) { min=i; for (j=i+ 1 ;j< 10 ;j++) { if (a[j]<a[min]) min=j; } t=a[i]; a[i]=a[min]; a[min]=t; } for (i= 0 ;i< 10 ;i++) printf ( "%d " ,a[i]); printf ( "\n" ); return 0 ; }
求一个 3 × 3 的整型矩阵对角线元素之和。
1 2 3 4 5 6 7 8 9 10 11 12 # include <stdio.h> int main () { int a[ 3 ][ 3 ],i,j,s= 0 ; for (i= 0 ;i< 3 ;i++) for (j= 0 ;j< 3 ;j++) scanf ( "%d" ,&a[i][j]); for (i= 0 ;i< 3 ;i++) s+=a[i][i]; printf ( "%d\n" ,s); return 0 ; }
有一个已排好序的数组,要求输入一个数后,按原来排序的规律将它插入数组中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 # include <stdio.h> int main () { int a[ 11 ],b,i,pos; for (i= 0 ;i< 10 ;i++) scanf ( "%d" ,&a[i]); scanf ( "%d" ,&b); for (i= 0 ;i< 10 ;i++) if (b<a[i]) break ; pos=i; for (i= 10 ;i>pos;i--) a[i]=a[i -1 ]; a[pos]=b; for (i= 0 ;i<= 10 ;i++) printf ( "%d " ,a[i]); printf ( "\n" ); return 0 ; }
将一个数组中的值按逆序重新存放。例如,原来顺序为8,6,5,4,1。要求改为1,4,5,6,8。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 # include <stdio.h> int main () { int a[ 5 ],i,t; for (i= 0 ;i< 5 ;i++) scanf ( "%d" ,&a[i]); for (i= 0 ;i< 5 / 2 ;i++) { t=a[i]; a[i]=a[ 4 -i]; a[ 4 -i]=t; } for (i= 0 ;i< 5 ;i++) printf ( "%d " ,a[i]); printf ( "\n" ); return 0 ; }
输出以下的杨辉三角形(要求输出10行)。
1
1
1
1
2
1
1
3
3
1
1
4
6
4
1
1
5
10
10
5
1
⋮
⋮
⋮
⋮
⋮
⋮
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 # include <stdio.h> int main () { int a[ 10 ][ 10 ],i,j; for (i= 0 ;i< 10 ;i++) a[i][ 0 ]=a[i][i]= 1 ; for (i= 2 ;i< 10 ;i++) for (j= 1 ;j<i;j++) a[i][j]=a[i -1 ][j -1 ]+a[i -1 ][j]; for (i= 0 ;i< 10 ;i++) { for (j= 0 ;j<=i;j++) printf ( "%d " ,a[i][j]); printf ( "\n" ); } return 0 ; }
输出“魔方阵”。所谓魔方阵是指这样的方阵,它的每一行、每一列和对角线之和均相等。例如,三阶魔方阵为 8 1 6 3 5 7 4 9 2 要求输出 1 ~ n 2 的自然数构成的魔方阵。
奇数阶魔方阵的生成规律如下: ① 1 位于第 1 行第 n + 1 2 列; ② 2 到 n 2 的各数,每一个数存放的行比前一个数少 1 ,若前一个数已放在第 1 行,则这一个放在第 n 行; ③ 2 到 n 2 的各数,每一个数存放的列比前一个数多 1 ,若前一个数已放在第 n 列,则这一个放在第 1 列; ④ 若当前数要放的位置已经有数,则存放到前一个数同一列的下一行的位置,若前一个数已放在第 n 行,则这一个放在第 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 35 36 37 38 39 40 41 42 # include <stdio.h> int main () { int a[ 11 ][ 11 ],i,j,k,n; scanf ( "%d" ,&n); if (n% 2 == 0 ) { printf ( "Only Odd Number!\n" ); return 0 ; } for (i= 1 ;i<=n;i++) for (j= 1 ;j<=n;j++) a[i][j]= 0 ; i= 1 ; j=(n+ 1 )/ 2 ; a[i][j]= 1 ; for (k= 2 ;k<=n*n;k++) { if (i== 1 )i=n; else i--; if (j==n)j= 1 ; else j++; if (a[i][j]) { if (i==n)i= 1 ; else i++; if (j== 1 )j=n; else j--; if (i==n)i= 1 ; else i++; } a[i][j]=k; } for (i= 1 ;i<=n;i++) { for (j= 1 ;j<=n;j++) printf ( "%2d " ,a[i][j]); printf ( "\n" ); } return 0 ; }
找出一个二维数组中的鞍点,即该位置上的元素在该行上最大、在该列上最小。也可能没有鞍点。
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 # include <stdio.h> int main () { int a[ 5 ][ 5 ],i,j,max,flag,num= 0 ; for (i= 0 ;i< 5 ;i++) for (j= 0 ;j< 5 ;j++) scanf ( "%d" ,&a[i][j]); for (i= 0 ;i< 5 ;i++) { max= 0 ; flag= 1 ; for (j= 0 ;j< 5 ;j++) max=a[i][max]<a[i][j]?j:max; for (j= 0 ;j< 5 ;j++) if (a[i][max]>a[j][max]) { flag= 0 ; break ; } if (flag) { printf ( "a[%d][%d]=%d\n" ,i,max,a[i][max]); num++; } } if (!num) printf ( "It does not exist!\n" ); return 0 ; }
有15个数按由大到小顺序存放在一个数组中,输入一个数,要求用折半查找法找出该数是数组中第几个元素的值。如果该数不在数组中,则输出“无此数”。
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 # include <stdio.h> int main () { int a[ 15 ],b,i,l= 0 ,r= 14 ,mid; for (i= 0 ;i< 15 ;i++) scanf ( "%d" ,&a[i]); scanf ( "%d" ,&b); while (l<r) { mid=(l+r)/ 2 ; if (a[mid]>b) l=mid+ 1 ; else if (a[mid]<b) r=mid -1 ; else { l=r=mid; break ; } } if (a[l]==b) printf ( "a[%d]=%d\n" ,l,b); else printf ( "No Found!\n" ); return 0 ; }
有一篇文章,共有3行文字,每行有80个字符。要求分别统计出其中英文大写字母、小写字母、数字、空格以及其它字符的个数。
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,dx= 0 ,xx= 0 ,sz= 0 ,kg= 0 ,qt= 0 ; char s[ 3 ][ 81 ]; for (i= 0 ;i< 3 ;i++) { gets(s[i]); for (j= 0 ;s[i][j]!= '\0' ;j++) { if (s[i][j]>= 'A' &&s[i][j]<= 'Z' ) dx++; else if (s[i][j]>= 'a' &&s[i][j]<= 'z' ) xx++; else if (s[i][j]== ' ' ) kg++; else if (s[i][j]>= '0' &&s[i][j]<= '9' ) sz++; else qt++; } } printf ( "dx=%d,xx=%d,sz=%d,kg=%d,qt=%d\n" ,dx,xx,sz,kg,qt); return 0 ; }
输出以下图案:1 2 3 4 5 * * * * * * * * * * * * * * * * * * * * * * * * *
1 2 3 4 5 6 7 8 9 10 11 12 13 14 # include <stdio.h> int main () { int i,j; for (i= 0 ;i< 5 ;i++) { for (j= 0 ;j<i;j++) printf ( " " ); for (j= 0 ;j< 5 ;j++) printf ( "* " ); printf ( "\n" ); } return 0 ; }
有一行电文,已按下面规律译成密码: A→Z a→z B→Y b→y C→X C→x⋮ ⋮ 即第1个字母变成第26个字母,第i个字母变成第(26-i+1)个字母,非字母字符不变。要求编程序将密码译回原文,并输出密码和原文。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 # include <stdio.h> int main () { int i; char s[ 100 ]; gets(s); printf ( "%s\n" ,s); for (i= 0 ;s[i]!= '\0' ;i++) { if (s[i]>= 'A' &&s[i]<= 'Z' ) s[i]= 25 -(s[i]- 'A' )+ 'A' ; if (s[i]>= 'a' &&s[i]<= 'z' ) s[i]= 25 -(s[i]- 'a' )+ 'a' ; } printf ( "%s\n" ,s); return 0 ; }
编一程序,将两个字符串连接起来,不要用strcat函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 # include <stdio.h> int main () { int i,j; char s1[ 200 ],s2[ 100 ]; gets(s1); gets(s2); for (i= 0 ;s1[i]!= '\0' ;i++); for (j= 0 ;s2[j]!= '\0' ;i++,j++) s1[i]=s2[j]; s1[i]= '\0' ; printf ( "%s\n" ,s1); return 0 ; }
编一个程序,将两个字符串s1和s2比较,若s1>s2,输出一个正数;若s1=s2,输出0;若s1<s2,输出一个负数。不要用strcpy函数。两个字符串用gets函数读入。输出的正数或负数的绝对值应是相比较的两个字符串相应字符的ASCII码的差值。例如,”A”与”C”相比,由于”A”<”C”,应输出负数,同时由于’A’与’C’的ASCII码差值为2,因此应输出“-2”。同理:”And”和”Aid”比较,根据第2个字符比较结果,”n”比”i”大5,因此应输出“5”。
1 2 3 4 5 6 7 8 9 10 11 # include <stdio.h> int main () { int i; char s1[ 200 ],s2[ 100 ]; gets(s1); gets(s2); for (i= 0 ;s1[i]==s2[i]&&s1[i]!= '\0' ;i++); printf ( "%d\n" ,s1[i]-s2[i]); return 0 ; }
编写一个程序,将字符数组s2中的全部字符复制到字符数组s1中。不用strcpy函数。复制时,’\0’也要复制过去。’\0’后面的字符不复制。
1 2 3 4 5 6 7 8 9 10 11 12 13 # include <stdio.h> int main () { int i; char s1[ 200 ],s2[ 100 ]; gets(s1); gets(s2); for (i= 0 ;s2[i]!= '\0' ;i++) s1[i]=s2[i]; s1[i]= '\0' ; printf ( "%s\n" ,s1); return 0 ; }
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。
预览: