乐趣区

关于c:浙大版C语言程序设计第四版何钦铭颜晖-第9章-结构-课后习题答案

你也能够上程序咖 (https://meta.chengxuka.com),关上大学幕题板块,岂但有答案,解说,还能够在线答题。

一、选择题

1. 以下定义构造变量的语句中,谬误的是()。

A. struct student {int num; char name[ 20];} s;

B. struct {int num; char name[ 20] ;} s;

C. struct student {int num; char name[ 20] ;} ; student s;

D. struct student {int num; char name [ 20] ; } ; struct student s;

答:C

解析:

构造变量名能够在定义构造后独自定义。也能够跟在构造后间接定义,间接写构造变量名即可。

2. 如果构造变量 s 中的生日是“1984 年 11 月 11 日”,下列对其生日的正确赋值是()。

struct student{int no; char name[20]; char sex;
    struct {int year; int month; int day;}birth;
}s;

A. year= 1984; month=11; day=11;

B. birth. year= 1984; birth. month=11; birth. day=11;

C. s. year= 1984; s. month=11; s. day=11;

D. s. birth. year= 1984; s. birth. month= 11; s. birth. day=11;

答:D

解析:

s 对应的构造为 student,birth 是它的一个成员,year,month,day 是 birth 的成员。所以要通过 s. birth. year= 1984; s. birth. month= 11; s. birth. day=11; 示意。

3. 以下程序段的输入后果为()。

struct
    {int x, y;} s[2] = {{1, 3}, {2, 7}};
    printf("%d\n", s[0].y / s[1].x);

A.0

B.1

C.2

D.3

答:B

解析:

这里打印的后果是 s[0].y / s[1].x,就是 3 / 2 的后果,是 1。

4. 没有如下定义,则对 data 中的 a 成员的正确援用是()。

struct sk{int a; double b;}data, *p=&data;

A. (*p).data.a

B. (*p).a

C. p->data. a

D. p.data.a

答:B

解析:

这里 *p 指向 data,想援用对应的 a,间接 (*p).a 即可。所以这里选 B。

5. 对于以下构造定义,++p->str 中的 ++ 加在()。

struct{int len; char *str;}*P;

A. 指针 str 上

B. 指针 p 上

C. str 指向的内容上

D. 语法错误

答:D

解析:p 是指针,能够写 p->str,然而 (*p) 只能写 (*p).str;

6. 若有下列定义,则以下不非法的表达式是()。

struct student
    {
        int num;
        int age;
    } stu[3] = {{101, 20}, {102, 19}, {103, 20}}, *p = stu;

A. (p++)->num

B. p++

C. (*p). num

D. p= &stu.age

答:D

解析:

p 是 struct student 类型的指针,stu.age 是 int 型变量,p 指向 stu.age 会产生类型不匹配的问题

二、填空题

1. 写出上面程序段的运行后果()。

    struct example
    {
        struct
        {
            int x;
            int y;
        } in;
        int a;
        int b;
    } e;
    e.a = 1;
    e.b = 2;
    e.in.x = e.a * e.b;
    e.in.y = e.a + e.b;
    printf("%d,%d\n", e.in.x, e.in.y);

答:2,3

解析:

e.a = 1, e.b = 2,

e.in.x = e.a e.b = 1 2 = 2

e.in.y = e.a + e.b = 1 + 2 = 3

最终打印 2 和 3。

2. 工夫计算。读入工夫数值,将其加 1 秒后输入,工夫格局为 “hh: mm: ss”,即 “ 小时: 分钟: 秒 ”,当小时等于 24 小时,置为 0。请填空。

#include <stdio.h>
struct
{int hour, minute, second;} time;
int main()
{scanf("%d:%d:%d", _______________);
    time.second++;
    if (_______________ == 60)
    {
        _______________;
        time.second = 0;
        if (time.minute == 60)
        {
            time.hour++;
            time.minute = 0;
            if (_______________ == 24)
            {time.hour = 0;}
        }
    }
    printf("%d:%d:%d\n", time.hour, time.minute, time.second);
    return 0;
}

答:

&time.hour, &time.minute, &time.second

time.second

time.minute++

time.hour

解析:

第一空,&time.hour, &time.minute, &time.second,读入工夫的时,分,秒。而后依据题意,给秒加 1。

第二空,time.second == 60,判断秒是否是 60。

第三空,time.minute++,如果是,那么分钟累加 1,秒置为 0。而后判断分钟是否是 60,如果是,时就累加 1,而后分钟置为 0。

第四空,time.hour == 24,如果时为 24,要将时置为 0,示意第二天了。

3.”.” 称为()运算符,”->” 称为()运算符。

答:重量 指向

解析:

. 叫做构造成员操作符。用于拜访构造成员。

-> 叫做指向运算符。用于拜访指针指向的构造成员。

4. 写出上面程序段的运行后果()。

    struct example
    {
        int a;
        double b;
        char *c;
    } x = {23, 98.5, "wang"}, *px = &x;
    printf("%d,%s,%.1f,%s\n", x.a, x.c, (*px).b, px->c);

答:23,wang,98.5,wang

解析:

打印语句中,先打印 x.a,就是 23,而后打印 x.c,就是 wang,而后 (*px).b,这里 px 指向 x,打印的就是 98.5,px->c,打印 wang。

5. 写出上面程序段的运行后果()。

    struct table
    {int x, y;} a[4] = {{10, 20}, {30, 40}, {50, 60}, {70, 80}};
    struct table *p = a;
    printf("%d,", p++->x);
    printf("%d,", ++p->y);
    printf("%d\n", (a + 3)->x);

答:10,41,70

解析:

第一行打印:p++->x,最后 p 指向数组 a 的第一个元素,打印它的 x,值为 10。而后 p 指向下一个元素。

第二行打印:此时 p 指向第二个元素 {30,40},++p->y,这里示意取 p->y,40,而后 ++,打印 41。

第三行打印:(a + 3)->x,a+3 示意外面下标为 3 的元素,就是 {70,80},取 x 打印出 70。

6. 写出上面程序段的运行后果()。

struct
    {
        int a;
        int *b;
    } s[4], *p;
    int i, n = 1;
    for (i = 0; i < 4; i++)
    {s[i].a = n;
        s[i].b = &s[i].a;
        n = n + 2;
    }
    p = &s[0];
    printf("%d\n", ++*p->b);
    p++;
    printf("%d,%d\n", (++p)->a, (p++)->a);

答:

2

5,5

解析:

for 循环中次要是为了给数组 s 中的 4 个元素赋值。

s[0] 中 a 和 b 别离是 1。

s[1] 中 a 和 b 别离是 3。

s[2] 中 a 和 b 别离是 5。

s[3] 中 a 和 b 别离是 7。

第一行打印语句,++*p->b,这里取 *p 指向数组中的第一个元素,取 b 的值,就是 1。而后有个前置的 ++,所以打印的是 2。

第二行打印语句,(++p)->a,在这之前,下面有一行独自的 p++,那么 p 会指向数组中第二个元素,这里 (++p) 后,那么 p 就指向了数组第三个元素,打印 它的 a,就是 5。再打印 (p++)->a,这里 (p++),还是先运算再累加 1,所以还是打印第三个元素的 a,而后 p 指向第四个元素。

三、程序设计题

题目 1:工夫换算:用构造类型示意工夫内容(工夫以时、分、秒示意),输出一个工夫数值,再输出一个秒数 n(n<60),以 h: m: s 的格局输入该工夫再过 n 秒后的工夫值(超过 24 点就从 0 点开始计时)。试编写相应程序。

答案代码:

#include <stdio.h>

struct time
{
    int hour;
    int minute;
    int second;
};

void add(struct time *p, int s);

int main()
{// 习题 (9.3.1)
    /*
    工夫换算:用构造类型示意工夫内容(工夫以时、分、秒示意),输出一个工夫数值,再输出一个秒数 n(n<60),以 h: m: s 的格局输入该工夫再过 n 秒后的工夫值(超过 24 点就从 0 点开始计时)。*/

    struct time c;
    int n;
    printf("input time:");
    scanf("%d%d%d", &c.hour, &c.minute, &c.second);
    printf("input n:");
    scanf("%d", &n);
    add(&c, n);
    printf("%d: %d: %d\n", c.hour, c.minute, c.second);
    return 0;
}

void add(struct time *p, int s)
{
    int ho, mi, se;
    ho = p->hour;
    mi = p->minute;
    se = p->second;
    se = se + s;
    if (se < 60)
    {
        p->second = se;
        return;
    }
    else
    {
        mi = p->minute = mi + se / 60;
        se = p->second = se % 60;
        if (mi < 60)
        {return;}
        else
        {
            mi = p->minute = mi % 60;
            ho = ho + mi / 60;
            mi = p->hour = mi % 60;
        }
        if (ho < 24)
        {return;}
        else
            mi = p->hour = mi % 24;
        return;
    }
}

运行后果:

题目 2:计算两个复数之积:编写程序,利用构造变量求解两个复数之积。

提醒:求解 (a1+a2i)x(b1+b2i),乘积的实部为:a1xb1-a2xb2,虚部为:a1xb2+a2xb1。

答案代码:

#include <stdio.h>
struct complex
{int real, im;};
struct complex cmult(struct complex, struct complex);
int main()
{// 习题 (9.3.2)
    /*
    计算两个复数之积:编写程序,利用构造变量求解两个复数之积。提醒:求解 (a1+a2i)x(b1+b2i),乘积的实部为:a1xb1-a2xb2,虚部为:a1xb2+a2xb1。*/

    struct complex a = {3, 4}, b = {5, 6}, c;
    c = cmult(a, b);
    printf("(%d+%di)x(%d+%di) =%d+%di\n", a.real, a.im, b.real, b.im, c.real, c.im);
    return 0;
}
struct complex cmult(struct complex a, struct complex b)
{
    struct complex w;
    w.real = a.real * b.real - a.im * b.im;
    w.im = a.real * b.im + a.im * b.real;
    return w;
}

运行后果:

题目 3:立体向量加法:输出两个二维立体向量 V1=(x1, y1) 和 V2=(x2, y2) 的重量,计算并输入两个向量的和向量。试编写相应程序。

答案代码:

#include <stdio.h>

struct vector
{
    double x;
    double y;
};

struct vector vector_add(struct vector v1, struct vector v2);

int main()
{// 习题 (9.3.3)
    /*
    立体向量加法:输出两个二维立体向量 V1=(x1, y1) 和 V2=(x2, y2) 的重量,计算并输入两个向量的和向量。*/

    struct vector v1, v2, sum;
    double s1, s2;
    printf("input first vector:\n");
    scanf("%lf%lf", &v1.x, &v1.y);
    printf("input second vector:\n");
    scanf("%lf%lf", &v2.x, &v2.y);

    sum = vector_add(v1, v2);
    printf("(%.1lf, %.1lf)\n", sum.x, sum.y);

    return 0;
}

struct vector vector_add(struct vector v1, struct vector v2)
{
    struct vector sum;
    double s1, s2;
    s1 = v1.x + v2.x;
    s2 = v1.y + v2.y;
    sum.x = s1;
    sum.y = s2;
    return sum;
}

运行后果:

题目 4:查找书籍:从键盘输入 10 本书的名称和定价并存入构造数组中,从中查找定价最高和最低的书的名称和定价,并输入。试编写相应程序。

答案代码:

#include <stdio.h>

#define NUMBER 10
struct book
{char name[30];
    float price;
};
int main()
{// 习题 (9.3.4)
    /*
    查找书籍:从键盘输入 10 本书的名称和定价并存入构造数组中,从中查找定价最高和最低的书的名称和定价,并输入。*/
    int i, max1, min1;
    struct book test[NUMBER];
    printf("input 10 book's name and price\n");
    for (i = 0; i < NUMBER; i++)
        scanf("%s%f", test[i].name, &test[i].price);
    max1 = min1 = 0;
    for (i = 1; i < NUMBER; i++)
    {if (test[max1].price < test[i].price)
            max1 = i;
        if (test[min1].price > test[i].price)
            min1 = i;
    }
    printf("Max Price: %.2f, %s\n", test[max1].price, test[max1].name);
    printf("Min Price: %.2f, %s\n", test[min1].price, test[min1].name);
    return 0;
}

运行后果:

题目 5:通信录排序:建设一个通信录,通信录的构造记录包含:姓名、生日、电话号码; 其中生日又包含三项:年、月、日。编写程序,定义一个嵌套的构造类型,输出 n(n<10)个联系人的信息,再按他们的年龄从大到小的程序顺次输入其信息。试编写相应程序。

答案代码:

#include <stdio.h>
struct birth
{
    int year;
    int month;
    int date;
};

struct friends_list
{char name[10];           /* 姓名 */
    struct birth birthday; /* 生日 */
    char phone[15];           /* 电话号码 */
    char address[50];       /* 住址 */
};
void sort(struct friends_list s[], int n) /* 按生日日期从小到大排序 */
{
    int i, j;
    struct friends_list temp;
    for (i = 1; i < n; i++)
        for (j = 0; j < n - i; j++)
            // 先判断年份
            if (s[j].birthday.year > s[j + 1].birthday.year)
            {temp = s[j];
                s[j] = s[j + 1];
                s[j + 1] = temp;
            }
            else if (s[j].birthday.year == s[j + 1].birthday.year)
            {if (s[j].birthday.month > s[j + 1].birthday.month)
                {temp = s[j];
                    s[j] = s[j + 1];
                    s[j + 1] = temp;
                }
                else if (s[j].birthday.month == s[j + 1].birthday.month)
                {if (s[j].birthday.date > s[j + 1].birthday.date)
                    {temp = s[j];
                        s[j] = s[j + 1];
                        s[j + 1] = temp;
                    }
                }
            }
}

int main()
{// 习题 (9.3.5)
    /*
    通信录排序:建设一个通信录,通信录的构造记录包含:姓名、生日、电话号码;
    其中生日又包含三项:年、月、日。编写程序,定义一个嵌套的构造类型,输出 n(n<10)个联系人的信息,再按他们的年龄从大到小的程序顺次输入其信息。*/
    int i, n;
    struct friends_list friends[10];
    printf("input n:");
    scanf("%d", &n);
    for (i = 0; i < n; i++) /* 输出 n 集体的通信信息 */
    {printf("请输出第 %d 集体的信息: 姓名 年 月 日 手机号 地址 \n", i + 1);
        scanf("%s%d%d%d%s%s", friends[i].name, &friends[i].birthday.year, &friends[i].birthday.month, &friends[i].birthday.date, friends[i].phone, friends[i].address);
    }
    printf("------------------------------------------------------------------------\n");
    printf("通讯录信息:\n");
    for (i = 0; i < n; i++)
        /* 输入 */
        printf("%s\t%d\t%d\t%d\t%s\t%s\n", friends[i].name, friends[i].birthday.year, friends[i].birthday.month, friends[i].birthday.date, friends[i].phone, friends[i].address);
    printf("------------------------------------------------------------------------\n");
    printf("排序后信息:\n");
    /* 按年龄从大到小排序 */
    sort(friends, n);
    for (i = 0; i < n; i++)
        /* 输入 */
        printf("%s\t%d\t%d\t%d\t%s\t%s\n", friends[i].name, friends[i].birthday.year, friends[i].birthday.month, friends[i].birthday.date, friends[i].phone, friends[i].address);

    return 0;
}

运行后果:

题目 6:按等级统计学生问题:输出 10 个学生的学号、姓名和问题,输入学生的问题等级和不及格人数。每个学生的记录包含学号、姓名、问题和等级,要求定义和调用函数 set_grade(),依据学生问题设置其等级,并统计不及格人数,等级设置:85~100 为 A,70~84 为 B,60~69 为 C,0~59 为 D。试编写相应程序。

答案代码:

#include <stdio.h>
#define N 10
struct student
{
    int num;
    char name[20];
    int score;
    char grade;
};

int set_grade(struct student *p);

int main()
{// 习题 (9.3.6)
    /*
    按等级统计学生问题:输出 10 个学生的学号、姓名和问题,输入学生的问题等级和不及格人数。每个学生的记录包含学号、姓名、问题和等级,要求定义和调用函数 set_grade(),依据学生问题设置其等级,并统计不及格人数,等级设置:85~100 为 A,70~84 为 B,60~69 为 C,0~59 为 D。*/

    struct student stu[N], *ptr;
    int i, count;
    ptr = stu;
    printf("input the student's number, name and score: \n");
    for (i = 0; i < N; i++)
    {printf("No %d:", i + 1);
        scanf("%d%s%d", &stu[i].num, stu[i].name, &stu[i].score);
    }
    count = set_grade(ptr);
    printf("The count (<60): %d\n", count);
    printf("The student grade:\n");
    for (i = 0; i < N; i++)
        printf("%d\t%s\t%c\n", stu[i].num, stu[i].name, stu[i].grade);
    return 0;
}

// 等级设置
int set_grade(struct student *p)
{
    int i, n = 0;
    for (i = 0; i < N; i++, p++)
    {if (p->score >= 85)
            p->grade = 'A';
        else if (p->score >= 70)
            p->grade = 'B';
        else if (p->score >= 60)
            p->grade = 'C';
        else
        {
            p->grade = 'D';
            n++;
        }
    }
    return n;
}

运行后果:

退出移动版