- C primer plus编程练习
- 第一章初识C语言
- 第二章 C语言概述
- 第三章 数据和C
- 第四章 字符串的格式化输入/输出
- 第五章 运算符,表达式和语句
- 第六章 C控制语句:循环
- 第七章 C 控制语句:分之合跳转
- 第八章 字符输入/输出和输入验证
- 第九章 函数
- 第十章 数组和指针
- 第十一章 字符串和字符串函数
- 你刚被MacroMuscle有限公司聘用。该公司准备进入欧洲市场,需要一个把英寸单位转换为厘米单位(1英寸=2.54厘米)的程序。该程序要提示用户输入英寸值。你的任务是定义程序目标和设计程序。
#include第二章 C语言概述#define cm 2.54//宏定义 英寸转换厘米 int main(void) { float inch = 1.0;//英寸 printf("请输入英寸值:"); scanf_s("%f", &inch); printf("%.3f英寸等于%.3f厘米n", inch, inch * cm); printf("程序结束n"); return 0; }
- 编写一个程序,调用一次 printf()函数,把你的姓名打印在一行。再调用一次 printf()函数,把你的姓名分别打印在两行。然后,再调用两次printf()函数,把你的姓名打印在一行。输出应如下所示(当然要把示例的内容换成你的姓名):
#includeint main(void) { printf("Gustav Mahlern"); printf("GustavnMahlern"); printf("Gustav "); printf("Mahlern"); return 0; }
- .编写一个程序,打印你的姓名和地址。
#includeint main(void) { printf("my name is jo,i live in sdn"); return 0; }
- 编写一个程序把你的年龄转换成天数,并显示这两个值。这里不用考虑闰年的问题。
#includeint main(void) { int ageyears; int agedays; ageyears = 30; agedays = 365 * ageyears; printf("出生年数%d,俺出生的天数是%dn",ageyears,agedays); return 0; }
- 编写一个程序,生成以下输出:
For he’s a jolly good fellow!
For he’s a jolly good fellow!
For he’s a jolly good fellow!
Which nobody can deny!
除了 main()函数以外,该程序还要调用两个自定义函数:一个名为jolly(),用于打印前 3 条消息,调用一次打印一条;另一个函数名为deny(),打印最后一条消息。
#includevoid jolly(void); void deny(void); int main(void) { jolly(); deny(); return 0; } void jolly(void) { printf("First he's a jolly good fellow!n"); printf("First he's a jolly good fellow!n"); printf("First he's a jolly good fellow!n"); } void deny(void) { printf("Which nobody can deny!n"); }
- .编写一个程序,生成以下输出:
Brazil, Russia, India, China India, China, Brazil, Russia
除了main()以外,该程序还要调用两个自定义函数:一个名为br(),调用一次打印一次“Brazil, Russia”;另一个名为ic(),调用一次打印一次“India,China”。其他内容在main()函数中完成。
#includevoid br(void) { printf("Brazil,Russian"); } void ic(void) { printf("India,Russian"); } int main(void) { printf("Brazil,Russia,India,Chinan"); ic(); br(); return 0; }
- 编写一个程序,创建一个整型变量toes,并将toes设置为10。程序中还要计算toes的两倍和toes的平方。该程序应打印3个值,并分别描述以示区分。
#include#define toes 10 int dob_toes ; int toes_sq ; int main() { dob_toes = toes * 2; toes_sq = toes * toes; printf("toes = %d ,dob_toes = %d, toes_sq = %d" ,toes,dob_toes,toes_sq); return 0; }
- .许多研究表明,微笑益处多多。编写一个程序,生成以下格式的输出:
Smile!Smile!Smile! Smile!Smile! Smile!
该程序要定义一个函数,该函数被调用一次打印一次“Smile!”,根据程序的需要使用该函数。
#includevoid po(void); void ptw(void); void pth(void); int main() { pth(); ptw(); po(); return 0; } void pth(void) { printf("smile!smile!smile!n"); } void ptw(void) { printf("smile!smile!n"); } void po(void) { printf("smile!n"); }
- ** 在C语言中,函数可以调用另一个函数。编写一个程序,调用一个名为one_three()的函数。该函数在一行打印单词“one”,再调用第2个函数two(),然后在另一行打印单词“three”。two()函数在一行显示单词“two”。main()函数在调用 one_three()函数前要打印短语“starting now:”,并在调用完毕后显示短语“done!”。因此,该程序的输出应如下所示:**
starting now: one two three done!
#include第三章 数据和Cvoid one_three(void); void two(void); int main(void) { printf("starting now :n"); one_three(); printf("done!"); return 0; } void one_three(void ) { printf("onen"); two(); printf("threen"); } void two(void) { printf("twon"); }
- 通过试验(即编写带有此类问题的程序)观察系统如何处理整数上溢、浮点数上溢和浮点数下溢的情况。
#include#include int main() { int a = 2147483647; float b = 3.4E38 * 100.0f; float c = (3.4E-38) / (100.0E100); printf("%d %d %dn", a, a+1, a+2); //整数上溢 printf("%en", b); //浮点数上溢 printf("%e", c); //浮点数下溢 return 0; }
- 编写一个程序,要求提示输入一个ASCII码值(如,66),然后打印输入的字符。
#includeint main(void) { int i ; printf("please input a number like 66 :"); scanf("%d",&i); printf("%c",i); return 0; }
- 编写一个程序,发出一声警报,然后打印下面的文本:
Startled by the sudden sound, Sally shouted, "By the Great Pumpkin, what was that!"
#include#include int main(void) { printf("aStartled by the sudden sound,Sally shouted,n" ""By the Great Pumpkin,what was that!""); return 0; }
- 编写一个程序,读取一个浮点数,先打印成小数点形式,再打印成指数形式。然后,如果系统支持,再打印成p记数法(即十六进制记数法)。按以下格式输出(实际显示的指数位数因系统而异):
Enter a floating-point value: 64.25 fixed-point notation: 64.250000 exponential notation: 6.425000e+01 p notation: 0x1.01p+6
#include#include int main(void) { printf("aStartled by the sudden sound,Sally shouted,n" ""By the Great Pumpkin,what was that!""); return 0; }
- 一年大约有3.156×107秒。编写一个程序,提示用户输入年龄,然后显示该年龄对应的秒数。
#includeint main(void) { int year; printf("input your age:"); scanf("%d",&year); long long second; second = year * (3.156*10e7); printf("you have live %lld seconds",second); return 0; }
- 一个水分子的质量约为3.0×10−23克。1夸脱水大约是950克。编写一个程序,提示用户输入水的夸脱数,并显示水分子的数量。
#includeint main(void) { float mass_mol =3.0e-23; float mass_qt = 950; float quarts; float molecules; printf("Enter the number of quarters of water:"); scanf("%f",&quarts); molecules = quarts * mass_qt / mass_mol; printf("%f quarts of water contain %e molecules.n",quarts,molecules); return 0; }
- 1英寸相当于2.54厘米。编写一个程序,提示用户输入身高(/英寸),然后以厘米为单位显示身高。
#includeint main(void) { float i; float h; printf("input the inch of your height:n"); scanf("%f",&i); h = 2.54 * i; printf("your hight is %.2fcm!n",h); return 0; }
- 在美国的体积测量系统中,1品脱等于2杯,1杯等于8盎司,1盎司等于2大汤勺,1大汤勺等于3茶勺。编写一个程序,提示用户输入杯数,并以品脱、盎司、汤勺、茶勺为单位显示等价容量。思考对于该程序,为何使用浮点类型比整数类型更合适?
#include第四章 字符串的格式化输入/输出int main() { float cup; printf("Enter the cup number:"); scanf("%f",&cup); printf("%.1f杯等于 %.1f 品脱n",cup,cup/2); printf("%.1f杯等于 %.1f 盎司n",cup,cup*8); printf("%.1f杯等于 %.1f 大汤勺n",cup,cup*8*2); printf("%.1f杯等于 %.1f 茶勺n",cup,cup*8*3*2); return 0; }
- .编写一个程序,提示用户输入名和姓,然后以“名,姓”的格式打印出
来。
#include#include int main(void) { char char1[20],char2[20]; printf("please input your first name and your last name:n"); scanf("%s%s",&char1,&char2); printf("%s,%s",char1,char2); return 0; }
- 编写一个程序,提示用户输入名和姓,并执行一下操作:
a.打印名和姓,包括双引号;
b.在宽度为20的字段右端打印名和姓,包括双引号;
c.在宽度为20的字段左端打印名和姓,包括双引号;
d.在比姓名宽度宽3的字段中打印名和姓。
#include#include int main(void) { char string1[20]; int len; printf("input your first name and last name:like firstname,lastnamen"); scanf("%s",&string1); len = strlen(string1); printf(""%s"n",string1); printf("%20sn",string1); printf("%-20sn",string1); printf("%*sn",len+3,string1); return 0; }
- 编写一个程序,读取一个浮点数,首先以小数点记数法打印,然后以指数记数法打印。用下面的格式进行输出(系统不同,指数记数法显示的位数可能不同):
a.输入21.3或2.1e+001;
b.输入+21.290或2.129E+001;
#includeint main(void) { float num; printf("Please enter a float number:n"); scanf("%f",&num); printf("The input is %.1f or %.1e.n",num,num); return 0; }
- 编写一个程序,提示用户输入身高(单位:英寸)和姓名,然后以下面的格式显示用户刚输入的信息:
Dabney, you are 6.208 feet tall
使用float类型,并用/作为除号。如果你愿意,可以要求用户以厘米为单位输入身高,并以米为单位显示出来。
#include#define LEN 30 int main(void) { float heigh; char name[LEN]; printf("please enter your name:n"); scanf("%29s",&name); printf("Hello!%s,how tall you are (inch):",name); scanf("%f",&heigh); printf("%s,you r %.3f feet tall.n",name,heigh/12.0); return 0; }
- 编写一个程序,提示用户输入以兆位每秒(Mb/s)为单位的下载速度和以兆字节(MB)为单位的文件大小。程序中应计算文件的下载时间。注意,这里1字节等于8位。使用float类型,并用/作为除号。该程序要以下面的格式打印 3 个变量的值(下载速度、文件大小和下载时间),显示小数点后面两位数字:
At 18.12 megabits per second, a file of 2.20 megabytes downloads in 0.97 seconds.
#includeint main(void) { int BIT = 8; float speed ,size,time; printf("Please enter net speed(Mbit/s):"); scanf("%f", &speed); printf("Please enter file size(MB):"); scanf("%f", &size); time = size * BIT / speed; printf("At %.2f megabits per secnod, ", speed); printf("a file of %.2f megabytes ", size); printf("downloads in %.2f seconds.n", time); return 0; }
- 编写一个程序,先提示用户输入名,然后提示用户输入姓。在一行打印用户输入的名和姓,下一行分别打印名和姓的字母数。字母数要与相应名和姓的结尾对齐,如下所示:
Melissa Honeybee 7 8
接下来,再打印相同的信息,但是字母个数与相应名和姓的开头对齐,
如下所示:
Melissa Honeybee
#include#include int main(void) { int x, y; char fname[20], lname[20]; printf("Please enter your first name: "); scanf("%19s", fname); printf("Please enter your last name: "); scanf("%19s", lname); x = strlen(fname); y = strlen(lname); printf("%s %sn", fname, lname); printf("%*d %*dn", x, x, y, y); printf("%s %sn", fname, lname); printf("%-*d %-*dn", x, x, y, y); return 0; }
- 编写一个程序,将一个double类型的变量设置为1.0/3.0,一个float类型的变量设置为1.0/3.0。分别显示两次计算的结果各3次:一次显示小数点后面6位数字;一次显示小数点后面12位数字;一次显示小数点后面16位数字。程序中要包含float.h头文件,并显示FLT_DIG和DBL_DIG的值。1.0/3.0的值与这些值一致吗?
#include#include int main(void) { float f_value = 1.0 / 3.0; double d_value = 1.0 / 3.0; printf("1.0 / 3.0 display 6 decimal places:n"); printf("f_value = %.6fnd_value = %.6lfn", f_value, d_value); printf("n1.0 / 3.0 display 12 decimal places:n"); printf("f_value = %.12fnd_value = %.12lfn", f_value, d_value); printf("n1.0 / 3.0 display 16 decimal places:n"); printf("f_value = %.16fnd_value = %.16lfn", f_value, d_value); printf("nfloat and double maximum significant digits:n"); printf("FLT_DIG = %d, DBL_DIG = %dn", FLT_DIG, DBL_DIG); //↑FLTDIG代表float有效十进制数字位数; //↑DBL_DIG代表double有效十进制数字位数; return 0; }
- 编写一个程序,提示用户输入旅行的里程和消耗的汽油量。然后计算并显示消耗每加仑汽油行驶的英里数,显示小数点后面一位数字。接下来,使用1加仑大约3.785升,1英里大约为1.609千米,把单位是英里/加仑的值转换为升/100公里(欧洲通用的燃料消耗表示法),并显示结果,显示小数点后面 1 位数字。注意,美国采用的方案测量消耗单位燃料的行程(值越大越好),而欧洲则采用单位距离消耗的燃料测量方案(值越低越好)。使用#define 创建符号常量或使用 const 限定符创建变量来表示两个转换系数。
#include第五章 运算符,表达式和语句#define GALLON_TO_LITRE 3.785f #define MILE_TO_KM 1.609f int main(void) { float range, oil; printf("Please input the range you traveled(in mile):"); scanf("%f", &range); printf("Please input the oil you spend(in gallon):"); scanf("%f", &oil); printf("Fuel consumptions:n"); printf("In USA, your oil wear is %.1f mile/gallon.n", range / oil); printf("In Europe, your oil wear is "); printf("%.1f litre/100km.n", (oil * GALLON_TO_LITRE) / (range * MILE_TO_KM)); return 0; }
编写一个程序,把用分钟表示的时间转换成用小时和分钟表示的时间。使用#define或const创建一个表示60的符号常量或const变量。通过while循环让用户重复输入值,直到用户输入小于或等于0的值才停止循环。
#includeint main(void) { const int minperhour = 60; int minutes,hours,mins; printf("Enter the number of minutes to convert:"); scanf("%d",&minutes); while(minutes>0) { hours = minutes / minperhour; mins = minutes % minperhour; printf("%d minutes = %d hours,%d minutesn ",minutes,hours,mins); printf("Enter next value (0 to quit):"); scanf("%d",&minutes); } printf("Byen"); return 0; }
- 编写一个程序,提示用户输入一个整数,然后打印从该数到比该数大10的所有整数(例如,用户输入5,则打印5~15的所有整数,包括5和15)。要求打印的各值之间用一个空格、制表符或换行符分开。
#includeint main(void) { int i; printf("please input a number :"); scanf("%d",&i); for(int j=i;j<=i+10;j++) { printf("%d ",j); } return 0; }
- 编写一个程序,提示用户输入天数,然后将其转换成周数和天数。例如,用户输入18,则转换成2周4天。以下面的格式显示结果:编写一个程序,提示用户输入天数,然后将其转换成周数和天数。例如,用户输入18,则转换成2周4天。以下面的格式显示结果:
18 days are 2 weeks, 4 days.
通过while循环让用户重复输入天数,当用户输入一个非正值时(如0或-20),循环结束。
#includeint main(void) { const int daysperweek = 7; int days,weeks,day_rem; printf("Enter the number of days:"); scanf("%d",&days); while(days>0) { weeks = days/daysperweek; day_rem = days % daysperweek; printf("%d day are %d weeks and %d days.n",days,weeks,day_rem); printf("Enter the number of days(0 or less to end:"); scanf("%d",&days); } printf("Done!n"); return 0; }
- 编写一个程序,提示用户输入一个身高(单位:厘米),并分别以厘米和英寸为单位显示该值,允许有小数部分。程序应该能让用户重复输入身高,直到用户输入一个非正值。其输出示例如下:
182.0 cm = 5 feet, 11.7 inches Enter a height in centimeters (<=0 to quit): 168.7 168.0 cm = 5 feet, 6.4 inches Enter a height in centimeters (<=0 to quit): 0 bye
#include#define FEET_TO_CM 30.48 #define INCH_TO_CM 2.54 int main() { int feet = 0; float inches = 0, cm = 0; printf("Input the hight in centimeters:"); scanf("%f", &cm); while(cm > 0) { feet = cm / FEET_TO_CM; inches = (cm - feet*FEET_TO_CM) / INCH_TO_CM; printf("%.1f cm = %d feet, %.1f inchesn", cm, feet, inches); printf("Input the hight in centimeters( <= 0 to Quit):"); scanf("%f", &cm); } printf("Proram Exit!"); return 0; }
- 修改程序addemup.c(程序清单5.13),你可以认为addemup.c是计算20天里赚多少钱的程序(假设第1天赚$1、第2天赚$2、第3天赚$3,以此类推)。修改程序,使其可以与用户交互,根据用户输入的数进行计算(即,用读入的一个变量来代替20)。
#includeint main(void) { int count ,sum; int n; printf("Enter the upper limit:"); scanf("%d",&n); count = 0; sum = 0; while(count++
- 修改编程练习5的程序,使其能计算整数的平方和(可以认为第1天赚$1、第2天赚$4、第3天赚$9,以此类推,这看起来很不错)。C没有平方函数,但是可以用n * n来表示n的平方。
#includeint main(void) { int count ,sum; int n; printf("Enter the upper limit:"); scanf("%d",&n); count = 0; sum = 0; while(count++ int j ; j= count*count; sum = sum + j; } printf("sum = %dn",sum); return 0; }
- 编写一个程序,提示用户输入一个double类型的数,并打印该数的立方值。自己设计一个函数计算并打印立方值。main()函数要把用户输入的值传递给该函数。
#includevoid showCube(double x) { printf("The cube of %e is %e.n",x,x*x*x); } int main(void) { double val; printf("Enter a float-point value:"); scanf("%lf",&val); showCube(val); return 0; }
- .编写一个程序,显示求模运算的结果。把用户输入的第1个整数作为求模运算符的第2个运算对象,该数在运算过程中保持不变。用户后面输入的数是第1个运算对象。当用户输入一个非正值时,程序结束。其输出示例如下:
This program computes moduli. Enter an integer to serve as the second operand: 256 Now enter the first operand: 438 438 % 256 is 182 Enter next number for first operand (<= 0 to quit): 1234567 1234567 % 256 is 135 Enter next number for first operand (<= 0 to quit): 0 Done#includeint main(void) { int first ,second; printf("This program computer moduli.n"); printf("Enter an integer to server as the second operand:"); scanf("%d",&second); printf("Now enter the first operand:"); scanf("%d",&first); while(first>0) { printf("%d %% %d is %dn",first ,second,(first % second)); printf("Enter next number for first operand(<=0 to quit):"); scanf("%d",&first); } printf("Done!n"); return 0; }
编写一个程序,要求用户输入一个华氏温度。程序应读取double类型的值作为温度值,并把该值作为参数传递给一个用户自定义的函数Temperatures()。该函数计算摄氏温度和开氏温度,并以小数点后面两位数字的精度显示3种温度。要使用不同的温标来表示这3个温度值。下面是华氏温度转摄氏温度的公式:
摄氏温度 = 5.0 / 9.0 * (华氏温度 - 32.0)
开氏温标常用于科学研究,0表示绝对零,代表最低的温度。下面是摄氏温度转开氏温度的公式:
开氏温度 = 摄氏温度 + 273.16
Temperatures()函数中用const创建温度转换中使用的变量。在main()函数中使用一个循环让用户重复输入温度,当用户输入 q 或其他非数字时,循环结束。scanf()函数返回读取数据的数量,所以如果读取数字则返回1,如果读取q则不返回1。可以使用==运算符将scanf()的返回值和1作比较,测试两值是否相等。#include第六章 C控制语句:循环void Temperatures(double fahrenheit) { const double F_TO_C = 32.0; const double C_TO_T = 273.16; double celsius,kelvin; celsius = 5.0 / 9.0 * (fahrenheit - F_TO_C); kelvin = celsius + C_TO_T; printf("%.2f.fahrenheit,equal %.2f celsius,and %.2f kelvinn",fahrenheit,celsius,kelvin); } int main(void) { double input; printf("This programmer convert fahrenheit to celsius and kelvin.n"); printf("Enter a fahrenheit to start:"); while(scanf("%lf",&input)==1) { Temperatures(input); printf("Enter next fahrenheit!(q to quit):"); } printf("Done!n"); return 0; }
- 编写一个程序,创建一个包含26个元素的数组,并在其中储存26个小写字母。然后打印数组的所有内容。
#include#define N 26 int main(void) { char char1[N]; int i; for(i=0;i 2.使用嵌套循环,按下面的格式打印字符:
$ $$ $$$ $$$$ $$$$$#includeint main(void) { int i,j; for(i=0;i<5;i++) { for(j=0;j
- 使用嵌套循环,按下面的格式打印字母:
F FE FED FEDC FEDCB FEDCBA注意:如果你的系统不使用ASCII或其他以数字顺序编码的代码,可以把字符数组初始化为字母表中的字母:char lets[27] =“ABCDEFGHIJKLMNOPQRSTUVWXYZ”;402然后用数组下标选择单独的字母,例如lets[0]是‘A’,等等。
#includeint main(void) { char ch = 'F'; int i,j; for(i=0;i<6;i++) { int k= 0; for(j= 0;j printf("%c",ch-k); k++; } printf("n"); } return 0; } 4.使用嵌套循环,按下面的格式打印字母:
A BC DEF GHIJ KLMNO PQRSTU如果你的系统不使用以数字顺序编码的代码,请参照练习3的方案解决。
#includeint main(void) { char ch = 'A'; int i,j; int k= 0; for(i=0;i<6;i++) { for(j= 0;j printf("%c",ch+k); k++; } printf("n"); } return 0; } 5.编写一个程序,提示用户输入大写字母。使用嵌套循环以下面金字塔型的格式打印字母:
A ABA ABCBA ABCDCBA ABCDEDCBA打印这样的图形,要根据用户输入的字母来决定。例如,上面的图形是在用户输入E后的打印结果。提示:用外层循环处理行,每行使用3个内层循环,分别处理空格、以升序打印字母、以降序打印字母。如果系统不使用ASCII或其他以数字顺序编码的代码,请参照练习3的解决方案。
#includeint main(void) { int line, line_all, row_blank, row_plus, row_minus; char ch; printf("please input :n"); scanf("%c", &ch, 1); line_all = ch - 'A' + 1; for (line = 1; line <= line_all; line++) { for (row_blank = 0; row_blank < line_all - line; row_blank++) printf("%c", ' '); for (row_plus = 0; row_plus < line; row_plus++) printf("%c", 'A' + row_plus); for (row_minus = line - 2; row_minus >= 0; row_minus--) printf("%c", 'A' + row_minus); printf("n"); } while(1); return 0; } 6.编写一个程序打印一个表格,每一行打印一个整数、该数的平方、该数的立方。要求用户输入表格的上下限。使用一个for循环。
#includeint main(void) { int lower,upper,index; int square,cube; printf("Enter starting integer:"); scanf("%d",&lower); printf("Enter ending integer:"); scanf("%d",&upper); printf("%5s %10s %15sn","num","square","cube"); for(index =lower;index <= upper;index++) { square = index * index; cube = index * square; printf("%5d %10d %15dn",index,square,cube); } return 0; }
- 编写一个程序把一个单词读入一个字符数组中,然后倒序打印这个单词。提示:strlen()函数(第4章介绍过)可用于计算数组最后一个字符的下标。
#include#include int main(void) { char ch[30]; scanf("%s",&ch); int len = strlen(ch); for(int i=0;i printf("%c",ch[len-i-1]); } return 0; }
- 编写一个程序,要求用户输入两个浮点数,并打印两数之差除以两数乘积的结果。在用户输入非数字之前,程序应循环处理用户输入的每对值。
#includeint main(void) { double n,m; double res; while(scanf("%lf %lf",&n,&m)==2) { res = (n-m)/(n*m); printf("(%.3g - %.3g)/(%.3g * %.3g)=%.5gn",n,m,n,m,res); printf("Enter next pair (non-numeric to quit):"); } return 0; }
- 修改练习8,使用一个函数返回计算的结果。
#includefloat get(float,float); int main(void) { double n,m; double res; printf("input two float number:"); scanf("%f%f",&n,&m); res = get(n,m); printf("(%.3g - %.3g)/(%.3g * %.3g)=%.5gn",n,m,n,m,res); printf("Enter next pair (non-numeric to quit):"); return 0; } float get(float n,float m) { double res; res = (n-m)/(n*m); return res; }
- 编写一个程序,要求用户输入一个上限整数和一个下限整数,计算从上限到下限范围内所有整数的平方和,并显示计算结果。然后程序继续提示用户输入上限和下限整数,并显示结果,直到用户输入的上限整数小于下限整数为止。程序的运行示例如下:
Enter lower and upper integer limits: 5 9 The sums of the squares from 25 to 81 is 255 Enter next set of limits: 3 25 The sums of the squares from 9 to 625 is 5520 Enter next set of limits: 5 5 Done#includeint main(void) { int up,low,i; printf("Enter lower and upper integer limits:"); while(1) { int sum = 0; scanf("%d%d",&low,&up); if(up>low) { for(i=low;i<=up;i++) { sum += i*i; } printf("The sums of the squares from %d to %d is %dn",low,up,sum); } else { break; } printf("Enter next set of limits:n"); } printf("Done!"); return 0; } 11.编写一个程序,在数组中读入8个整数,然后按倒序打印这8个整数。
#include#define N 8 int main(void) { int i,ch[8]; printf("please input 8 numbers:"); for(i=0;i scanf("%d",&ch[i]); } for(i=N-1;i>=0;i--) { printf("%dt",ch[i]); } return 0; } 12
考虑下面两个无限序列:1.0 + 1.0/2.0 + 1.0/3.0 + 1.0/4.0 + ... 1.0 - 1.0/2.0 + 1.0/3.0 - 1.0/4.0 + ...编写一个程序计算这两个无限序列的总和,直到到达某次数。提示:奇数个-1 相乘得-1,偶数个-1相乘得1。让用户交互地输入指定的次数,当用户输入0或负值时结束输入。查看运行100项、1000项、10000项后的总和,是否发现每个序列都收敛于某值?
#includeint main(void) { float f1,f2,f3,f4; int a; printf("输入项数(小于等于0退出):"); while(scanf("%d",&a),a>0) { for(f1=0,f3=0,f2=1,f4=1; f2<=a;f2++,f4*=-1) { f1+=1.0/f2; f3+=1/(f2*f4); } printf("f1=%fnf3=%fn输入项数(小于等于0退出):",f1,f3); } return 0; }
- 编写一个程序,创建一个包含8个元素的int类型数组,分别把数组元素设置为2的前8次幂。使用for循环设置数组元素的值,使用do while循环显示数组元素的值。
#include#define Size 8 int main(void) { int twopows[Size]; int i; int value = 1; for(i = 0;i twopows[i]=value; value *= 2; } i = 0; do { printf("%dt",twopows[i]); i++; }while(i
编写一个程序,创建两个包含8个元素的double类型数组,使用循环提示用户为第一个数组输入8 个值。第二个数组元素的值设置为第一个数组对应元素的累积之和。例如,第二个数组的第 4个元素的值是第一个数组前4个元素之和,第二个数组的第5个元素的值是第一个数组前5个元素之和(用嵌套循环可以完成,但是利用第二个数组的第5个元素是第二个数组的第4个元素与第一个数组的第5个元素之和,只用一个循环就能完成任务,不需要使用嵌套循环)。最后,使用循环显示两个数组的内容,第一个数组显示成一行,第二个数组显示在第一个数组的下一行,而且每个元素都与第一个数组各元素相对应。
#include#define size 8 int main(void) { double arr[size]; double arr_cumul[size]; int i; printf("Enter %d numbers:n",size); for(i=0;i printf("value #%d:",i+1); scanf("%lf",&arr[i]); } arr_cumul[0]=arr[0]; for(i = 1;i
编写一个程序,读取一行输入,然后把输入的内容倒序打印出来。可以把输入储存在char类型的数组中,假设每行字符不超过255。回忆一下,根据%c转换说明,scanf()函数一次只能从输入中读取一个字符,而且在用户按下Enter键时scanf()函数会生成一个换行字符(n)。
#includeint main(void) { char ch[255]; int i = -1; printf("please input some charsn"); do { i++; scanf("%c", &ch[i]); } while (ch[i] != 'n'); for (; i >= 0; i--) { printf("%c", ch[i]); } return 0; }
- Daphne以10%的单利息投资了100美元(也就是说,每年投资获利相当于原始投资的10%)。Deirdre以 5%的复合利息投资了 100 美元(也就是说,利息是当前余额的 5%,包含之前的利息)。编写一个程序,计算需要多少年Deirdre的投资额才会超过Daphne,并显示那时两人的投资额。
#include#define RATE_SIMP 0.10 #define RATE_COMP 0.05 #define INIT_AMT 100.0 int main(void) { double daphne = INIT_AMT; double deidre = INIT_AMT; int years = 0; while(deidre<= daphne) { daphne += RATE_SIMP * INIT_AMT; deidre += RATE_COMP * deidre; ++years; } printf("Investment value after %d years:n",years); printf("Dephne:$%.2fn",daphne); printf("Deidre:$%.2fn",deidre); return 0; } 17
Chuckie Lucky赢得了100万美元(税后),他把奖金存入年利率8%的账户。在每年的最后一天, Chuckie取出10万美元。编写一个程序,计算多少年后Chuckie会取完账户的钱?#includeint main(void) { double award = 100.0; int year = 0; do{ year++; award = award * (1 + 0.08) - 10; }while (award > 0); printf("%d 年后Chuckie会取完账户的钱。n", year); getchar(); return 0; } 18
Rabnud博士加入了一个社交圈。起初他有5个朋友。他注意到他的朋友数量以下面的方式增长。第1周少了1个朋友,剩下的朋友数量翻倍第2
周少了2个朋友,剩下的朋友数量翻倍。一般而言,第N周少了N个朋友,剩下的朋友数量翻倍。编写一个程序,计算并显示Rabnud博士每周的朋友数量。该程序一直运行,直到超过邓巴数(Dunbar’s number)。邓巴数是粗略估算一个人在社交圈中有稳定关系的成员的最大值,该值大约是150。#include第七章 C 控制语句:分之合跳转int main() { int week = 0, friends = 5; do { week++; friends = 2 * (friends - week); printf("第%d周,Rabnud博士的朋友数量为:%dn", week, friends); }while (friends <= 150); printf("Done!"); return 0; }
- 编写一个程序读取输入,读到#字符停止,然后报告读取的空格数、换行符数和所有其他字符的数量。
#includeint main(void) { char ch; int sp_ct = 0; int nl_ct = 0; int other = 0; while((ch = getchar())!='#') { if(ch == ' ') sp_ct++; else if(ch=='n') nl_ct++; else other++; } printf("spaces: %d, newlines: %d, others: %dn", sp_ct, nl_ct, other); return 0; }
- 编写一个程序读取输入,读到#字符停止。程序要打印每个输入的字符以及对应的ASCII码(十进制)。一行打印8个字符。建议:使用字符计数和求模运算符(%)在每8个循环周期时打印一个换行符。
#include#define CHARS_PER_LINE 8 int main(void) { char ch; int n_chars = 1; printf("Enter some characters(# to quit):n"); while ((ch = getchar()) != '#') { printf("%3c(%3d) ", ch, ch); if (n_chars++ % CHARS_PER_LINE == 0) printf("n"); } printf("n"); return 0; }
- 编写一个程序,读取整数直到用户输入 0。输入结束后,程序应报告用户输入的偶数(不包括 0)个数、这些偶数的平均值、输入的奇数个数及其奇数的平均值。
#includeint main(void) { int num; int n_even = 0, n_odd = 0; //偶数和奇数个数 int sum_even = 0, sum_odd = 0; //偶数和奇数和 printf("Enter some integers(0 to quit):n"); scanf("%d", &num); while (num != 0) { if (num % 2 == 0) { n_even++; sum_even += num; } //计算偶数个数和偶数和 else { n_odd++; sum_odd +=num; } //计算奇数个数和奇数和 scanf("%d",&num); } printf("The number of even numbers is %d, " "and the everage of even numbers is %.2fn", n_even, (n_even == 0) ? 0 : (float)sum_even / n_even); printf("The number of odd numbers is %d, " "and the everrage of odd numers is %.2fn", n_odd, (n_odd == 0) ? 0 : (float)sum_odd / n_odd); return 0; }
- 使用if else语句编写一个程序读取输入,读到#停止。用感叹号替换句号,用两个感叹号替换原来的感叹号,最后报告进行了多少次替换。
#includeint main(void) { char ch; int n_repl = 0; //替换次数 printf("Enter some texts(# to quit):n"); while ((ch = getchar()) != '#') { if (ch == '.') { ch = '!'; n_repl++; } //替换句号 else if (ch == '!') { printf("!"); n_repl++; } //替换感叹号 printf("%c", ch); } printf("n%d substitutions were made.n", n_repl); return 0; }
- 使用switch重写练习4。
#includeint main(void) { char ch; int n_repl = 0; printf("Enter some text(# to quit):n"); while((ch = getchar())!='#') { switch(ch) { case'.': ch = '!'; n_repl++; break; case'!': printf("!"); n_repl++; break; default: break; } printf("%c",ch); } printf("n%d substitutions were made.n",n_repl); return 0; }
- 编写程序读取输入,读到#停止,报告ei出现的次数。
注意: 该程序要记录前一个字符和当前字符。用“Receive your eieio award”这样的输入来测试。#includeint main(void) { char ch; char last_ch = 0; int count=0; printf("Enter some texts(# to quit):n"); while ((ch = getchar()) != '#') { if ((ch == 'i') && (last_ch == 'e')) count++; last_ch = ch; } printf(""ei" appeared %d times.n", count); return 0; }
- 编写一个程序,提示用户输入一周工作的小时数,然后打印工资总额、税金和净收入。做如下假设:
a.基本工资 = 1000美元/小时 b.加班(超过40小时) = 1.5倍的时间 c.税率: 前300美元为15% 续150美元为20% 余下的为25%用#define定义符号常量。不用在意是否符合当前的税法。
#include#define BASE 1000 //基本工资 100美元/h #define TIME 40 //超过40h为加班 #define MUL 1.5 //加班时间算作平时的1.5倍 #define RATE1 0.15 //前300美元的税率 #define RATE2 0.2 //300-450美元的税率 #define RATE3 0.25 //大于450美元的税率 #define BREAK1 300 //税率的第一个分界点 #define BREAK2 450 //税率的第二个分界点 int main(void) { double hour, tax, gross; printf("Input your work hours in a week: "); scanf("%lf", &hour); if (hour <= TIME) gross = hour * BASE; else gross = TIME * BASE + (hour - TIME) * MUL * BASE; //计算总收入 if (gross <= BREAK1) tax = gross * RATE1; else if (gross <= BREAK2) tax = BREAK1 * RATE1 + (gross - BREAK1) * RATE2; else tax = BREAK1 * RATE1 + (BREAK2 - BREAK1) * RATE2 + (gross - BREAK2) * RATE3; //计算税金 printf("Your gross income is $%.2lfnYour tax is $%.2lfn" "Your net income is $%.2lfn", gross, tax, (gross - tax)); return 0; }
- 修改练习7的假设a,让程序可以给出一个供选择的工资等级菜单。使用switch完成工资等级选择。运行程序后,显示的菜单应该类似这样:
***************************************************************** Enter the number corresponding to the desired pay rate or action: 1) $8.75/hr 2) $9.33/hr 3) $10.00/hr 4) $11.20/hr 5) quit *****************************************************************如果选择 1~4 其中的一个数字,程序应该询问用户工作的小时数。程序要通过循环运行,除非用户输入 5。如果输入 1~5 以外的数字,程序应提醒用户输入正确的选项,然后再重复显示菜单提示用户输入。使用#define创建符号常量表示各工资等级和税率。
#include#define BASE1 8.75 #define BASE2 9.33 #define BASE3 10.00 #define BASE4 11.20 //四种等级的基本工资 #define TIME 40 //超过40h为加班 #define MUL 1.5 //加班时间算作平时的1.5倍 #define RATE1 0.15 //前300美元的税率 #define RATE2 0.2 //300-450美元的税率 #define RATE3 0.25 //大于450美元的税率 #define BREAK1 300 //税率的第一个分界点 #define BREAK2 450 //税率的第二个分界点 int main(void) { double base, hour, tax, gross; int count, num; const int LENGTH = 65; //*的长度 printpart: for (count = 0; count < LENGTH; count++) printf("*"); printf("nEnter the number corresponding to the desired pay rate or action:n"); printf("%-36s%s","1) $8.75/hr", "2) $9.33/hrn"); printf("%-36s%s","3) $10.00/hr", "4) $11.20/hrn"); printf("%sn", "5) quit"); for (count = 0; count < LENGTH; count++) printf("*"); printf("n"); //打印表格 while (scanf("%d", &num) == 1) { switch (num) { case 1: base = BASE1; break; case 2: base = BASE2; break; case 3: base = BASE3; break; case 4: base = BASE4; break; case 5: printf("quit.n"); return 0; default: printf("Please input the right option.n"); goto printpart; } //选择基本工资等级 printf("Input your work hours in a week: "); scanf("%lf", &hour); if (hour <= TIME) gross = hour * base; else gross = TIME * base + (hour - TIME) * MUL * base; //计算总收入 if (gross <= BREAK1) tax = gross * RATE1; else if (gross <= BREAK2) tax = BREAK1 * RATE1 + (gross - BREAK1) * RATE2; else tax = BREAK1 * RATE1 + (BREAK2 - BREAK1) * RATE2 + (gross - BREAK2) * RATE3; //计算税金 printf("Your gross income is $%.2lfnYour tax is $%.2lfn" "Your net income is $%.2lfn", gross, tax, (gross - tax)); printf("nYour next choice:n"); } return 0; }
编写一个程序,只接受正整数输入,然后显示所有小于或等于该数的素数。
#include#include int main(void) { int limit; int num; int div; bool numIsPrime; // use int if stdbool.h not available printf("Enter a positive integer: "); while (scanf("%d", &limit) == 1 && limit > 0) { if (limit > 1) printf("Here are the prime numbers up through %dn", limit); else printf("No primes.n"); for (num = 2; num <= limit; num++) { for (div = 2, numIsPrime = true; (div * div) <= num; div++) if (num % div == 0) numIsPrime = false; if (numIsPrime) printf("%d is prime.n", num); } printf("Enter a positive integer (q to quit): "); } printf("Done!n"); return 0; }
- 1988年的美国联邦税收计划是近代最简单的税收方案。它分为4个类别,每个类别有两个等级。
下面是该税收计划的摘要(美元数为应征税的收入):
例如,一位工资为20000美元的单身纳税人,应缴纳税费0.15×17850+0.28×(20000−17850)美元。编写一个程序,让用户指定缴纳税金的种类和应纳税收入,然后计算税金。程序应通过循环让用户可以多次输入。#include#define RATE1 0.15 #define RATE2 0.28 #define SINGLE 17850 //单身人群的税率分界点 #define HOST 23900 //户主人群的税率分界点 #define MAR_SHA 29750 //已婚共有人群的分界点 #define MAR_DEV 14875 //已婚离异人群的分界点 int main(void) { int num; double income, tax_break, tax; printpart: printf("Please enter Corresponding" "figures to select the typen"); printf("1 single, 2 host, 3 married and shared, " "4 married but devoced and 5 to quit.n"); scanf("%d", &num); switch (num) { case 1: tax_break = SINGLE; break; case 2: tax_break = HOST; break; case 3: tax_break = MAR_SHA; break; case 4: tax_break = MAR_DEV; break; case 5: printf("quit.n"); return 0; default: printf("Please input right number."); goto printpart; //回到输入阶段 } printf("Enter your income: "); //指定种类和收入 while (scanf("%lf", &income) == 1) { if (income <= tax_break) tax = income * RATE1; else tax = tax_break * RATE1 + (income - tax_break) * RATE2; //计算税金 printf("The tax is $%.2lf.n", tax); printf("Your next input: n"); goto printpart; //回到输入阶段 } return 0; }
- ABC 邮购杂货店出售的洋蓟售价为 2.05 美元/磅,甜菜售价为 1.15美元/磅,胡萝卜售价为 1.09美元/磅。在添加运费之前,100美元的订单有5%的打折优惠。少于或等于5磅的订单收取6.5美元的运费和包装费,5磅~20磅的订单收取14美元的运费和包装费,超过20磅的订单在14美元的基础上每续重1磅增加0.5美元。编写一个程序,在循环中用switch语句实现用户输入不同的字母时有不同的响应,即输入a的响应是让用户输入洋蓟的磅数,b是甜菜的磅数,c是胡萝卜的磅数,q 是退出订购。程序要记录累计的重量。即,如果用户输入 4 磅的甜菜,然后输入 5磅的甜菜,程序应报告9磅的甜菜。然后,该程序要计算货物总价、折扣(如果有的话)、运费和包装费。随后,程序应显示所有的购买信息:物品售价、订购的重量(单位:磅)、订购的蔬菜费用、订单的总费用、折扣(如果有的话)、运费和包装费,以及所有的费用总额。
#include第八章 字符输入/输出和输入验证#include #define ARTICHOKE 2.05 //洋蓟2.05美元/磅 #define BEET 1.15 //甜菜1.15美元/磅 #define CARROT 1.09 //胡萝卜1.09美元/磅 #define DISCOUNT_LIMIT 100 //包装费和运费打折要求订单100美元 #define DISCOUNT_RATE 0.05 //折扣为%5 #define BREAK1 5 #define BREAK2 20 //装运费的分界点 #define FEE1 6.5 #define FEE2 14 #define FEE3_RATE 0.5 //不同重量区间的装运费,其中超过20磅的每续重一磅 //增加0.5元 int main(void) { double weight; double weight_artichoke = 0; double weight_beet = 0; double weight_carrot = 0; //购买三种蔬菜的重量 double total_weight; //总重量 double veg_cost; //三种蔬菜总共花费 double order_cost; //订单总额 double total_cost; //费用总额 double pack_tran_fee; //装运费 double discount; int count = 0; char ch; printf("Please select the vegetables you want to buy:n"); printf("a: artichoke $%.2f/lbn", ARTICHOKE); printf("b: beet $%.2f/lbn", BEET); printf("c: carrot $%.2f/lbn", CARROT); printf("q: quit.n"); //打印选择信息 while ((ch = tolower(getchar())) != 'q') { // if (ch == 'n') // continue; //滤掉回车 switch (ch) { case 'a': printf("Input the weight of artichoke in pound: "); scanf("%lf", &weight); weight_artichoke += weight; count++; printf("Continue entering a, b, c or q: "); break; case 'b': printf("Input the weight of beet in pound: "); scanf("%lf", &weight); weight_beet += weight; count++; printf("Continue entering a, b, c or q: "); break; case 'c': printf("Input the weight of carrot in pound: "); scanf("%lf", &weight); weight_carrot += weight; count++; printf("Continue entering a, b, c or q: "); break; default: printf("Please enter the right character."); } while (getchar () != 'n') continue; //滤掉输入重量后面的所有字符 } if (!count) { printf("Bye.n"); return 0; } //开始输出q,直接退出 total_weight = weight_artichoke + weight_beet + weight_carrot; veg_cost = weight_artichoke * ARTICHOKE + weight_beet * BEET + weight_carrot * CARROT; discount = 0; if (veg_cost >= DISCOUNT_LIMIT) { discount = veg_cost * DISCOUNT_RATE; order_cost = veg_cost - discount; } else order_cost = veg_cost; //折扣计算 if (total_weight <= BREAK1) pack_tran_fee = FEE1; else if (total_weight <= BREAK2) pack_tran_fee = FEE2; else pack_tran_fee = FEE2 + (total_weight - BREAK2) * FEE3_RATE; //装运费计算 total_cost = order_cost + pack_tran_fee; printf("nHere is what you choose:n"); if (weight_artichoke) { printf("artichoke Price: $%.2f/lb weight: %.2f pounds cost: $%.2fn", ARTICHOKE, weight_artichoke, weight_artichoke * ARTICHOKE); } if (weight_beet) { printf("beet Price: $%.2f/lb weight: %.2f pounds cost: $%.2fn", BEET, weight_beet, weight_beet * BEET); } if (weight_carrot) { printf("carrot Price: $%.2f/lb weight: %.2f pounds cost: $%.2fn", CARROT, weight_carrot, weight_carrot * CARROT); } printf("The order cost: $%.2fn", veg_cost); if (discount) printf ("You have %%%.f discount, and the reduced money is $%.2fn", DISCOUNT_RATE * 100, discount); printf("The packing and transpoting fee is $%.2fn", pack_tran_fee); printf("The total cost is $%.2fn", total_cost); //输出订单信息 return 0; }
设计一个程序,统计在读到文件结尾之前读取的字符数。
#includeint main(void) { int ch; int count = 0; while((ch=getchar())!= EOF) count++; printf("The number of characters is %dn",count); return 0; }
**编写一个程序,在遇到 EOF 之前,把输入作为字符流读取。程序要打印每个输入的字符及其相应的ASCII十进制值。注意,在ASCII序列中,空格字符前面的字符都是非打印字符,要特殊处理这些字符。如果非打印字符是换行符或制表符,则分别打印n或t。否则,使用控制字符表示法。例如,ASCII的1是Ctrl+A,可显示为^A。注意,A的ASCII值是Ctrl+A的值加上64。其他非打印字符也有类似的关系。除每次遇到换行符打印新的一行之外,每行打印10对值。(注意:不同的操作系统其控制字符可能不同。)
**#include#define SPACE 32 #define CTRL 64 #define COL 10 //每行打印10对 int main(void) { char ch; int count = 0; while ((ch = getchar()) != EOF) { count++; //打印字符输出 if (ch >= SPACE) printf("%c ", ch); //换行符和制表符的输出 else if (ch == 'n' || ch == 't') printf("%s", ch == 'n' ? "\n" : "\t"); //一般控制字符的输出 else printf("^%c", ch + CTRL); printf("%-5d", ch); if (ch == 'n') count = 0; if (count % COL == 0) //10对换行 printf("n"); } return 0; }
编写一个程序,在遇到 EOF 之前,把输入作为字符流读取。该程序要报告输入中的大写字母和小写字母的个数。假设大小写字母数值是连续的。或者使用ctype.h库中合适的分类函数更方便。
#include#include int main(void) { int lower = 0, upper = 0; char ch; printf("Input some texts:n"); while ((ch = getchar()) != EOF) { if (islower(ch)) lower++; if (isupper(ch)) upper++; } printf("lower:%d, upper:%dn", lower, upper); return 0; }
编写一个程序,在遇到EOF之前,把输入作为字符流读取。该程序要报告平均每个单词的字母数。不要把空白统计为单词的字母。实际上,标点符号也不应该统计,但是现在暂时不同考虑这么多(如果你比较在意这点,考虑使用ctype.h系列中的ispunct()函数)。
#include#include int main(void) { char ch; int inword = 0; //在单词中为1否则为0 int words = 0; //单词数 int chars = 0; //字符数 printf("Please enter some words:n"); while ((ch = getchar()) != EOF) { if (!isspace(ch) && !ispunct(ch)) chars++; //开始一个新的单词 if (!isspace(ch) && !ispunct(ch) && !inword) { inword = 1; words++; } //单词末尾 if (isspace(ch) || ispunct(ch) && inword) inword = 0; } printf("There are %d words and %d lettersn", words, chars); printf("The average number of letters of "); printf("each word is %.2f.n", ((double)chars / (double)words)); return 0; }
- 修改程序清单8.4的猜数字程序,使用更智能的猜测策略。例如,程序最初猜50,询问用户是猜大了、猜小了还是猜对了。如果猜小了,那么下一次猜测的值应是50和100中值,也就是75。如果这次猜大了,那么下一次猜测的值应是50和75的中值,等等。使用二分查找(binary search)策略,如果用户没有欺骗程序,那么程序很快就会猜到正确的答案。
#include#define LOW 1 //初始下限 #define HIGH 100 //初始上限 int get_guess(void); int main(void) { char response; int guess; int low = LOW; int high = HIGH; guess = (low + high) / 2; printf("Pick an integer from %d to %d. I will try to guess ", LOW, HIGH); printf("it.nRespond with a y if my guess is right, with an s if itn"); printf("is small and with a b if it is big.n"); printf("Uh...is your number %d?n", guess); while ((response = getchar()) != 'y') { if (response == 's') { low = guess; guess = (guess + high) / 2; } else if (response == 'b') { high = guess; guess = (guess + low) / 2; } else printf("Sorry, I understand only y, s and b.n"); printf("Well, then, is it %d?n", guess); //跳过剩余输入行 while (getchar() != 'n') continue; //使取值能到达上限 if (guess == HIGH - 1) guess++; } printf("I knew i could do it!n"); return 0; }
修改程序清单8.8中的get_first()函数,让该函数返回读取的第1个非空白字符,并在一个简单的程序中测试。
#include#include char get_first(void); int main(void) { char ch; while ((ch = get_first()) != EOF) { putchar(ch); printf("n"); } return 0; } char get_first(void) { char ch; while (isspace(ch = getchar())) continue; while (getchar() != 'n') continue; return ch; }
- 修改第7章的编程练习8,用字符代替数字标记菜单的选项。用q代替5作为结束输入的标记。
#include#define BASE1 8.75 #define BASE2 9.33 #define BASE3 10.00 #define BASE4 11.20 //四种等级的基本工资 #define TIME 40 //超过40h为加班 #define MUL 1.5 //加班时间算作平时的1.5倍 #define RATE1 0.15 //前300美元的税率 #define RATE2 0.2 //300-450美元的税率 #define RATE3 0.25 //大于450美元的税率 #define BREAK1 300 //税率的第一个分界点 #define BREAK2 450 //税率的第二个分界点 #define LENGTH 65 //长度 char get_choice(void); void calculate(double base); int main(void) { double base; char choice; while ((choice = get_choice()) != 'q') { switch (choice) { case 'a': base = BASE1; break; case 'b': base = BASE2; break; case 'c': base = BASE3; break; case 'd': base = BASE4; break; default: printf("Please respond with a, b, c, d or q.n"); break; } if (choice >= 'a' && choice <= 'd') calculate(base); } return 0; } //计算和输出结果的函数 void calculate(double base) { double hour, gross, tax; printf("Input your work hours in a week: "); scanf("%lf", &hour); while (getchar() != 'n') continue; //跳过回车 if (hour <= TIME) gross = hour * base; else gross = TIME * base + (hour - TIME) * MUL * base; //计算总收入 if (gross <= BREAK1) tax = gross * RATE1; else if (gross <= BREAK2) tax = BREAK1 * RATE1 + (gross - BREAK1) * RATE2; else tax = BREAK1 * RATE1 + (BREAK2 - BREAK1) * RATE2 + (gross - BREAK2) * RATE3; //计算税金 printf("Your gross income is $%.2lfnYour tax is $%.2lfn" "Your net income is $%.2lfn", gross, tax, (gross - tax)); printf("n"); } //打印选择界面并让用户输入的函数 char get_choice(void) { char ch; int count; for (count = 0; count < LENGTH; count++) printf("*"); printf("nEnter the letter corresponding to the desired pay rate or action:n"); printf("%-36s%s","a) $8.75/hr", "b) $9.33/hrn"); printf("%-36s%s","c) $10.00/hr", "d) $11.20/hrn"); printf("%sn", "q) quit"); for (count = 0; count < LENGTH; count++) printf("*"); printf("n"); ch = getchar(); while (getchar() != 'n') continue; //跳过输出行剩余内容 return ch; }
编写一个程序,显示一个提供加法、减法、乘法、除法的菜单。获得用户选择的选项后,程序提示用户输入两个数字,然后执行用户刚才选择的操作。该程序只接受菜单提供的选项。程序使用float类型的变量储存用户输入的数字,如果用户输入失败,则允许再次输入。进行除法运算时,如果用户输入0作为第2个数(除数),程序应提示用户重新输入一个新值。该程序的一个运行示例如下:
Enter the operation of your choice: a. add s. subtract m. multiply d. divide q. quit a Enter first number: 22 .4 Enter second number: one one is not an number. Please enter a number, such as 2.5, -1.78E8, or 3: 1 22.4 + 1 = 23.4 Enter the operation of your choice: a. add s. subtract m. multiply d. divide 559q. quit d Enter first number: 18.4 Enter second number: 0 Enter a number other than 0: 0.2 18.4 / 0.2 = 92 Enter the operation of your choice: a. add s. subtract m. multiply d. divide q. quit q Bye.#include第九章 函数float get_float(void); char get_choice(void); char get_first(void); int main(void) { char choice; float num1, num2; while ((choice = get_choice()) != 'q') { printf("Enter first number: "); num1 = get_float(); printf("Enter second number: "); num2 = get_float(); switch (choice) { case 'a': printf("%.2f + %.2f = %.2fn", num1, num2, num1 + num2); break; case 's': printf(".2%f - %.2f = %.2fn", num1, num2, num1 - num2); break; case 'm': printf("%.2f * %.2f = %.2fn", num1, num2, num1 * num2); break; case 'd': if (!num2) { printf("Enter a number other than 0: "); num2 = get_float(); } printf("%.2f / %.2f = %.2fn", num1, num2, num1 / num2); break; default: printf("Program error!n"); break; } } printf("Bye.n"); return 0; } //打印界面和让用户选择的函数 char get_choice(void) { char ch; printf("Enter the operation of your choice:n"); printf("%-36s%sn", "a. add", "s. subtract"); printf("%-36s%sn", "m. multiply", "d. divide"); printf("q. quitn"); ch = get_first(); while (ch != 'a' && ch != 's' && ch != 'm' && ch != 'd' && ch != 'q') { printf("Please enter a, s, m, d or q.n"); ch = get_first(); } return ch; } //获得输入值并处理错误输入的函数 float get_float(void) { float input; char ch; while (scanf("%f", &input) != 1) { while ((ch = getchar()) != 'n') putchar(ch); printf(" is not an number.n"); printf("Please enter a number, such as 2.5, -1.78E8, or 3: "); } while (getchar() != 'n') continue; return input; } //读取输入行的第一个字符 char get_first(void) { char ch; ch = getchar(); while (getchar() != 'n') continue; return ch; }
- 设计一个函数min(x, y),返回两个double类型值的较小值。在一个简单的驱动程序中测试该函数。
#includedouble min(double x, double y); int main(void) { double num1, num2; printf("Enter two numbers: "); scanf("%lf%lf", &num1, &num2); printf("The smaller one is: %fn", min(num1, num2)); return 0; } double min(double n1, double n2) { return (n1 < n2 ? n1 : n2); }
- .设计一个函数chline(ch, i, j),打印指定的字符j行i列。在一个简单的驱动程序中测试该函数。
a.donut()接受一个int类型的参数,打印若干(参数指定数目)个0 b.gear()接受两个int类型的参数,返回int类型的值 c.guess()不接受参数,返回一个int类型的值 d.stuff_it()接受一个double类型的值和double类型变量的地址,把第1个 值储存在指定位置#includevoid chline(char ch, int i, int j); int main(void) { int row, col; char ch; printf("Input a character you want to print: "); ch = getchar(); printf("Input the number of rows and columns: "); scanf("%d%d", &row, &col); chline(ch, row, col); return 0; } void chline(char ch, int i , int j) { int row, col; for (row = 1; row <= i; row++) { for(col = 1; col <=j; col++) putchar(ch); putchar('n'); } return; }
- 编写一个函数,接受3个参数:一个字符和两个整数。字符参数是待打印的字符,第1个整数指定一行中打印字符的次数,第2个整数指定打印指定字符的行数。编写一个调用该函数的程序。
#includevoid chline(char ch, int i, int j); int main(void) { int row, col; char ch; printf("Input a character you want to print: "); ch = getchar(); printf("Input the number of rows and columns: "); scanf("%d%d", &row, &col); chline(ch, row, col); return 0; } void chline(char ch, int i , int j) { int row, col; for (row = 1; row <= i; row++) { for(col = 1; col <=j; col++) putchar(ch); putchar('n'); } return; }
- 两数的调和平均数这样计算:先得到两数的倒数,然后计算两个倒数的平均值,最后取计算结果的倒数。编写一个函数,接受两个double类型的参数,返回这两个参数的调和平均数。
#includedouble har_mean(double num1, double num2); int main(void) { double num1, num2; printf("Enter two numbers: "); scanf("%lf%lf", &num1, &num2); printf("The harmonic mean is: %fn", har_mean(num1, num2)); } double har_mean(double num1, double num2) { return 1 / (1 / num1 + 1 / num2); }
编写并测试一个函数larger_of(),该函数把两个double类型变量的值替换为较大的值。例如, larger_of(x, y)会把x和y中较大的值重新赋给两个变量。
#includevoid larger_of(double * x, double * y); int main(void) { double num1, num2; printf("Input two numbers: "); scanf("%lf%lf", &num1, &num2); printf("Originally, num1 = %f, num2 = %fn", num1, num2); larger_of(&num1, &num2); printf("Now, num1 = %f, num2 = %fn", num1, num2); return 0; } void larger_of(double * x, double * y) { *x > *y ? (*y = *x) : (*x = *y); }
- 编写并测试一个函数,该函数以3个double变量的地址作为参数,把最小值放入第1个函数,中间值放入第2个变量,最大值放入第3个变量。
#includevoid sort(double * x, double * y, double * z); int main(void) { double num1, num2 ,num3; printf("Enter 3 numbers: "); scanf("%lf%lf%lf", &num1, &num2, &num3); printf("Originallynnum1 = %.2f, num2 = %.2f, num3 = %.2fn", num1, num2, num3); sort(&num1, &num2, &num3); printf("Nownnum1 = %.2f, num2 = %.2f, num3 = %.2fn", num1, num2, num3); return 0; } void sort(double * x, double * y, double * z) { double temp; if (*y < *x) { temp = *y; *y = *x; *x = temp; } if (*z < *x) { temp = *z; *z = *x; *x = temp; } if (*z < *y) { temp = *z; *z = *y; *y = temp; } }
- 下编写一个函数,从标准输入中读取字符,直到遇到文件结尾。程序要报告每个字符是否是字母。如果是,还要报告该字母在字母表中的数值位置。例如,c和C在字母表中的位置都是3。合并一个函数,以一个字符作为参数,如果该字符是一个字母则返回一个数值位置,否则返回-1。
void salami(num) { int num, count; for (count = 1; count <= num; num++) printf(" O salami mio!n"); }#include#include int get_ch(char ch); int main(void) { char ch; printf("Input some texts:n"); while ((ch = getchar()) != EOF) printf("%d ", get_ch(ch)); return 0; } int get_ch(char ch) { if (isalpha(ch)) return tolower(ch) - 'a' +1; else return -1; }
- 第6章的程序清单6.20中,power()函数返回一个double类型数的正整数次幂。改进该函数,使其能正确计算负幂。另外,函数要处理0的任何次幂都为0,任何数的0次幂都为1(函数应报告0的0次幂未定义,因此把该值处理为1)。要使用一个循环,并在程序中测试该函数。
#includedouble power(double n, int p); int main(void) { double x, xpow; int exp; printf("Enter a number and the interger power (q to quit):n"); while (scanf("%lf%d", &x, &exp) == 2) { xpow = power(x, exp); printf("%.3g to the power %d is %gn", x, exp, xpow); printf("Enter the next pair of numbers or q to quit.n"); } printf("Bye.n"); } double power(double n, int p) { int count; double pow = 1; if (p == 0) if (n == 0) { pow = 1; printf("It is not defined, so the value is treated as 1n"); } else pow = 1; else if (p > 0) for (count = 0; count < p; count++) pow *= n; else if (n != 0) for (count = 0; count > p; count--) pow /= n; else pow = 0; return pow; }
- 使用递归函数重写编程练习8。
#includedouble power(double n, int p); int main(void) { double x, xpow; int exp; printf("Enter a number and the interger power (q to quit):n"); while (scanf("%lf%d", &x, &exp) == 2) { xpow = power(x, exp); printf("%.3g to the power %d is %gn", x, exp, xpow); printf("Enter the next pair of numbers or q to quit.n"); } printf("Bye.n"); } double power(double n, int p) { int count; double pow; if (p > 0) pow = n * power(n, p - 1); else if (p < 0) if (n != 0) pow = (1.0 / n) * power(n, p + 1); else pow = 0; else pow = 1; return pow; }
- 为了让程序清单9.8中的to_binary()函数更通用,编写一to_base_n()函数接受两个在2~10范围内的参数,然后以第2个参数中指定的进制打印第1个参数的数值。例如,to_base_n(129, 8)显示的结果为201,也就是129的八进制数。在一个完整的程序中测试该函数。
#includevoid to_base_n(unsigned long n, unsigned int base); int main(void) { unsigned long num; unsigned int base; printf("Enter an integer and the base from 2 to 10 (q to quit): "); while (scanf("%lu%u", &num, &base) == 2) { printf("Equivalent number on the base of %u: ", base); to_base_n(num, base); printf("nEnter your next pair of numbers(q to quit): "); } printf("Done.n"); return 0; } void to_base_n(unsigned long n, unsigned int base) { int r; r = n % base; if (n >= base) to_base_n(n / base, base); printf("%d", r); }
编写并测试Fibonacci()函数,该函数用循环代替递归计算斐波那契数。
#include第十章 数组和指针unsigned long Fibonacci(unsigned n); int main(void) { unsigned int num; int count; printf("Input the number of the items (q to quit): "); while (scanf("%u", &num) == 1) { for (count = 1; count <= num; count++) printf("%lu ", Fibonacci(count)); printf("nYour next input(q to quit): "); } printf("Bye.n"); return 0; } unsigned long Fibonacci(unsigned n) { int count, temp; int n1 = 1, n2 = 1; if (n > 2) for (count = 3; count <= n; count++) { temp = n1 + n2; n1 = n2; n2 = temp; } else n2 = 1; return n2; }
修改程序清单10.7的rain.c程序,用指针进行计算(仍然要声明并初始化数组)。
#include#define months 12 #define years 5 int main(void) { const float rain[years][months]= { {4.3,4.3,4.3,3.0,2.0,1.2,0.2,0.2,0.4,2.4,3.5,6.6}, {8.5,8.2,1.2,1.6,2.4,0.0,5.2,0.9,0.3,0.9,1.4,7.3}, {9.1,8.5,6.7,4.3,2.1,0.8,0.2,0.2,1.1,2.3,6.1,8.4}, {7.2,9.9,8.4,3.3,1.2,0.8,0.4,0.0,0.6,1.7,4.3,6.2}, {7.6,5.6,3.8,2.8,3.8,0.2,0.0,0.0,0.0,1.3,2.6,5.2} }; int year, month; float subtot, total; printf(" YEAR RAINFALL (inches)n"); for (year = 0, total = 0; year < years; year++) { //每一年,个月降水量总和 for (month = 0, subtot = 0; month < months; month++) subtot += *(*(rain + year) + month); printf("%5d %15.1fn", 2010 + year, subtot); total += subtot; //5年的总降水量 } printf("n The yearly average is %.1f inches.nn", total / years); printf(" MONTHLY AVERAGES:nn"); printf(" Jan Feb Mar Apr May Jun Jul Aug Sep Oct "); printf(" Nov Decn"); for (month = 0; month < months; month++) { for (year = 0, subtot = 0; year < years; year++) subtot += *(*(rain + year) +month); printf("%4.1f ", subtot / years); } printf("n"); return 0; }
编写一个程序,初始化一个double类型的数组,然后把该数组的内容拷贝至3个其他数组中(在main()中声明这4个数组)。使用带数组表示法的函数进行第1份拷贝。使用带指针表示法和指针递增的函数进行第2份拷贝。把目标数组名、源数组名和待拷贝的元素个数作为前两个函数的参数。第3个函数以目标数组名、源数组名和指向源数组最后一个元素后面的元素的指针。也就是说,给定以下声明,则函数调用如下所示:
double source[5] = {1.1, 2.2, 3.3, 4.4, 5.5}; double target1[5]; double target2[5]; double target3[5]; copy_arr(target1, source, 5); copy_ptr(target2, source, 5); copy_ptrs(target3, source, source + 5);#include#define SIZE 5 void copy_arr(double ar1[], double ar[], int n); void copy_ptr(double * ar2, double * ar, int n); void copy_ptrs(double * ar3, double * ar, double * end); void print_array(double ar[], int n); //打印数组的函数 int main(void) { double source[SIZE] = {1.1, 2.2, 3.3, 4.4, 5.5}; double target1[SIZE]; double target2[SIZE]; double target3[SIZE]; copy_arr(target1, source, SIZE); copy_ptr(target2, source, SIZE); copy_ptrs(target3, source, source + SIZE); print_array(target1, SIZE); print_array(target2, SIZE); print_array(target3, SIZE); return 0; } void copy_arr(double ar1[], double ar[], int n) { int index; for (index = 0; index < n; index++) ar1[index] = ar[index]; } void copy_ptr(double * ar2, double * ar, int n) { int i; for (i = 0; i < n; i++) *(ar2++) = *(ar++); } void copy_ptrs(double * ar3, double * ar, double * end) { int i; for (i = 0; ar < end; i++) *(ar3++) = *(ar++); } void print_array(double ar[], int n) { int index; for (index = 0; index < n; index++) printf("%g ", ar[index]); printf("n"); } 3.编写一个函数,返回储存在int类型数组中的最大值,并在一个简单的程序中测试该函数。
#includeint max(int arg[],int n) { int i,max; for(i=0,max=arg[0];i if(max int num[] = {23,2,32,66,3,5,25,7,3,20}; printf("The biggest number is %dn",max(num,10)); return 0; }
编写一个函数,返回储存在double类型数组中最大值的下标,并在一个简单的程序中测试该函数。
#includeint max_index(double *ar, int n); int main(void) { double array[] = {1.5, 3.75, 4.3, 2.6, 2.15, 6.66}; printf("The index of the maximum number is: %dn", max_index(array, 6)); return 0; } int max_index(double ar[], int n) { int i, max; for (max = 0, i = 1; i < n; i++) if (ar[max] < ar[i]) max = i; return max; }
- 编写一个函数,返回储存在double类型数组中最大值和最小值的差值,并在一个简单的程序中测试该函数。
#includedouble gap(double ar[], int n); int main(void) { double array[] = {1.5, 3.75, 4.3, 2.6, 2.15, 6.66}; printf("The difference between the maximum and minimum " "values is:n%gn", gap(array, 6)); return 0; } double gap(double ar[], int n) { int i; double max, min; max = min = ar[0]; for (i = 0; i < n; i++) { if (max < ar[i]) max = ar[i]; if (min > ar[i]) min = ar[i]; } return (max - min); } 6.编写一个函数,把double类型数组中的数据倒序排列,并在一个简单的程序中测试该函数。
#include#define SIZE 6 void reverse(double ar [], int n); void print_ar(double ar[], int n); //打印数组的函数 int main(void) { double array[] = {1.5, 3.75, 4.3, 2.6, 2.15, 6.66}; printf("The original array:n"); print_ar(array, SIZE); reverse(array, SIZE); //使数据倒序排列 printf("The present array:n"); print_ar(array, SIZE); return 0; } void reverse(double ar [], int n) { int i; double temp; for (i = 0; i < n / 2; i++) { temp = ar[i]; ar[i] = ar[n - i -1]; ar[n - i -1] = temp; } } void print_ar(double ar[], int n) { int i; for (i = 0; i < n; i++) printf("%g ", ar[i]); printf("n"); }
编写一个程序,初始化一个double类型的二维数组,使用编程练习2中的一个拷贝函数把该数组中的数据拷贝至另一个二维数组中(因为二维数组是数组的数组,所以可以使用处理一维数组的拷贝函数来处理数组中的每个子数组)。
#include#define ROWS 3 #define COLS 2 void copy_ar(double ar1[], double ar[], int n); //拷贝数组的函数 void print_ar(double ar[][COLS], int rows); //打印数组的函数 int main(void) { int rows; double target[ROWS][COLS]; double source[ROWS][COLS] = { {1.2, 2.3}, {4.6, 5.2}, {7.8, 8.6} }; printf("The original array:n"); print_ar(source, ROWS); for (rows = 0; rows < ROWS; rows++) copy_ar(target[rows], source[rows], COLS); printf("The copied array:n"); print_ar(target, ROWS); return 0; } void copy_ar(double ar1[], double ar[], int n) { int index; for (index = 0; index < n; index++) ar1[index] = ar[index]; } void print_ar(double ar[][COLS], int rows) { int r, c; for (r = 0; r < rows; r++) { for (c = 0; c < COLS; c++) printf("%g ", ar[r][c]); printf("n"); } }
使用编程练习2中的拷贝函数,把一个内含7个元素的数组中第3~第5个元素拷贝至内含3个元素的数组中。该函数本身不需要修改,只需要选择合适的实际参数(实际参数不需要是数组名和数组大小,只需要是数组元素的地址和待处理元素的个数)。
#include#define SIZE_SOU 7 //源数组元素个数 #define SIZE_TAR 3 //待拷贝元素个数 void copy_ptr(double * ar2, double * ar, int n); int main(void) { int i; double target[SIZE_TAR]; double souce[SIZE_SOU] = {1.5, 3.75, 4.3, 2.6, 2.15, 3.27, 6.66}; copy_ptr(target, souce + 2, SIZE_TAR); for (i = 0; i < SIZE_TAR; i++) printf("%g ", target[i]); printf("n"); return 0; } void copy_ptr(double * ar2, double * ar, int n) { int i; for (i = 0; i < n; i++) *(ar2++) = *(ar++); } 9.编写一个程序,初始化一个double类型的3×5二维数组,使用一个处理变长数组的函数将其拷贝至另一个二维数组中。还要编写一个以变长组为形参的函数以显示两个数组的内容。这两个函数应该能处理任意N×M数组(如果编译器不支持变长数组,就使用传统C函数处理N×5的数组)。
#include#define ROWS 3 #define COLS 5 void copy_ar(double ar1[][COLS], double ar[][COLS], int n); //拷贝数组的函数 void print_ar(double ar[][COLS], int rows); //打印数组的函数 int main(void) { double target[ROWS][COLS]; double source[ROWS][COLS] = { {1.2, 2.3, 2.6, 3.5, 3.2}, {4.6, 5.2, 2.8, 3.3, 2.1}, {7.8, 8.6, 7.2, 3.9, 6.6} }; printf("The original array:n"); print_ar(source, ROWS); copy_ar(target, source, ROWS); printf("The copied array:n"); print_ar(target, ROWS); return 0; } void copy_ar(double ar1[][COLS], double ar[][COLS], int rows) { int r, c; for (r = 0; r < rows; r++) for (c = 0; c < COLS; c++) ar1[r][c] = ar[r][c]; } void print_ar(double ar[][COLS], int rows) { int r, c; for (r = 0; r < rows; r++) { for (c = 0; c < COLS; c++) printf("%g ", ar[r][c]); printf("n"); } }
- 编写一个函数,把两个数组中相对应的元素相加,然后把结果储存到第 3 个数组中。也就是说,如果数组1中包含的值是2、4、5、8,数组2中包含的值是1、0、4、6,那么该函数把3、4、9、14赋给第3个数组。函数接受3个数组名和一个数组大小。在一个简单的程序中测试该函数。
#include#define SIZE 4 void print_ar(double ar[], int n); //打印数组元素的函数 //将两个数组相加放入第三个数组的函数 void add_ar(double ar1[], double ar2[], double ar3[], int n); int main(void) { double ar1[SIZE] = {2, 4, 5, 8}; double ar2[SIZE] = {1, 0, 4, 6}; double ar3[SIZE]; printf("The first array: "); print_ar(ar1, SIZE); printf("The second array: "); print_ar(ar2, SIZE); add_ar(ar1, ar2, ar3, SIZE); printf("The third array: "); print_ar(ar3, SIZE); return 0; } void print_ar(double ar[], int n) { int i; for (i = 0; i < n; i++) printf("%g ", ar[i]); printf("n"); } void add_ar(double ar1[], double ar2[], double ar3[], int n) { int i; for (i = 0; i < n; i++) ar3[i] = ar1[i] + ar2[i]; }
编写一个程序,声明一个int类型的3×5二维数组,并用合适的值初始化它。该程序打印数组中的值,然后各值翻倍(即是原值的2倍),并显示出各元素的新值。编写一个函数显示数组的内容,再编写一个函数把各元素的值翻倍。这两个函数都以函数名和行数作为参数。
#include#define ROWS 3 #define COLS 5 void change_ar(int ar[][COLS], int rows); //变化数组的函数 void print_ar(int ar[][COLS], int rows); //打印数组的函数 int main(void) { int array[ROWS][COLS] = { {1, 2, 6, 3, 3}, {6, 5, 2, 3, 2}, {7, 8, 7, 3, 6} }; printf("The original array:n"); print_ar(array, ROWS); change_ar(array, ROWS); printf("The present array:n"); print_ar(array, ROWS); return 0; } void change_ar(int ar[][COLS], int rows) { int r, c; for (r = 0; r < rows; r++) for (c = 0; c < COLS; c++) ar[r][c] *= 2; } void print_ar(int ar[][COLS], int rows) { int r, c; for (r = 0; r < rows; r++) { for (c = 0; c < COLS; c++) printf("%3d ", ar[r][c]); printf("n"); } }
- 重写程序清单10.7的rain.c程序,把main()中的主要任务都改成用函数来完成。
#include#define MONTHS 12 //一年的月份数 #define YEARS 5 //一年的年数 void rainfall(float rain[][MONTHS], int years); int main(void) { //用2010~2014年的降水量数据初始化数组 const float rain[YEARS][MONTHS] = { {4.3,4.3,4.3,3.0,2.0,1.2,0.2,0.2,0.4,2.4,3.5,6.6}, {8.5,8.2,1.2,1.6,2.4,0.0,5.2,0.9,0.3,0.9,1.4,7.3}, {9.1,8.5,6.7,4.3,2.1,0.8,0.2,0.2,1.1,2.3,6.1,8.4}, {7.2,9.9,8.4,3.3,1.2,0.8,0.4,0.0,0.6,1.7,4.3,6.2}, {7.6,5.6,3.8,2.8,3.8,0.2,0.0,0.0,0.0,1.3,2.6,5.2} }; rainfall(rain, YEARS); return 0; } void rainfall(float rain[][MONTHS], int years) { float subtot, total; int y, m; printf(" YEAR RAINFALL (inches)n"); for (y = 0, total = 0; y < years; y++) { //每一年,各月降水量总和 for (m = 0, subtot = 0; m < MONTHS; m++) subtot += rain[y][m]; printf("%5d %15.1fn", 2010 + y, subtot); total += subtot; //5年的总降水量 } printf("n The yearly average is %.1f inches.nn", total / YEARS); printf(" MONTHLY AVERAGES:nn"); printf(" Jan Feb Mar Apr May Jun Jul Aug Sep Oct "); printf(" Nov Decn"); for (m = 0; m < MONTHS; m++) { for (y = 0, subtot = 0; y < years; y++) subtot += rain[y][m]; printf("%4.1f ", subtot / years); } printf("n"); }
编写一个程序,提示用户输入3组数,每组数包含5个double类型的数(假设用户都正确地响应,不会输入非数值数据)。该程序应完成下列任务。
a.把用户输入的数据储存在3×5的数组中 b.计算每组(5个)数据的平均值 c.计算所有数据的平均值 d.找出这15个数据中的最大值 e.打印结果每个任务都要用单独的函数来完成(使用传统C处理数组的方式)。完成任务b,要编写一个计算并返回一维数组平均值的函数,利用循环调用该函数3次。对于处理其他任务的函数,应该把整个数组作为参数,完成任务c和d的函数应把结果返回主调函数。
14. 以变长数组作为函数形参,完成编程练习13。#include#define ROWS 3 #define COLS 5 #define NUM 15 //共计15个数 void get_num(double ar[][COLS], int rows); //把用户输入的数据储存在数组中 double aver_row(double ar[]); //计算每组数据的平均值 double aver_all(double ar[][COLS], int rows); //计算所有数据的平均值 double max_num(double ar[][COLS], int rows); //找出15个数据的最大值 //打印结果 void print_result(double ar[][COLS], int rows); int main(void) { double array[ROWS][COLS]; get_num(array, ROWS); print_result(array, ROWS); return 0; } void get_num(double ar[][COLS], int rows) { int r, c; double a = 1.0; //是为了让vc6.0编译器链接浮点链接库 printf("Please enter 3 groups of numbers, and theren" "are 5 numbers in each group:n"); for (r = 0; r < rows; r++) for (c = 0; c < COLS; c++) scanf("%lf", &ar[r][c]); } double aver_row(double ar[]) { int c; double sub; for (c = 0, sub = 0.0; c < COLS; c++) sub += ar[c]; return (sub / COLS); } double aver_all(double ar[][COLS], int rows) { int r, c; double total; for (r = 0, total = 0.0; r < rows; r++) for (c = 0; c < COLS; c++) total += ar[r][c]; return (total / NUM); } double max_num(double ar[][COLS], int rows) { int r, c; double max; for (r = 0, max = ar[0][0]; r < rows; r++) for (c = 0; c < COLS; c++) if (max < ar[r][c]) max = ar[r][c]; return max; } void print_result(double ar[][COLS], int rows) { int r, c, row; //打印数组 printf("The array:n"); for (r = 0; r < rows; r++) { for (c = 0; c < COLS; c++) printf("%-5g", ar[r][c]); printf("n"); } //输出每组平均值 for (row = 0; row 第十一章 字符串和字符串函数 1.设计并测试一个函数,从输入中获取下n个字符(包括空白、制表符、换行符),把结果储存在一个数组里,它的地址被传递作为一个参数。
#include#define N 40 char *gets_n(char ar[],int n) { int count= 0; while(count < n) ar[count++] = getchar(); ar[count] = ' '; } int main(void) { char str[N]; int n; printf("how many chars do you want input:t"); scanf("%d",&n); gets_n(str,n); puts(str); return 0; }
- 修改并编程练习1的函数,在n个字符后停止,或在读到第1个空白、制表符或换行符时停止,哪个先遇到哪个停止。不能只使用scanf()。
#include#include #define SIZE 256 char *gets_n(char *ar,int n) { int i; for(i = 0;i *(ar+i)=getchar(); if(isspace(*(ar+i))) break; } *(ar+i)=' '; return ar; } int main(void) { char str[SIZE]; printf("Enter some character :n"); gets_n(str,250); puts(str); return 0; }
- 设计并测试一个函数,从一行输入中把一个单词读入一个数组中,并丢弃输入行中的其余字符。该函数应该跳过第1个非空白字符前面的所有空白。将一个单词定义为没有空白、制表符或换行符的字符序列。
#include#include #define N 256 void get_word(char *ar) { char ch; int i=0; while(isspace(ch=getchar())) continue; do *ar++ = ch; while(!isspace(ch = getchar())) ; } int main(void) { char str[N]; printf("Enter some characters:n"); get_word(str); puts(str); return 0; }
- 设计并测试一个函数,它类似编程练习3的描述,只不过它接受第2个参数指明可读取的最大字符数。
#include#include #define N 256 void get_words(char *ar,int n) { char ch; int i = 0; while(isspace(ch=getchar())) continue; do { *(ar+i)=ch; i++; } while(!isspace(ch = getchar())&&i<(n-1)) ; } int main(void) { char str[250]; int n=0; printf("enter how many characters do you want to show :n"); scanf("%d",&n); printf("Enter some character:n"); get_words(str,n); puts(str); }
- 设计并测试一个函数,搜索第1个函数形参指定的字符串,在其中查找第2个函数形参指定的字符首次出现的位置。如果成功,该函数返指向该字符的指针,如果在字符串中未找到指定字符,则返回空指针(该函数的功能与 strchr()函数相同)。在一个完整的程序中测试该函数,使用一个循环给函数提供输入值。
#include#include #define QUIT "quit" #define SIZE 256 char *str_ch(char *str,char c) { int flag = 0; int count = 0; while(count++ < strlen(str)) if(*str++ == c) { flag = 1; break; } if(flag) return str-1; else return NULL; } int main(void) { char str[SIZE]; char ch; char*ret_val; printf("Input a string(type quit to quit):n"); gets(str); while(strcmp(str,QUIT)) { printf("Input a character:"); scanf("%c",&ch); while(getchar()!='n') continue; ret_val = str_ch(str, ch); if (ret_val != NULL) printf("Find! The string start with the %c:n" "%sn", ch, ret_val); else printf("Can't find!n"); printf("Input a string (type quit to quit):n"); gets(str); } printf("Bye.n"); return 0; }
- 编写一个名为is_within()的函数,接受一个字符和一个指向字符串的指针作为两个函数形参。如果指定字符在字符串中,该函数返回一个非零值(即为真)。否则,返回0(即为假)。在一个完整的程序中测试该函数,使用一个循环给函数提供输入值。
#include#include #define QUIT "quit" #define SIZE 256 int is_within(char*str,char c) { int flag = 0; size_t count = 0; while(count++ if(*str++ == c) { flag = 1; break; } } return flag; } int is_within(char * str, char c); int main(void) { char str[SIZE]; char ch; printf("Input a string (type quit to quit):n"); while (strcmp(gets(str), QUIT)) { printf("Input a character: "); scanf("%c", &ch); while (getchar() != 'n') //跳过剩余输入部分 continue; if (is_within(str, ch)) printf("Find!n"); else printf("Can't find!n"); printf("Input a string (type quit to quit):n"); } printf("Bye.n"); return 0; }
strncpy(s1, s2, n)函数把s2中的n个字符拷贝至s1中,截断s2,或者有必要的话在末尾添加空字符。如果s2的长度是n或多于n,目标字符串不能以空字符结尾。该函数返回s1。自己编写一个这样的函数,名为mystrncpy()。在一个完整的程序中测试该函数,使用一个循环给函数提供输入值。
#include#include #define QUIT "quit" #define SIZE 256 char *mystrncpy(char*p1,char*p2,int n) { int i = 1; char*p=p1; while(*p++) continue; *--p1=*p2; while(i *++p1 = *++p2; i++; } return p; } int main() { char s1[SIZE]; char s2[SIZE]; int num; printf("Input the first string(type "quit" to quit):n"); while (strcmp(gets(s1), QUIT)) //输入quit结束 { printf("Input the second string:n"); gets(s2); printf("Input the number of char copied from s2: "); scanf("%d", &num); getchar(); //跳过回车 //当s2的长度大于或等于要拷贝的字符数时,要给s1末尾加上' ', //并且注意要在调用函数之前,不然strlen(s1)会发生改变 if (strlen(s2) >= num) s1[strlen(s1) + num] = ' '; puts(mystrncpy(s1, s2, num)); //输出拷贝后的字符串s1 printf("Input the first string (type quit to quit):n"); } printf("Bye.n"); return 0; }
- 编写一个名为string_in()的函数,接受两个指向字符串的指针作为参数。如果第2个字符串中包含第1个字符串,该函数将返回第1个字符串开始的地址。例如,string_in(“hats”, “at”)将返回hats中a的地址。否则,该函数返回空指针。在一个完整的程序中测试该函数,使用一个循环给函数提供输入值。
#include#include #define SIZE 40 #define QUIT "quit" char * s_gets(char * st, int n); //读取字符串输入的函数 char * string_in(char * s1, char * s2); int main(void) { char str1[SIZE]; char str2[SIZE]; char * ret_val; printf("Input the first string (type quit to quit):n"); while (strcmp(s_gets(str1, SIZE), QUIT)) //输入quit结束 { printf("Input the second string:n"); s_gets(str2, SIZE); ret_val = string_in(str1, str2); if (ret_val) { printf("Find!n"); puts(ret_val); } else printf("Can't find!n"); printf("Input the first string (type quit to quit):n"); } printf("Bye.n"); } //自定义的字符串输入函数 char * s_gets(char * st, int n) { int i = 0; if (fgets(st, n, stdin)) //即返回值st不等于NULL { while (st[i] != 'n' && st[i] != ' ') i++; if (st[i] == 'n') st[i] = ' '; else while (getchar() != 'n') continue; } return st; } //在s1中检测s2 char * string_in(char * s1, char * s2) { int i; while (*s1) { i = 0; while (s1[i] == s2[i]) { i++; if (!s2[i]) return s1; } s1++; } return NULL; }
- 编写一个函数,把字符串中的内容用其反序字符串代替。在一个完整的程序中测试该函数,使用一个循环给函数提供输入值。
#include#include #define SIZE 40 #define QUIT "quit" char * s_gets(char * st, int n); void reverse(char * st); int main(void) { char str[SIZE]; while (strcmp(s_gets(str, SIZE), QUIT)) //输入quit结束 { reverse(str); puts(str); } return 0; } //自定义的字符串输入函数 char * s_gets(char * st, int n) { int i = 0; printf("Input the first string (type quit to quit):n"); if (fgets(st, n, stdin)) //即返回值st不等于NULL { while (st[i] != 'n' && st[i] != ' ') i++; if (st[i] == 'n') st[i] = ' '; else while (getchar() != 'n') continue; } return st; } //使字符串倒序的函数 void reverse(char * st) { unsigned int i; char temp; size_t length = strlen(st); for (i = 0; i < length / 2; i++) { temp = st[length - i -1]; st[length - i - 1] = st[i]; st[i] = temp; } st[length] = ' '; }
编写一个函数接受一个字符串作为参数,并删除字符串中的空格。在一个程序中测试该函数,使用循环读取输入行,直到用户输入一行空行。该程序应该应用该函数只每个输入的字符串,并显示处理后的字符串。
#include#define SIZE 40 char * s_gets(char * st, int n); void delete_space(char * st); int main(void) { char str[SIZE]; while (*s_gets(str, SIZE) != 'n') delete_space(str); printf("Bye.n"); return 0; } //删除空格的函数 void delete_space(char * st) { int i; char * p = st; printf("nThe original string is:n"); puts(st); while (*st) { //如果遇到空格,后面所有字符往前进一格 if (*st == ' ') for (i = 0; st[i] != ' '; i++) st[i] = st[i + 1]; else st++; } printf("Now, the string is:n"); puts(p); printf("n"); } //自定义的字符串输入函数 char * s_gets(char * st, int n) { int i = 0; printf("Input the first string (blank line to quit):n"); if (fgets(st, n, stdin) != NULL && st[0] != 'n') //即返回值st不等于NULL { while (st[i] != 'n' && st[i] != ' ') i++; if (st[i] == 'n') st[i] = ' '; else while (getchar() != 'n') continue; } return st; }
编写一个函数,读入10个字符串或者读到EOF时停止。该程序为用户提供一个有5个选项的菜单:打印源字符串列表、以ASCII中的顺序打印字符串、按长度递增顺序打印字符串、按字符串中第1个单词的长度打印字符串、退出。菜单可以循环显示,除非用户选择退出选项。当然,该程序要能真正完成菜单中各选项的功能。
#include#include #include #define LIM 10 #define SIZE 80 char * s_gets(char * st, int n); //获取字符串输入 char get_choice(void); //获取选择 void print_sour(char * st[], int n); //打印源字符串 void print_ascii(char * st[], int n); //按ASCII码顺序打印 void print_length(char * st[], int n); //按长度顺序打印 void print_first_word(char * st[], int n); //按第一个单词的长度顺序打印 int first_word(char * st); //计算第一个单词数 int main(void) { char str[LIM][SIZE]; char * ptr[LIM]; int row = 0; //输入的字符串数量 char choice; //用户输入的选择字符 printf("Input some strings before EOF (no more than 10):n"); while (row < LIM && s_gets(str[row], SIZE) != NULL) { ptr[row] = str[row]; //设置指针指向字符串 row++; } while((choice = get_choice()) != 'q') { printf("n"); switch (choice) { case 'a': print_sour(ptr, row); break; case 'b': print_ascii(ptr, row); break; case 'c': print_length(ptr, row); break; case 'd': print_first_word(ptr, row); break; default: printf("Error!n"); break; } printf("n"); } printf("Bye.n"); return 0; } //获取用户选择 char get_choice(void) { char ch; printf("a. print the sourse strings. b. print in order of ASCII.n"); printf("c. print in order of length. d. print in order of the first word's length.n"); printf("q. quit.n"); printf("Enter a character (a, b, c, d or q):"); ch = getchar(); while (getchar() != 'n') continue; while (ch < 'a' || ch > 'd' && ch != 'q') { printf("Please input the right option (a, b, c, d or q): "); ch = getchar(); while (getchar() != 'n') continue; } return ch; } //打印源字符串 void print_sour(char * st[], int n) { int i; for (i = 0; i < n; i++) puts(st[i]); } //按ASCII中的顺序打印字符串 void print_ascii(char * st[], int n) { int i, j; char * temp; for (i = 0; i < n - 1; i++) for (j = i + 1; j < n; j++) if (strcmp(st[i], st[j]) > 0) { temp = st[j]; st[j] = st[i]; st[i] = temp; } for (i = 0; i < n; i++) puts(st[i]); } //按长度顺序打印 void print_length(char * st[], int n) { int i, j; char * temp; for (i = 0; i < n - 1; i++) for (j = i + 1; j < n; j++) if (strlen(st[i]) > strlen(st[j])) { temp = st[j]; st[j] = st[i]; st[i] = temp; } for (i = 0; i < n; i++) puts(st[i]); } //按第一个单词的长度顺序打印 void print_first_word(char * st[], int n) { int i, j; char * temp; for (i = 0; i < n - 1; i++) for (j = i + 1; j < n; j++) if (first_word(st[i]) > first_word(st[j])) { temp = st[j]; st[j] = st[i]; st[i] = temp; } for (i = 0; i < n; i++) puts(st[i]); } //计算第一个单词的长度 int first_word(char * st) { int i = 0; int count = 0; while (!isalpha(st[i])) i++; while (isalpha(st[i])) { i++; count++; } return count; } //自定义的输入函数 char * s_gets(char * st, int n) { int i = 0; if (fgets(st, n, stdin) != NULL) //即返回值st不等于NULL { while (st[i] != 'n' && st[i] != ' ') i++; if (st[i] == 'n') st[i] = ' '; else while (getchar() != 'n') continue; return st; } else return NULL; }
编写一个程序,读取输入,直至读到 EOF,报告读入的单词数、大写字母数、小写字母数、标点符号数和数字字符数。使用ctype.h头文件中的函数。
#include#include int main(void) { char ch; int word = 0, upper = 0, lower = 0; int punct = 0, digit = 0, inword = 0; while ((ch = getchar()) != EOF) { if (!isspace(ch) && (!ispunct(ch)) && !inword) { inword = 1; word++; } if (isspace(ch) || ispunct(ch) && inword) inword = 0; if (isupper(ch)) upper++; if (islower(ch)) lower++; if (ispunct(ch)) punct++; if (isdigit(ch)) digit++; } printf("words: %d, upper: %d, lower: %d, punct: %d, digit: %d.n", word, upper, lower, punct, digit); return 0; }
编写一个程序,反序显示命令行参数的单词。例如,命令行参数是see you later,该程序应打印later you see。
#includeint main(int argc, char * argv[]) { int count; for (count = argc - 1; count > 0; count--) printf("%s ", argv[count]); return 0; }
编写一个通过命令行运行的程序计算幂。第1个命令行参数是double类型的数,作为幂的底数,第2个参数是整数,作为幂的指数。
#include#include double mypower(double n, int exp); int main(int argc, char * argv[]) { printf("The result is: %g", mypower(atof(argv[1]), atoi(argv[2]))); } double mypower(double n, int exp) { double pow; if (exp > 0) for (pow = 1; exp > 0; exp--) pow *= n; else if (exp < 0) { if (!n) printf("It's not defined!n"); for (pow = 1; exp < 0; exp++) pow *= (1 / n); } else if (n) pow = 1; else { pow = 1 / n; printf("It's not defined!n"); } return pow; }
使用字符分类函数实现atoi()函数。如果输入的字符串不是纯数字,该函数返回0。
#include#include int myatoi(char * st); int main(void) { char str[40]; gets(str); printf("%dn", myatoi(str)); } int myatoi(char * st) { int sum = 0; while (*st) { //把字符数字逐位转化为数值 if (isdigit(*st)) sum = 10 * sum + (*st - '0'); else return 0; //不是纯数字则返回0 st++; } return sum; }
- 编写一个程序读取输入,直至读到文件结尾,然后把字符串打印出来。该程序识别和实现下面的命令行参数:
-p 按原样打印 -u 把输入全部转换成大写 -l 把输入全部转换成小写如果没有命令行参数,则让程序像是使用了-p参数那样运行。
#include#include #include #define SIZE 80 #define LIM 10 int main(int argc, char * argv[]) { int col; int i; int row = 0; char str[LIM][SIZE]; while (row < LIM && fgets(str[row], SIZE, stdin) != NULL) { if (argc == 1); else if (!strcmp(argv[1], "-p")); else if (!strcmp(argv[1], "-u")) for (col = 0; str[row][col] != ' '; col++) str[row][col] = toupper(str[row][col]); else if (!strcmp(argv[1], "-l")) for (col = 0; str[row][col] != ' '; col++) str[row][col] = tolower(str[row][col]); row++; } for (i = 0; i < row; i++) fputs(str[i], stdout); return 0; }



