高级语言程序设计课程第三次个人作业

课程链接: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. ,                    逗号运算符
==========================================

五、遇到的问题和解决办法

  1. 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 位。
  2. printf 输出百分号:设计2 里想打印 %= 这个赋值运算符,直接写 printf("%= ") 会出错,因为 % 是格式转换说明符。解决:写成 %%,printf 遇到 %% 才输出一个真正的 %。
  3. 类型转换溢出:run3 里把 5212205.17 赋给 char,超过 char 的取值范围,结果被截断(只保留低 8 位),得到一个不可打印字符。这说明 C 语言赋值时不会自动做范围检查,写程序时要自己注意。
  4. 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 溢出)提醒我:写程序不能只看「能跑」,还要清楚每个变量能装下多大的数。
posted @ 2026-10-28 19:33  grylls_teng  阅读(10)  评论(0)    收藏  举报