高级语言程序设计课程第三次个人作业
课程链接:https://edu.cnblogs.com/campus/fzu/2026gjyycxsj
作业要求:https://edu.cnblogs.com/campus/fzu/2026gjyycxsj/homework/16749
学号:010100223 姓名:武子腾
一、第4章 4.8 编程练习
4-2
题目: 4-2 编写一个程序,提示用户输入名字,并执行一下操作: a.打印名字,包括双引号; b.在宽度为20的字段右端打印名字,包括双引号; c.在宽度为20的字段左端打印名字,包括双引号; d.在比姓名宽度宽3的字段中打印名字。
代码:
/* 第4章 4.8 编程练习 第2题
提示用户输入名字,并执行以下操作:
a. 打印名字,包括双引号;
b. 在宽度为20的字段右端打印名字,包括双引号;
c. 在宽度为20的字段左端打印名字,包括双引号;
d. 在比姓名宽度宽3的字段中打印名字。 */
#include <stdio.h>
#include <string.h>
int main(void)
{
char name[40];
int width;
printf("请输入你的名字:");
scanf("%s", name);
/* a. 打印名字,包括双引号 */
printf("a. \"%s\"\n", name);
/* b. 在宽度为20的字段右端打印,包括双引号 */
printf("b. \"%20s\"\n", name);
/* c. 在宽度为20的字段左端打印,包括双引号 */
printf("c. \"%-20s\"\n", name);
/* d. 在比姓名宽度宽3的字段中打印名字 */
width = strlen(name) + 3;
printf("d. \"%*s\"\n", width, name);
return 0;
}
运行结果:
请输入你的名字:a. "Dabney"
b. " Dabney"
c. "Dabney "
d. " Dabney"
4-3
题目: 4-3 编写一个程序,读取一个浮点数,首先以小数点记数法打印 然后以指数记数法打印。用下面的格式进行输出 (系统不同,指数记数法显示的位 数可能不同): a.输入21.3或2.1e+001; b.输入+21.290或2.129E+001;
代码:
/* 第4章 4.8 编程练习 第3题
编写一个程序,读取一个浮点数,首先以小数点记数法打印,
然后以指数记数法打印。输出格式(指数记数法显示的位数因系统可能不同):
a. 输入 21.3,输出类似 2.1e+001;
b. 输入 +21.290,输出类似 2.129E+001。 */
#include <stdio.h>
int main(void)
{
float num;
printf("请输入一个浮点数:");
scanf("%f", &num);
/* a. 小数点记数法(1位小数) + 指数记数法(1位小数) */
printf("a. %.1f %.1e\n", num, num);
/* b. 带符号的小数点记数法(3位小数) + 指数记数法(3位小数) */
printf("b. %+.3f %.3E\n", num, num);
return 0;
}
运行结果:
请输入一个浮点数:a. 21.3 2.1e+01
b. +21.300 2.130E+01
4-4
题目: 4-4 4.编写一个程序,提示用户输入身高(单位:英寸)和姓名, 然后以下 面的格式显示用户刚输入的信息: Dabney, you are 6.208 feet tall 使用float类型,并用/作为除号。 如果你愿意,可以要求用户以厘米为 单位输入身高,并以米为单位显示出来。
代码:
/* 第4章 4.8 编程练习 第4题
提示用户输入身高和姓名,然后显示用户刚输入的信息,例如:
Dabney, you are 6.208 feet tall
要求使用 float 类型,并用 / 作为除号。
题目允许:以厘米为单位输入身高,并以米为单位显示。 */
#include <stdio.h>
int main(void)
{
char name[40];
float height_cm; /* 身高,单位:厘米 */
printf("请输入你的姓名:");
scanf("%s", name);
printf("请输入你的身高(厘米):");
scanf("%f", &height_cm);
/* 厘米换算成米(除以 100),保留 3 位小数 */
printf("%s, you are %.3f meters tall\n", name, height_cm / 100.0f);
return 0;
}
运行结果:
请输入你的姓名:请输入你的身高(厘米):Dabney, you are 1.820 meters tall
4-6
题目: 4-6 编写一个程序,先提示用户输入名,然后提示用户输入姓。 在一行打印用户输入的名和姓,下一行分别打印名和姓的字母数。 字母数要与相应名和姓的结尾对齐 接下来,再打印相同的信息,但是字母个数与相应名和姓的开头对齐
代码:
/* 第4章 4.8 编程练习 第6题
编写一个程序,先提示用户输入名,然后提示用户输入姓。
在一行打印用户输入的名和姓,下一行分别打印名和姓的字母数,
字母数要与相应名和姓的结尾对齐(右对齐);
接下来再打印相同的信息,但字母数与相应名和姓的开头对齐(左对齐)。 */
#include <stdio.h>
#include <string.h>
int main(void)
{
char first[40], last[40];
int len1, len2;
printf("请输入名:");
scanf("%s", first);
printf("请输入姓:");
scanf("%s", last);
len1 = strlen(first);
len2 = strlen(last);
/* 第一组:名和姓,下一行字母数右对齐(与结尾对齐) */
printf("%s %s\n", first, last);
printf("%*d %*d\n", len1, len1, len2, len2);
/* 第二组:相同信息,字母数左对齐(与开头对齐) */
printf("%s %s\n", first, last);
printf("%-*d %-*d\n", len1, len1, len2, len2);
return 0;
}
运行结果:
请输入名:请输入姓:Dabney Smith
6 5
Dabney Smith
6 5
4-7
题目: 4-7 编写一个程序,将一个double类型的变量设置为1.0/3.0, 一个float类型的变量设置为1.0/3.0。 分别显示两次计算的结果各3次:一次显示小数点后面6位数字; 一次显示小数点后面12位数字; 一次显示小数点后面16位数字。 程序中要包含float.h头文件,并显示FLT_DIG和DBL_DIG的值。 1.0/3.0 的值与这些值一致吗?
代码:
/* 第4章 4.8 编程练习 第7题
将一个 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 <stdio.h>
#include <float.h>
int main(void)
{
double d = 1.0 / 3.0; /* double 类型 */
float f = 1.0f / 3.0f; /* float 类型 */
printf("小数点后6位 : %.6f %.6f\n", d, f);
printf("小数点后12位: %.12f %.12f\n", d, f);
printf("小数点后16位: %.16f %.16f\n", d, f);
printf("FLT_DIG = %d\n", FLT_DIG);
printf("DBL_DIG = %d\n", DBL_DIG);
return 0;
}
运行结果:
小数点后6位 : 0.333333 0.333333
小数点后12位: 0.333333333333 0.333333343267
小数点后16位: 0.3333333333333333 0.3333333432674408
FLT_DIG = 6
DBL_DIG = 15
4-8
题目: 4-8 编写一个程序,提示用户输入旅行的里程和消耗的汽油量。 然后计算并显示消耗每加仑汽油行驶的英里数,显示小数点后面一位数字。 接下来,使用1加仑大约3.785升,1英里大约为1.609千米, 把单位是英里/加仑的值转换为升/100公里(欧洲通用的燃料消耗表示法), 并显示结果,显示小数点后面 1 位数字。 注意,美国采用的方案测量消耗单位燃料的行程(值越大越好), 而欧洲则采用单位距离消耗的燃料测量方案(值越低越好)。 使用 #define 创建符号常量或使用 const 限定符创建变量来表示两个转换系数。
代码:
/* 第4章 4.8 编程练习 第8题
提示用户输入旅行的里程和消耗的汽油量。
计算并显示消耗每加仑汽油行驶的英里数(显示小数点后 1 位)。
再把英里/加仑换算成升/100公里(欧洲通用的燃料消耗表示法),显示小数点后 1 位。
用 #define 创建符号常量表示两个转换系数:
1 加仑 ≈ 3.785 升,1 英里 ≈ 1.609 千米。 */
#include <stdio.h>
#define GALLON_TO_LITRE 3.785 /* 1 加仑 = 3.785 升 */
#define MILE_TO_KM 1.609 /* 1 英里 = 1.609 千米 */
int main(void)
{
double miles, gallons; /* 里程(英里)、油耗(加仑) */
double mpg; /* 英里/加仑 */
double l_per_100km; /* 升/100公里 */
printf("请输入行驶里程(英里):");
scanf("%lf", &miles);
printf("请输入消耗汽油(加仑):");
scanf("%lf", &gallons);
/* 美国方案:每加仑行驶的英里数(值越大越好) */
mpg = miles / gallons;
printf("油耗为 %.1f 英里/加仑\n", mpg);
/* 欧洲方案:每100公里消耗的升数(值越小越好) */
l_per_100km = (gallons * GALLON_TO_LITRE) / (miles * MILE_TO_KM / 100.0);
printf("油耗为 %.1f 升/100公里\n", l_per_100km);
return 0;
}
运行结果:
请输入行驶里程(英里):请输入消耗汽油(加仑):油耗为 26.7 英里/加仑
油耗为 8.8 升/100公里
二、第5章 5.11 编程练习
5-1
题目: 编写一个程序,把用分钟表示的时间转换成用小时和分钟表示的时间。 使用#define或const创建一个表示60的符号常量或const变量。 通过while循环让用户重复输入值,直到用户输入小于或等于0的值才停止循环。
代码:
/* 第5章 5.11 编程练习 第1题
编写一个程序,把用分钟表示的时间转换成用小时和分钟表示的时间。
使用 #define 或 const 创建一个表示 60 的符号常量。
通过 while 循环让用户重复输入,直到用户输入小于或等于 0 的值才停止。 */
#include <stdio.h>
#define MIN_PER_HOUR 60
int main(void)
{
int minutes, hour, min;
printf("请输入分钟数(<=0 结束):");
scanf("%d", &minutes);
while (minutes > 0)
{
hour = minutes / MIN_PER_HOUR; /* 整数除法得小时 */
min = minutes % MIN_PER_HOUR; /* 取模得剩余分钟 */
printf("%d 分钟 = %d 小时 %d 分钟\n", minutes, hour, min);
printf("请输入分钟数(<=0 结束):");
scanf("%d", &minutes);
}
printf("结束!\n");
return 0;
}
运行结果:
请输入分钟数(<=0 结束):450 分钟 = 7 小时 30 分钟
请输入分钟数(<=0 结束):结束!
5-2
题目: 编写一个程序,提示用户输入一个整数,然后打印从该数到比该数大10的所有整数 (例如,用户输入5,则打印5~15的所有整数,包括5和 15)。 要求打印的各值之间用一个空格、制表符或换行符分开。
代码:
/* 第5章 5.11 编程练习 第2题
提示用户输入一个整数,然后打印从该数到比该数大 10 的所有整数
(例如输入 5,则打印 5~15 的所有整数,包括 5 和 15)。
各值之间用一个空格、制表符或换行符分开。 */
#include <stdio.h>
int main(void)
{
int num, i;
printf("请输入一个整数:");
scanf("%d", &num);
/* 打印 num 到 num+10,共 11 个数 */
for (i = 0; i <= 10; i++)
printf("%d ", num + i);
printf("\n");
return 0;
}
运行结果:
请输入一个整数:5 6 7 8 9 10 11 12 13 14 15
5-3
题目: 编写一个程序,提示用户输入天数,然后将其转换成周数和天数。 例如,用户输入18,则转换成2周4天。以下面的格式显示结果: 18 days are 2 weeks, 4 days. 通过while循环让用户重复输入天数,当用户输入一个非正值时(如0 或-20),循环结束。
代码:
/* 第5章 5.11 编程练习 第3题
提示用户输入天数,然后转换成周数和天数。
例如输入 18,则转换成 2 周 4 天,显示格式:
18 days are 2 weeks, 4 days.
通过 while 循环让用户重复输入,当输入非正值时(如 0 或 -20)循环结束。 */
#include <stdio.h>
#define DAY_PER_WEEK 7
int main(void)
{
int days, week, day;
printf("请输入天数(非正值结束):");
scanf("%d", &days);
while (days > 0)
{
week = days / DAY_PER_WEEK; /* 整数除法得周数 */
day = days % DAY_PER_WEEK; /* 取模得剩余天数 */
printf("%d days are %d weeks, %d days.\n", days, week, day);
printf("请输入天数(非正值结束):");
scanf("%d", &days);
}
printf("Done!\n");
return 0;
}
运行结果:
请输入天数(非正值结束):18 days are 2 weeks, 4 days.
请输入天数(非正值结束):Done!
5-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.0 cm = 5 feet, 6.4 inches Enter a height in centimeters (<=0 to quit): 0 bye
代码:
/* 第5章 5.11 编程练习 第4题
提示用户输入身高(单位:厘米),分别以厘米和英尺/英寸显示该值,允许有小数部分。
让用户重复输入,直到输入非正值。输出示例:
Enter a height in centimeters: 182
182.0 cm = 5 feet, 11.7 inches
Enter a height in centimeters (<=0 to quit): 0
bye */
#include <stdio.h>
#define CM_PER_INCH 2.54 /* 1 英寸 = 2.54 厘米 */
#define INCH_PER_FOOT 12.0 /* 1 英尺 = 12 英寸 */
int main(void)
{
double height; /* 身高(厘米) */
double inches; /* 总英寸 */
int feet; /* 英尺(整数部分) */
double remain; /* 剩余英寸 */
printf("Enter a height in centimeters: ");
scanf("%lf", &height);
while (height > 0)
{
inches = height / CM_PER_INCH; /* 厘米换算成英寸 */
feet = (int)(inches / INCH_PER_FOOT); /* 英寸换算成英尺 */
remain = inches - feet * INCH_PER_FOOT; /* 剩余英寸 */
printf("%.1f cm = %d feet, %.1f inches\n", height, feet, remain);
printf("Enter a height in centimeters (<=0 to quit): ");
scanf("%lf", &height);
}
printf("bye\n");
return 0;
}
运行结果:
Enter a height in centimeters: 182.0 cm = 5 feet, 11.7 inches
Enter a height in centimeters (<=0 to quit): 168.7 cm = 5 feet, 6.4 inches
Enter a height in centimeters (<=0 to quit): bye
5-5
题目: 修改程序addemup.c(程序清单5.13),你可以认为addemup.c是计算20天里赚多少钱的程序 (假设第1天赚$1、第2天赚$2、第3天赚$3,以此类推)。 修改程序,使其可以与用户交互,根据用户输入的数进行计算 (即, 用读入的一个变量来代替20)。
代码:
/* 第5章 5.11 编程练习 第5题
修改程序 addemup.c(程序清单 5.13)。addemup.c 计算前 20 个整数的和,
可以理解成"20 天里第 1 天赚 $1、第 2 天赚 $2、第 3 天赚 $3……"的程序。
修改程序,使其可以与用户交互:用一个读入的变量代替 20,
根据用户输入的天数计算总和。 */
#include <stdio.h>
int main(void)
{
int days, i, sum = 0;
printf("请输入天数:");
scanf("%d", &days);
for (i = 1; i <= days; i++)
sum = sum + i; /* 第 i 天赚 i 元 */
printf("前 %d 天的总收入为 $%d\n", days, sum);
return 0;
}
运行结果:
请输入天数:前 20 天的总收入为 $210
5-6
题目: 修改编程练习5的程序,使其能计算整数的平方和(可以认为第1天赚 $1、第2天赚$4、第3天赚$9,以此类推,这看起来很不错)。 C没有平方函数,但是可以用n * n来表示n的平方。
代码:
/* 第5章 5.11 编程练习 第6题
修改编程练习 5,使其能计算整数的平方和
(第 1 天赚 $1、第 2 天赚 $4、第 3 天赚 $9,以此类推)。
C 没有平方函数,用 n * n 表示 n 的平方。 */
#include <stdio.h>
int main(void)
{
int days, i, sum = 0;
printf("请输入天数:");
scanf("%d", &days);
for (i = 1; i <= days; i++)
sum = sum + i * i; /* 第 i 天赚 i*i 元 */
printf("前 %d 天的总收入为 $%d\n", days, sum);
return 0;
}
运行结果:
请输入天数:前 20 天的总收入为 $2870
5-7
题目: 编写一个程序,提示用户输入一个double类型的数,并打印该数的立方值。 自己设计一个函数计算并打印立方值。main()函数要把用户输入的值传递给该函数。
代码:
/* 第5章 5.11 编程练习 第7题
提示用户输入一个 double 类型的数,并打印该数的立方值。
自己设计一个函数 cube() 计算并打印立方值,
main() 函数要把用户输入的值传递给该函数。 */
#include <stdio.h>
double cube(double n); /* 函数原型:计算 n 的立方 */
int main(void)
{
double num;
printf("请输入一个数:");
scanf("%lf", &num);
printf("%.2f 的立方是 %.2f\n", num, cube(num));
return 0;
}
double cube(double n)
{
return n * n * n;
}
运行结果:
请输入一个数:3.50 的立方是 42.88
5-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
代码:
/* 第5章 5.11 编程练习 第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): 0
Done */
#include <stdio.h>
int main(void)
{
int base, num;
printf("This program computes moduli.\n");
printf("Enter an integer to serve as the second operand: ");
scanf("%d", &base);
printf("Now enter the first operand: ");
scanf("%d", &num);
while (num > 0)
{
printf("%d %% %d is %d\n", num, base, num % base);
printf("Enter next number for first operand (<= 0 to quit): ");
scanf("%d", &num);
}
printf("Done\n");
return 0;
}
运行结果:
This program computes moduli.
Enter an integer to serve as the second operand: Now enter the first operand: 438 % 256 is 182
Enter next number for first operand (<= 0 to quit): 1234567 % 256 is 135
Enter next number for first operand (<= 0 to quit): Done
5-9
题目: 编写一个程序,要求用户输入一个华氏温度。程序应读取double类型的值作为温度值, 并把该值作为参数传递给一个用户自定义的函数Temperatures()。 该函数计算摄氏温度和开氏温度,并以小数点后面两位数字的精度显示3种温度。 要使用不同的温标来表示这3个温度值。下面是华氏温度转摄氏温度的公式: 摄氏温度 = 5.0 / 9.0 * (华氏温度 - 32.0) 开氏温标常用于科学研究,0表示绝对零,代表最低的温度。 下面是摄氏温度转开氏温度的公式: 开氏温度 = 摄氏温度 + 273.16 Temperatures()函数中用const创建温度转换中使用的变量。 在main()函数 中使用一个循环让用户重复输入温度,当用户输入q或其他非数字时,循环结束。 scanf()函数返回读取数据的数量,所以如果读取数字则返回1,如果读取q则不返回1。 可以使用==运算符将scanf()的返回值和1作比较,测试两值是否相等。
代码:
/* 第5章 5.11 编程练习 第9题
要求用户输入一个华氏温度(double),作为参数传递给自定义函数 Temperatures(),
该函数计算摄氏温度和开氏温度,并以小数点后 2 位的精度显示 3 种温度。
公式:摄氏温度 = 5.0 / 9.0 * (华氏温度 - 32.0)
开氏温度 = 摄氏温度 + 273.16
Temperatures() 函数中用 const 创建温度转换中使用的变量。
main() 中用循环让用户重复输入,当输入 q 或其他非数字时循环结束
(scanf() 返回读取数据的数量:读数字返回 1,读 q 不返回 1)。 */
#include <stdio.h>
void Temperatures(double fahrenheit); /* 函数原型 */
int main(void)
{
double temp;
int result;
printf("请输入华氏温度(输入 q 退出):");
result = scanf("%lf", &temp);
while (result == 1)
{
Temperatures(temp);
printf("请输入华氏温度(输入 q 退出):");
result = scanf("%lf", &temp);
}
printf("Done!\n");
return 0;
}
void Temperatures(double fahrenheit)
{
const double F2C1 = 5.0; /* 转换系数 */
const double F2C2 = 9.0;
const double F2C3 = 32.0;
const double C2K = 273.16; /* 开氏温度偏移 */
double celsius = F2C1 / F2C2 * (fahrenheit - F2C3);
double kelvin = celsius + C2K;
printf("%.2f 华氏度 = %.2f 摄氏度 = %.2f 开氏度\n",
fahrenheit, celsius, kelvin);
}
运行结果:
请输入华氏温度(输入 q 退出):212.00 华氏度 = 100.00 摄氏度 = 373.16 开氏度
请输入华氏温度(输入 q 退出):Done!
三、运行给定程序(观察结果)
run1
程序说明: 程序清单 talking.c 的演示——PRAISE 字符串,观察 strlen()(字符数,不含结束符)与 sizeof(占用字节数,含结束符)的区别
程序代码:
/* 运行程序(1):strlen 与 sizeof 的演示 */
#include <stdio.h>
#include <string.h> /* 提供 strlen() 原型 */
#define PRAISE "What a super marvelous name!"
int main(void)
{
char name[40];
printf("What's your name?\n");
scanf("%s", name);
printf("Hello, %s. %s\n", name, PRAISE);
printf("Your name of %d letters occupies %d memory cells.\n",
strlen(name), sizeof name);
printf("The phrase of praise has %d letters ", strlen(PRAISE));
printf("and occupies %d memory cells.\n", sizeof PRAISE);
return 0;
}
运行结果:
What's your name?
Hello, Dabney. What a super marvelous name!
Your name of 6 letters occupies 40 memory cells.
The phrase of praise has 28 letters and occupies 29 memory cells.
run2
程序说明: 程序清单 rows2.c 棋盘麦粒——64 格,每格麦粒数是前一格的 2 倍,观察指数增长与 US 总量占比
程序代码:
/* 运行程序(2):棋盘上的麦粒(2 的幂逐格累加) */
#include <stdio.h>
#define SQUARES 64 /* 棋盘上的方格数 */
#define CROP 1E15 /* 以粒计的美国小麦产量 */
int main(void)
{
double current, total;
int count = 1;
printf("square grains total ");
printf("fraction of \n");
printf(" added grains ");
printf("US total\n");
total = current = 1.0; /* 从一粒开始 */
printf("%4d %13.2e %12.2e %12.2e\n", count, current, total, total / CROP);
while (count < SQUARES)
{
count = count + 1;
current = 2.0 * current;
total = total + current;
printf("%4d %13.2e %12.2e %12.2e\n", count, current, total, total / CROP);
}
printf("That's all.\n");
return 0;
}
运行结果:
square grains total fraction of
added grains US total
1 1.00e+00 1.00e+00 1.00e-15
2 2.00e+00 3.00e+00 3.00e-15
3 4.00e+00 7.00e+00 7.00e-15
4 8.00e+00 1.50e+01 1.50e-14
5 1.60e+01 3.10e+01 3.10e-14
6 3.20e+01 6.30e+01 6.30e-14
7 6.40e+01 1.27e+02 1.27e-13
8 1.28e+02 2.55e+02 2.55e-13
9 2.56e+02 5.11e+02 5.11e-13
10 5.12e+02 1.02e+03 1.02e-12
11 1.02e+03 2.05e+03 2.05e-12
12 2.05e+03 4.10e+03 4.09e-12
13 4.10e+03 8.19e+03 8.19e-12
14 8.19e+03 1.64e+04 1.64e-11
15 1.64e+04 3.28e+04 3.28e-11
16 3.28e+04 6.55e+04 6.55e-11
17 6.55e+04 1.31e+05 1.31e-10
18 1.31e+05 2.62e+05 2.62e-10
19 2.62e+05 5.24e+05 5.24e-10
20 5.24e+05 1.05e+06 1.05e-09
21 1.05e+06 2.10e+06 2.10e-09
22 2.10e+06 4.19e+06 4.19e-09
23 4.19e+06 8.39e+06 8.39e-09
24 8.39e+06 1.68e+07 1.68e-08
25 1.68e+07 3.36e+07 3.36e-08
26 3.36e+07 6.71e+07 6.71e-08
27 6.71e+07 1.34e+08 1.34e-07
28 1.34e+08 2.68e+08 2.68e-07
29 2.68e+08 5.37e+08 5.37e-07
30 5.37e+08 1.07e+09 1.07e-06
31 1.07e+09 2.15e+09 2.15e-06
32 2.15e+09 4.29e+09 4.29e-06
33 4.29e+09 8.59e+09 8.59e-06
34 8.59e+09 1.72e+10 1.72e-05
35 1.72e+10 3.44e+10 3.44e-05
36 3.44e+10 6.87e+10 6.87e-05
37 6.87e+10 1.37e+11 1.37e-04
38 1.37e+11 2.75e+11 2.75e-04
39 2.75e+11 5.50e+11 5.50e-04
40 5.50e+11 1.10e+12 1.10e-03
41 1.10e+12 2.20e+12 2.20e-03
42 2.20e+12 4.40e+12 4.40e-03
43 4.40e+12 8.80e+12 8.80e-03
44 8.80e+12 1.76e+13 1.76e-02
45 1.76e+13 3.52e+13 3.52e-02
46 3.52e+13 7.04e+13 7.04e-02
47 7.04e+13 1.41e+14 1.41e-01
48 1.41e+14 2.81e+14 2.81e-01
49 2.81e+14 5.63e+14 5.63e-01
50 5.63e+14 1.13e+15 1.13e+00
51 1.13e+15 2.25e+15 2.25e+00
52 2.25e+15 4.50e+15 4.50e+00
53 4.50e+15 9.01e+15 9.01e+00
54 9.01e+15 1.80e+16 1.80e+01
55 1.80e+16 3.60e+16 3.60e+01
56 3.60e+16 7.21e+16 7.21e+01
57 7.21e+16 1.44e+17 1.44e+02
58 1.44e+17 2.88e+17 2.88e+02
59 2.88e+17 5.76e+17 5.76e+02
60 5.76e+17 1.15e+18 1.15e+03
61 1.15e+18 2.31e+18 2.31e+03
62 2.31e+18 4.61e+18 4.61e+03
63 4.61e+18 9.22e+18 9.22e+03
64 9.22e+18 1.84e+19 1.84e+04
That's all.
run3
程序说明: 程序清单 toobig.c——把过大的浮点数 5212205.17 赋给 char 类型,观察类型转换时的溢出截断
程序代码:
/* 运行程序(3):字符、整型、浮点之间的类型转换 */
#include <stdio.h>
int main(void)
{
char ch;
int i;
float fl;
fl = i = ch = 'C';
printf("ch = %c, i = %d, fl = %2.2f\n", ch, i, fl);
ch = ch + 1;
i = fl + 2 * ch;
fl = 2.0 * ch + i;
printf("ch = %c, i = %d, fl = %2.2f\n", ch, i, fl);
ch = 5212205.17;
printf("Now ch = %c\n", ch);
return 0;
}
运行结果:
ch = C, i = 67, fl = 67.00
ch = D, i = 203, fl = 339.00
Now ch =
run4
程序说明: 程序清单 pound.c——pound() 函数返回 # 号,观察 char/float/double 实参传给 int 形参时的自动类型转换
程序代码:
/* 运行程序(4):pound() 函数演示(实参类型转换) */
#include <stdio.h>
void pound(int n); /* 函数原型 */
int main(void)
{
int times = 5;
char ch = '!';
float f = 6.0;
pound(times); /* 传入 int */
pound(ch); /* char 自动转换为 int */
pound((int) f); /* float 强制转换为 int */
return 0;
}
void pound(int n)
{
while (n-- > 0)
printf("#");
printf("\n");
}
运行结果:
#####
#################################
######
四、设计题
设计1:运算符优先级演示(自增/自减与四则运算混用)
设计思路: 用几组表达式对比 ++ / -- 前缀与后缀的取值时机,以及它们与乘除运算结合时的优先级与结合顺序。
代码:
/* 设计题1:设计一个可以展示运算符优先级的程序
(自增/自减运算与四则运算混用时的优先级演示) */
#include <stdio.h>
int main(void)
{
int a, b, result;
/* 例子1:前置 ++ 先自增,再参与四则运算 */
a = 5;
result = ++a + 2; /* 等价于 a=a+1; result=a+2; 结果 8,a 变为 6 */
printf("a=5 时, ++a + 2 = %d(a 变为 %d)\n", result, a);
/* 例子2:后置 ++ 先用原值参与运算,再自增 */
a = 5;
result = a++ + 2; /* 等价于 result=a+2; a=a+1; 结果 7,a 变为 6 */
printf("a=5 时, a++ + 2 = %d(a 变为 %d)\n", result, a);
/* 例子3:自增/自减优先级高于乘除,先自增减,再相乘 */
a = 3; b = 4;
result = ++a * --b; /* 先 ++a=4、--b=3,再 4*3=12 */
printf("a=3,b=4 时, ++a * --b = %d(a=%d, b=%d)\n", result, a, b);
/* 例子4:后置自增/自减用原值参与运算,运算后再自增减 */
a = 3; b = 4;
result = a++ * b--; /* 用原值 3*4=12,然后 a=4、b=3 */
printf("a=3,b=4 时, a++ * b-- = %d(a=%d, b=%d)\n", result, a, b);
return 0;
}
运行结果:
a=5 时, ++a + 2 = 8(a 变为 6)
a=5 时, a++ + 2 = 7(a 变为 6)
a=3,b=4 时, ++a * --b = 12(a=4, b=3)
a=3,b=4 时, a++ * b-- = 12(a=4, b=3)
设计2:运算符优先级从高到低一行行展示
设计思路: 用一张表把 C 语言的运算符按优先级从高到低排列并逐行打印,直观呈现各运算符的优先级层级。
代码:
/* 设计题2:设计一个程序,将 C 语言的运算符优先级从高到低一行行展示出来 */
#include <stdio.h>
int main(void)
{
printf("===== C 语言运算符优先级(从高到低)=====\n");
printf("1. ( ) [ ] -> . 函数调用、下标、成员访问\n");
printf("2. ++ -- ! ~ + - * & (类型) sizeof 单目运算符\n");
printf("3. * / %% 乘、除、取模\n");
printf("4. + - 加、减\n");
printf("5. << >> 左移、右移\n");
printf("6. < <= > >= 关系运算符(小于、小于等于、大于、大于等于)\n");
printf("7. == != 关系运算符(等于、不等于)\n");
printf("8. & 按位与\n");
printf("9. ^ 按位异或\n");
printf("10. | 按位或\n");
printf("11. && 逻辑与\n");
printf("12. || 逻辑或\n");
printf("13. ? : 条件运算符\n");
printf("14. = += -= *= /= %%= <<= >>= &= ^= |= 赋值运算符\n");
printf("15. , 逗号运算符\n");
printf("==========================================\n");
return 0;
}
运行结果:
===== C 语言运算符优先级(从高到低)=====
1. ( ) [ ] -> . 函数调用、下标、成员访问
2. ++ -- ! ~ + - * & (类型) sizeof 单目运算符
3. * / % 乘、除、取模
4. + - 加、减
5. << >> 左移、右移
6. < <= > >= 关系运算符(小于、小于等于、大于、大于等于)
7. == != 关系运算符(等于、不等于)
8. & 按位与
9. ^ 按位异或
10. | 按位或
11. && 逻辑与
12. || 逻辑或
13. ? : 条件运算符
14. = += -= *= /= %= <<= >>= &= ^= |= 赋值运算符
15. , 逗号运算符
==========================================
五、遇到的问题和解决办法
- float 与 double 精度差异:4-7 题中,1.0/3.0 用 float 存时,显示到小数点后 12 位就开始出现误差(0.333333343267),而 double 能保持 15 位有效数字。这与 float.h 里的 FLT_DIG=6、DBL_DIG=15 一致——float 只有约 6 位有效数字,double 约 15 位。
- printf 输出百分号:设计2 里想打印 %= 这个赋值运算符,直接写 printf("%= ") 会出错,因为 % 是格式转换说明符。解决:写成 %%,printf 遇到 %% 才输出一个真正的 %。
- 类型转换溢出:run3 里把 5212205.17 赋给 char,超过 char 的取值范围,结果被截断(只保留低 8 位),得到一个不可打印字符。这说明 C 语言赋值时不会自动做范围检查,写程序时要自己注意。
- scanf 返回值判断循环退出:5-9 题用 scanf("%lf", &temp) == 1 判断用户是否输入了合法数字,输入 q 时 scanf 返回 0,循环自动结束,比额外设标志位更简洁。
六、总结与思考
这次作业覆盖了第 4 章的字符串与格式化输入输出、第 5 章的循环结构(while/do-while/for)和函数初步。最大的收获是:
- 格式化输出(%20s、%-20s、%*s、%.1f、%e)看似细节,实际决定了程序的可用性,值得多练。
- 循环的三种写法各有适用场景:while 适合「先判断后执行」(5-1、5-3),do-while 适合「至少执行一次」(5-2),for 适合「次数确定」的累加(5-5、5-6)。
- 函数把重复逻辑封装起来(5-7 的 cube、5-9 的 Temperatures),让 main 更清爽,也更好复用。
- 数据类型的边界(float 精度、char 溢出)提醒我:写程序不能只看「能跑」,还要清楚每个变量能装下多大的数。
浙公网安备 33010602011771号