第二章
第三章
第四章
第五章
1. 编写一个程序, 把用分钟表示的时间转换成用小时和分钟表示的时间。 使用 #define 或 const 创建一个表示 60 的符号常量或 const 变量。 通过 while 循环让用户重复输入值, 直到用户输入小于或等于 0 的值才停止循环。
//通过scanf返回值读取用户输入 #include <stdio.h> #define MIN_TO_HOUR 60 int main(void) { int mins, hours, last_mins; puts("Enter the time (minute) you want to transfer (<= 0 to quit):"); while (scanf("%d", &mins) == 1 && mins > 0) { hours = mins / MIN_TO_HOUR; last_mins = mins % MIN_TO_HOUR; printf("%d minutes equal to %d hour(s) and %d minute(s).\n", mins, hours, last_mins); puts("Enter the time (minute) you want to transfer (<= 0 to quit):"); } puts("Bye!"); return 0; }
2. 编写一个程序, 提示用户输入一个整数, 然后打印从该数到比该数大 10 的所有整数( 例如, 用户输入 5, 则打印 5~15 的所有整数, 包括 5 和 15)。 要求打印的各值之间用一个空格、 制表符或换行符分开。
//通过for循环打印即可 #include <stdio.h> #define LEN 10 int main(void) { int n; puts("Enter an integer:"); scanf("%d", &n); for (int i = n; i <= n + LEN; i++) printf("%d ", i); return 0; }
3. 编写一个程序, 提示用户输入天数, 然后将其转换成周数和天数。 例如, 用户输入 18, 则转换成 2周 4 天。 以下面的格式显示结果:
18 days are 2 weeks, 4 days.//整数的取模 % 和除法 / #include <stdio.h> #define D_TO_W 7 int main(void) { int days; puts("Enter the number of days you want to convert (negative or zero to quit):"); while(scanf("%d", &days) == 1 && days > 0) { printf("%d days are %d weeks, %d days.\n", days, days / D_TO_W, days % D_TO_W); puts("Enter the number of days you want to convert (negative or zero to quit):"); } puts("Bye!"); return 0; }
4. 编写一个程序, 提示用户输入一个身高( 单位: 厘米), 并分别以厘米和英尺、 英寸为单位显示该值,允许有小数部分。 程序应该能让用户重复输入身高, 直到用户输入一个非正值。 其输出示例如下:
Enter a height in centimeters: 182
182.0 cm = 5 feet, 11.7 inches
Enter a height in centimeters (<=0 to quit): 168.7
168.7 cm = 5 feet, 6.4 inches
Enter a height in centimeters (<=0 to quit): 0
bye//1英尺 = 30.48厘米,1英寸 = 2.54厘米 #include <stdio.h> #define CM_TO_FEET 30.48 #define CM_TO_INCH 2.54 int main(void) { double height, inches; int feet; printf("Enter a height in centimeters: "); while(scanf("%lf", &height) == 1 && height > 0) { feet = height / CM_TO_FEET; inches = (height - feet * CM_TO_FEET) / CM_TO_INCH; printf("%.1f cm = %d feet, %.1f inches\n", height, feet, inches); printf("Enter a height in centimeters (<= to quit): "); } puts("Bye"); return 0; }
5. 修改程序 addeirmp.c (程序清单 5.13 ), 你可以认为 addemup.c 是计算 20 天里赚多少钱的程序
( 假设第 1 天赚$1 、 第 2 天赚S2、 第 3 天赚S3, 以此类推)。 修改程序, 使其可以与用户交互, 根据用户输入的数进行计算( 即, 用读入的一个变量来代替 20)。//for循环即可 #include <stdio.h> int main(void) { int n; int sum, count; puts("Enter a integer:"); scanf("%d", &n); for (count = 1; count <= n; count++) sum += count; printf("sum = %d", sum); return 0; }
6. 修改编程练习 5 的程序, 使其能计算整数的平方和( 可以认为第 1 天赚$1、 第 2 天赚$4、 第 3 天赚$9,以此类推, 这看起来很不错)。 C 没有平方函数, 但是可以用 n * n 来表示 n 的平方
//for循环即可 #include <stdio.h> int main(void) { int n; int sum, count; puts("Enter a integer:"); scanf("%d", &n); for (count = 1; count <= n; count++) sum += count * count; printf("sum = %d", sum); return 0; }
7. 编写一个程序, 提示用户输入一个 double 类型的数, 并打印该数的立方值。 自己设计一个函数计算并打印立方值。 main() 函数要把用户输入的值传递给该函数。
//设计函数,该函数为void类型,接受double类型的参数 #include <stdio.h> void cube(double num); int main(void) { double num; printf("Enter a number to calculate its cube: "); scanf("%lf", &num); cube(num); puts("\nBye"); return 0; } void cube(double num) { double ncube = num * num * num; printf("%.2f cubed is %.2f\n", num, ncube); }
8. 编写一个程序, 显示求模运算的结果。 把用户输入的第 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//注意取模仅用于整数 #include <stdio.h> int main(void) { int dividend, divisor; puts("This program computes moduli."); printf("Enter an integer to serve as the second operand: "); scanf("%d", &divisor); printf("Now enter the first operand: "); while (scanf("%d", ÷nd) == 1 && dividend > 0) { printf("%d %% %d is %d\n", dividend, divisor, dividend % divisor); printf("Enter next number for first operand (0 <= to quit): "); } puts("Done"); return 0; }
9. 编写一个程序, 要求用户输入一个华氏温度。 程序应读取 double 类型的值作为温度值, 并把该值作为参数传递给一个用户自定义的函数 Temperatures()。 该函数计算摄氏温度和开氏温度, 并以小数点后面两位数字的精度显示 3 种温度。 要使用不同的温标来表示这 3 个温度值。 下面是华氏温度转摄氏温度的公式:
摄氏温度 = 5.0 / 9.0 * (华氏溫度 - 32.0)
开氏温标常用于科学研究, 0 表示绝对零, 代表最低的温度。 下面是摄氏温度转开氏温度的公式:
开氏溫度 = 摄氏溫度 + 273.16
Temperatures ( ) 函数中用 const 创建温度转换中使用的变量。 在 main ( ) 函数中使用一个循环让用户重复输入温度, 当用户输入 q 或其他非数字时, 循环结束。 scanf() 函数返回读取数据的数量, 所以如果读取数字则返回 1, 如果读取 q 则不返回 1。可以使用=运算符将 scanf ( ) 的返回值和 1 作比较, 测试两值是否相等。// 1.摄氏温度(centigrade) = 5.0 / 9.0 * (华氏溫度(Fahrenheit) - 32.0) // 2.开氏溫度(Kelvin) = 摄氏溫度 + 273.16 // 3.自定义函数Tempertatures(),接受double类型华氏温度进行转换,返回类型为void。 #include <stdio.h> void Temperatures(double Fah); int main(void) { double Fah; puts("The program performs temperature conversion."); puts("Now enter the Fahrenheit temperature: "); while (scanf("%lf", &Fah) == 1) { Temperatures(Fah); puts("Now enter next Fahrenheit temperature (q to quit): "); } puts("Done"); return 0; } void Temperatures(double fah) { const double cen = 5.0 / 9.0 * (fah - 32); const double kel = cen + 273.16; printf("Fahrenheit temperature: %.2f\n", fah); printf("Centigrade temperature: %.2f\n", cen); printf(" Kelvin temperature: %.2f\n", kel); }
第六章
1. 编写一个程序, 创建一个包含 26 个元素的数组, 并在其中存储 26 个小写字母。 然后打印数组的所有内容。// 循环赋值打印 #include <stdio.h> #define LEN 26 int main(void) { int i; char arr[LEN]; for (i = 0; i < LEN; i++) { arr[i] = (int)'a' + i; printf("%c ", arr[i]); } putchar('\n'); return 0; }
2. 使用嵌套循环, 按下面的格式打印字符:
$
$$
$$$
$$$$
$$$$$
// 嵌套循环 #include <stdio.h> #define sign '$' int main(void) { int i, j; int n = 5; for (i = 1; i <= n; i++) { for (j = 0; j < i; j++) printf("%c", sign); putchar('\n'); } return 0; }
3. 使用嵌套循环, 按下面的格式打印字母:
F
FE
FED
FEDC
FEDCB
FEDCBA
注意: 如果你的系统不使用 ASCII 或其他以数字顺序编码的代码, 可以把字符数组初始化为字母表中的字母:char lets[27] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
然后用数组下标选择单独的字母, 例如 lets[0]是 'A', 等等。
#include <stdio.h> #define ROWS 6 int main(void) { int row; char ch; for (row = 0; row < ROWS; row++) { for (ch = 'F'; ch >= ('F' - row); ch--) printf("%c", ch); putchar('\n'); } return 0; }
4. 使用嵌套循环, 按下面的格式打印字母:
A
BC
DEF
GHIJ
KLMNO
PQRSTU如果你的系统不使用以数字顺序编码的代码, 请参照练习 3 的方案解决。
#include <stdio.h> #define ROWS 6 int main(void) { int row, col; char ch = 'A'; for (row = 0; row < ROWS; row++) { for (col = 0; col <= row; col++, ch++) printf("%c", ch); putchar('\n'); } return 0; }
5. 编写一个程序, 提示用户输入大写字母。 使用嵌套循环以下面金字塔型的格式打印字母:
A
ABA
ABCBA
ABCDCBA
ABCDEDCBA
打印这样的图形, 要根据用户输入的字母来决定。 例如, 上面的图形是在用户输入 E 后的打印结果。
提示: 用外层循环处理行, 每行使用 3 个内层循环, 分别处理空格、 以升序打印字母、 以降序打印字母。如果系统不使用 ASCII 或其他以数字顺序编码的代码, 请参照练习 3 的解决方案。
#include <stdio.h> #define space ' ' int main(void) { char ch; int row; printf("Enter a capital letter: "); scanf("%c", &ch); int i, j; row = ch - 'A' + 1; //计算行数 for (i = 0; i < row; i++) { //打印空格 for (j = row - i - 1; j > 0; j--) printf("%c", space); //升序打印 for (ch = 'A'; ch <= 'A' + i; ch++) printf("%c", ch); //降序打印 for (ch = ch - 2; ch >= 'A'; ch--) printf("%c", ch); putchar('\n'); } return 0; }
6. 编写一个程序打印一个表格, 每一行打印一个整数、 该数的平方、 该数的立方。 要求用户输入表格的上下限。 使用一个 for 循环。
#include <stdio.h> int main(void) { long up_limit, lo_limit; long n; printf("The program prints the trivial and cubic of all integers in a given range.\n"); printf("Now enter the upper limit: "); scanf("%d", &up_limit); printf("Next, enter the lower limit: "); scanf("%d", &lo_limit); printf("number square cube\n"); for (n = lo_limit; n <= up_limit; n++) printf("%4ld %5ld %5ld\n", n, n * n, n * n * n); return 0; }
7. 编写一个程序把一个单词读入一个字符数组中, 然后倒序打印这个单词。 提示: strlenO 函数( 第 4 章介绍过) 可用于计算数组最后一个字符的下标。
#include <stdio.h> #include <string.h> #define LEN 40 int main(void) { int count; char words[LEN]; printf("Enter a word: "); scanf("%s", words); count = strlen(words); for (int i = count - 1; i >= 0; i--) printf("%c", words[i]); return 0; }
8. 编写一个程序, 要求用户输入两个浮点数, 并打印两数之差除以两数乘积的结果。 在用户输入非数字之前, 程序应循环处理用户输入的每对值。
//while循环输入,输入非数字退出循环 #include <stdio.h> int main(void) { float f1, f2; printf("Enter the first float: "); while (scanf("%f", &f1) == 1) { printf("Now enter the second float: "); if (scanf("%f", &f2) == 1) printf("(%.2f - %.2f) / (%.2f * %.2f) = %.4f\n", f1, f2, f1, f2, (f1 - f2) / (f1 * f2)); else break; printf("Enter the first float (q to quit): "); } return 0; }
9. 修改练习 8, 使用一个函数返回计算的结果。
#include <stdio.h> float calculate(float a, float b); int main(void) { float f1, f2; printf("Enter the first float: "); while (scanf("%f", &f1) == 1) { printf("Now enter the second float: "); if (scanf("%f", &f2) == 1) printf("(%.2f - %.2f) / (%.2f * %.2f) = %.4f\n", f1, f2, f1, f2, calculate(f1, f2)); else break; printf("Enter the first float (q to quit): "); } return 0; } float calculate(float a, float b) { return ((a - b) / (a * b)); }
10. 编写一个程序, 要求用户输入一个上限整数和一个下限整数, 计算从上限到下限范围内所有整数的平方和, 并显示计算结果。 然后程序继续提示用户输入上限和下限整数, 并显示结果, 直到用户输入的上限整数等于或小于下限整数为止。 程序的运行示例如下:
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
// while循环处理输入 #include <stdio.h> int main(void) { unsigned long long lower, upper; unsigned long long sum; printf("Enter lower and upper integer limits: "); while ((scanf("%llu %llu", &lower, &upper) == 2) && upper > lower) { while (getchar() != '\n') continue; unsigned long long i; for (i = lower, sum = 0; i <= upper; i++) sum += i * i; printf("The sums of the squares from %llu to %llu is %llu\n", lower * lower, upper * upper, sum); printf("Enter next set of limits: "); } return 0; }
11. 编写一个程序, 在数组中读入 8 个整数, 然后按倒序打印这 8 个整数。
// for循环读入,然后循环打印 #include <stdio.h> #define SIZE 8 int main(void) { int arr[SIZE]; int i; for (i = 0; i < SIZE; i++) scanf("%d", &arr[i]); for (i = SIZE - 1; i >= 0 ; i--) printf("%d ", arr[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 项后的总和, 是否发现每个序列都收敛于某值?
//第一个序列为调和级数,不收敛 //第二个序列为交错调和级数,收敛于ln(2) //两序列之和发散 #include <stdio.h> int main(void) { double sum1, sum2, sum; int n; double i; printf("Enter specified times (<= 0 to quit): "); while (scanf("%d", &n) == 1 && n > 0) { for (i = 1.0, sum1 = 0.0, sum2 = 0.0, sum = 0.0; i <= (double)n; i = i + 1.0) { //第一个序列和 sum1 = sum1 + 1.0 / i; //第二个序列和 if ((int)i % 2 == 1) sum2 = sum2 + 1.0 / i; else sum2 = sum2 - 1.0 / i; //两个序列之和 if ((int)i % 2 == 1) sum = sum + 2 * 1.0 / i; } printf("sum1 = %lf\nsum2 = %lf\n sum = %lf\n", sum1, sum2, sum); printf("Enter specified times (<= 0 to quit): "); } printf("Done"); return 0; }
13. 编写一个程序, 创建一个包含 8 个元素的 int 类型数组, 分别把数组元素设置为 2 的前 8 次幂。使用 for 循环设置数组元素的值, 使用 do while 循环显示数组元素的值。
#include <stdio.h> #define SIZE 8 int main(void) { int arr[SIZE]; int i; arr[0] = 2; for (i = 1; i < SIZE; i++) arr[i] = arr[i-1] * 2; i = 0; do { printf("arr[%d] = %d\n",i, arr[i]); i++; } while (i < SIZE); return 0; }
14. 编写一个程序, 创建两个包含 8 个元素的 double 类型数组, 使用循环提示用户为第一个数组输入8 个值。 第二个数组元素的值设置为第一个数组对应元素的累积之和。 例如, 第二个数组的第 4个元素的值是第一个数组前 4 个元素之和, 第二个数组的第 5 个元素的值是第一个数组前 5 个元素之和( 用嵌套循环可以完成, 但是利用第二个数组的第 5 个元素是第二个数组的第 4 个元素与第一个数组的第 5 个元素之和, 只用一个循环就能完成任务, 不需要使用嵌套循环)。 最后, 使用循环显示两个数组的内容, 第一个数组显示成一行, 第二个数组显示在第一个数组的下一行, 而且每个元素都与第一个数组各元素相对应。
//第二个数组求和不使用嵌套循环,即只用一个循环完成 #include <stdio.h> #define SIZE 8 int main(void) { int i; double arr[SIZE]; double sum[SIZE]; //第一个数组赋值 printf("Enter the value: "); for (i = 0; i < SIZE; i++) { scanf("%lf", &arr[i]); printf("Enter the next value: "); } putchar('\n'); //第二个数组求和 sum[0] = arr[0]; for (i = 1; i < SIZE; i++) sum[i] = sum[i-1] + arr[i]; //显示 printf("arr:"); for (i = 0; i < SIZE; i++) printf(" %8.2lf ", arr[i]); putchar('\n'); printf("sum:"); for (i = 0; i < SIZE; i++) printf(" %8.2lf ", sum[i]); putchar('\n'); return 0; }
15. 编写一个程序, 读取一行输入, 然后把输入的内容倒序打印出来。 可以把输入存储在 char 类型的数组中, 假设每行字符不超过 255。 回忆一下,%c: 转换说明,scanf()函数一次只能从输入中读取一个字符, 而且在用户按下 Enter 键时 scanf()函数会生成一个换行字符( \n )。
#include <stdio.h> #define SIZE 255 int main(void) { char arr[SIZE]; int i = 0; while (scanf("%c", &arr[i]) == 1 && arr[i] != '\n' && i < SIZE) i++; for (i--; i >= 0; i--) printf("%c", arr[i]); return 0; }
16. Daphne 以 10%的单利息投资了 100 美元( 也就是说, 每年投资获利相当于原始投资的 10% ) 。Deirdre以 5%的复合利息投资了 100 美元( 也就是说, 利息是当前余额的 5%, 包含之前的利息)。 编写一个程序, 计算需要多少年 Deirdre 的投资额才会超过 Daphne, 并显示那时两人的投资额。
#include <stdio.h> #define INITIAL_FUNDING 100 int main(void) { double Dap = INITIAL_FUNDING, Dei = INITIAL_FUNDING; int year; for (year = 0; Dei <= Dap; year++) { Dap += INITIAL_FUNDING * 0.1; Dei += Dei * 0.05; } printf("Now it's been %d years, Dephic has $%lf, Deirdre has $%lf.\n", year, Dap, Dei); return 0; }
17. Chuckle Lucky 贏得了 100 万美元( 税后), 他把奖金存入年利率 8%的账户。 在每年的最后一天,Chuckie 取出 10 万美元。 编写一个程序, 计算多少年后 Chuckie 会取完账户的钱?
//先计算利率再取钱 #include <stdio.h> int main(void) { double money = 100; int year; for (year = 1; money > 0; year++) { money += money * 0.08; money -= 10; } printf("In %d years, Chuckie will run out of money.", --year); return 0; }
18. Rabnud 博士加入了一个社交圈。 起初他有 5 个朋友。 他注意到他的朋友数量以 "F面的方式增长。第 1 周少了1个朋友, 剩下的朋友数量翻倍: 第 2 周少了 2 个朋友, 剩下的朋友数量翻倍。 一般而言, 第 N 周少了 N 个朋友, 剩下的朋友数量翻倍。 编写一个程序, 计算并显示 Rabnud 博士每周的朋友数量。 该程序一直运行, 直到超过邓巴数( Dunbar's number )邓巴数是粗略估算一个人在社交圈中有稳定关系的成员的最大值, 该值大约是 150。
#include <stdio.h> #define DUNBAR 150 int main(void) { int friends = 5; int week; for (week = 1; friends < DUNBAR; week++) { friends -= week; friends *= 2; printf("week = %d, friends = %d\n", week, friends); } return 0; }