谭浩强《C程序设计》书后习题 第十一章

最近要复习一下C和C++的基础知识,于是计划把之前学过的谭浩强的《C程序设计》和《C++程序设计》习题重新做一遍。

编译环境为:操作系统32位Win7,编译工具VC++6.0

第十一章:结构体

11.1)定义一个结构体变量(包括年、月、日),计算该日在本年中是第几天?

#include<stdio.h>

struct Date
{
    int Year;
    int Month;
    int Day;
}
d = { 2014, 9, 4 };

void main()
{
    int days = 0;

    //判断当年是否为闰年
    int isLeapYear = 0;
    if(d.Year / 400 == 0)
    {
        isLeapYear = 1;
    }
    if(d.Year / 4 == 0 && d.Year / 100 != 0)
    {
        isLeapYear = 1;
    }

    //计算过去的月份中共有多少天
    switch(d.Month)
    {
        case 12: days += 30; //11月有30天
        case 11: days += 31; //10月有31天
        case 10: days += 30; //9月有30天
        case 9: days += 31;  //8月有31天
        case 8: days += 31;  //7月有31天
        case 7: days += 30;  //6月有30天
        case 6: days += 31;  //5月有31天
        case 5: days += 30;  //4月有30天
        case 4: days += 31;  //3月有31天
        case 3: days += (isLeapYear ? 29 : 28);
        case 2: days += 31;  //1月有31天
        default:;
    }

    //补上当月已经过去的天数
    days += d.Day;

    printf("%d 年已经过去了 %d 天\n", d.Year, days);
}

11.2)写一个函数,实现11.1中的计算。由主函数将年、月、日传递给函数,计算后将日子由主函数输出

#include<stdio.h>

struct Date
{
    int Year;
    int Month;
    int Day;
};

//计算一年中已经过去多少天
int Days(int year, int month, int day)
{
    int days = 0;

    //判断当年是否为闰年
    int isLeapYear = 0;
    if(year / 400 == 0)
    {
        isLeapYear = 1;
    }
    if(year / 4 == 0 && year / 100 != 0)
    {
        isLeapYear = 1;
    }

    //计算过去的月份中共有多少天
    switch(month)
    {
        case 12: days += 30; //11月有30天
        case 11: days += 31; //10月有31天
        case 10: days += 30; //9月有30天
        case 9: days += 31;  //8月有31天
        case 8: days += 31;  //7月有31天
        case 7: days += 30;  //6月有30天
        case 6: days += 31;  //5月有31天
        case 5: days += 30;  //4月有30天
        case 4: days += 31;  //3月有31天
        case 3: days += (isLeapYear ? 29 : 28);
        case 2: days += 31;  //1月有31天
        default:;
    }

    //补上当月已经过去的天数
    days += day;

    return days;
}

void main()
{
    Date d;
    d.Year = 2014;
    d.Month = 9;
    d.Day = 4;

    printf("%d 年已经过去了 %d 天\n", d.Year, Days(d.Year, d.Month, d.Day));
}

11.3)编写一个函数,打印一个学生的成绩数组,该数组中有5个学生的数据记录,每个记录包括num、name、score[3],用主函数输入这些记录,用编写的函数输出

#include<stdio.h>

struct Student
{
    int num;
    char* name;
    int score[3];
}
stdlist[5] = 
{
    { 0, "Tsybius", { 85, 85, 85 } },
    { 1, "Galatea", { 99, 99, 99 } },
    { 2, "Gaius",   { 80, 80, 80 } },
    { 3, "Quintus", { 83, 83, 83 } },
    { 4, "Aurelia", { 82, 82, 82 } },
};

//打印某个学生信息
void PrintInfo(Student* stdlist, int no)
{
    printf("编号:%d\n", stdlist[no].num);
    printf("名称:%s\n", stdlist[no].name);
    printf("分数1:%d\n", stdlist[no].score[0]);
    printf("分数2:%d\n", stdlist[no].score[1]);
    printf("分数3:%d\n", stdlist[no].score[2]);
}

void main()
{
    Student *p = stdlist;
    PrintInfo(p, 3);
}

11.4)在11.3的基础上,编写一个函数,用来输入5个学生的数据记录

#include<stdio.h>

struct Student
{
    int num;
    char name[100]; //这个要改为数组形式
    int score[3];
}
stdlist[5];

//打印某个学生信息
void PrintInfo(Student* stdlist, int no)
{
    printf("编号:%d\n", stdlist[no].num);
    printf("名称:%s\n", stdlist[no].name);
    printf("分数1:%d\n", stdlist[no].score[0]);
    printf("分数2:%d\n", stdlist[no].score[1]);
    printf("分数3:%d\n", stdlist[no].score[2]);
}

//输入学生数据
void InputInfo(Student* stdlist)
{
    /************* 
      测试数据
      0 abc 1 2 3
      1 def 1 2 3
      2 ghi 1 2 3
      3 jkl 1 2 3
      4 mno 1 2 3 
     *************/

    int i;
    for(i = 0; i < 5; i++)
    {
        scanf("%d", &stdlist[i].num);
        scanf("%s", &stdlist[i].name);
        scanf("%d", &stdlist[i].score[0]);
        scanf("%d", &stdlist[i].score[1]);
        scanf("%d", &stdlist[i].score[2]);
    }
}

void main()
{
    Student *p = stdlist;
    
    //输入数据
    InputInfo(p);

    //输出编号为3的人
    PrintInfo(p, 3);
}

11.5)有10个学生,每个学生的数据包括学号、姓名、3门课的成绩,从键盘输入10个学生的数据,要求输出3门课的总平均成绩,以及最高分的学生的成绩(包括学号、3门课程成绩、平均分数)

#include<stdio.h>

struct Student
{
    int num;
    char name[100]; //这个要改为数组形式
    int score[3];
}
stdlist[10];

void main()
{
    //输入数据
    int i;
    for(i = 0; i < 10; i++)
    {
        scanf("%d", &stdlist[i].num);
        scanf("%s", &stdlist[i].name);
        scanf("%d", &stdlist[i].score[0]);
        scanf("%d", &stdlist[i].score[1]);
        scanf("%d", &stdlist[i].score[2]);
    }

    //计算平均总成绩和总成绩最高分
    int average = 0, max = 0, temp = 0, x = 0;
    for(i = 0; i < 10; i++)
    {
        temp = (stdlist[i].score[0] + stdlist[i].score[1] + stdlist[i].score[2]);
        average += temp;
        if(max < temp)
        {
            max = temp;
            x = i;
        }
    }
    average /= 10;

    printf("平均成绩:%d\n", average);
    printf("总成绩最高:%d\n,", x);
    
    printf("编号:%d\n", stdlist[x].num);
    printf("名称:%s\n", stdlist[x].name);
    printf("分数1:%d\n", stdlist[x].score[0]);
    printf("分数2:%d\n", stdlist[x].score[1]);
    printf("分数3:%d\n", stdlist[x].score[2]);

    int averagex = 0;
    averagex = (stdlist[x].score[0] + stdlist[x].score[1] + stdlist[x].score[2]);
    averagex /= 3;
    printf("该学生的平均分:%d\n", averagex);
}

11.8)已有a、b两个链表,每个链表中的结点包括学号、成绩。要求把两个链表合并,按学号升序排列

#include<stdio.h>

struct Score
{
    int id;
    int score;
    Score* next;
};

void main()
{
    Score *p;

    //建立链表a
    Score *a = new Score;
    p = a;
    p -> id = 0;
    p -> score = 95;
    p -> next = new Score;
    p = p -> next;
    p -> id = 2;
    p -> score = 85;
    p -> next = new Score;
    p = p -> next;
    p -> id = 4;
    p -> score = 75;
    p -> next = new Score;
    p = p -> next;
    p -> id = 6;
    p -> score = 65;
    p -> next = NULL;

    //打印链表a
    p = a;
    printf("LinkList a:\n");
    while(p)
    {
        printf("id:%d\tscore:%d\n", p -> id, p -> score);
        p = p -> next;
    }
    
    //建立链表b
    Score *b = new Score;
    p = b;
    p -> id = 5;
    p -> score = 90;
    p -> next = new Score;
    p = p -> next;
    p -> id = 3;
    p -> score = 80;
    p -> next = new Score;
    p = p -> next;
    p -> id = 1;
    p -> score = 70;
    p -> next = NULL;

    //打印链表b
    p = b;
    printf("LinkList b:\n");
    while(p)
    {
        printf("id:%d\tscore:%d\n", p -> id, p -> score);
        p = p -> next;
    }

    //建立链表c(a、b合体)
    Score *c;
    c = a;
    p = c;
    while(p -> next)
    {
        p = p -> next;
    }
    p -> next = b;

    //打印链表c
    p = c;
    printf("New LinkList c:\n");
    while(p)
    {
        printf("id:%d\tscore:%d\n", p -> id, p -> score);
        p = p -> next;
    }

    //为链表c排序
    Score *i, *j;
    int temp;
    for(i = c; i; i = i -> next)
    {
        for(j = i -> next; j; j = j -> next)
        {
            if(i -> id > j -> id)
            {
                //交换id
                temp = i -> id;
                i -> id = j -> id;
                j -> id = temp;
                //交换分数
                temp = i -> score;
                i -> score = j -> score;
                j -> score = temp;
            }
        }
    }
    
    //打印排序后的链表c
    p = c;
    printf("Sorted LinkList c:\n");
    while(p)
    {
        printf("id:%d\tscore:%d\n", p -> id, p -> score);
        p = p -> next;
    }
}

11.9)13个人围城一圈,从第一个人开始顺序报数1、2、3。凡报数到3者退出圈子。找出最后留在圈子中的人原来的序号

#include<stdio.h>

struct Person
{
    int num;
    Person* next;
};

void main()
{
    Person *p;
    int i, j;

    //建立13人循环链表链表a
    Person *a = new Person;
    p = a;
    i = 12;
    while(i--)
    {
        p -> num = 0;
        p -> next = new Person;
        p = p -> next;
    }
    p -> num = 0;
    p -> next = a;

    //打印链表a
    i = 12;
    p = a;
    while(i--)
    {
        //三个人报数
        while(p -> num)
        {
            p = p -> next;
        }
        p = p -> next;
        while(p -> num)
        {
            p = p -> next;
        }
        p = p -> next;
        while(p -> num)
        {
            p = p -> next;
        }

        //报到3的人,将num更改为1
        p -> num = 1;
        p = p -> next;

        //输出当前报数情况
        Person *q = a;
        for(j = 0; j < 13; j++)
        {
            printf("%d ", q -> num);
            q = q -> next;
        }
        printf("\n");
    }

    //输出最后一个剩下的人
    int counter = 1;
    p = a;
    while(p -> num)
    {
        p = p -> next;
        counter++;
    }
    printf("最后剩下的是第 %d 个人\n", counter);
}

11.10)有2个链表a和b,设结点中包含学号、姓名。从a链表中删去与b链表中有相同学号的那些结点

#include<stdio.h>
#include<string.h>

struct Student
{
    int id;
    char name[100];
    Student* next;
    Student* last;
};

void main()
{
    Student *p, *q;

    //建立链表a
    Student *a = new Student;
    p = a;
    p -> last = NULL;
    p -> id = 0;
    strcpy(p -> name, "Tsybius");
    p -> next = new Student;
    p -> next -> last = p;
    p = p -> next;
    p -> id = 1;
    strcpy(p -> name, "Quintus");
    p -> next = new Student;
    p -> next -> last = p;
    p = p -> next;
    p -> id = 2;
    strcpy(p -> name, "Galatea");
    p -> next = new Student;
    p -> next -> last = p;
    p = p -> next;
    p -> id = 3;
    strcpy(p -> name, "Aurelia");
    p -> next = NULL;

    //打印链表a
    printf("打印链表a\n");
    for(p = a; p; p = p -> next)
    {
        printf("num:%d\t%s\n", p -> id, p ->name);
    }

    //建立链表b
    Student *b = new Student;
    p = b;
    p -> last = NULL;
    p -> id = 0;
    strcpy(p -> name, "Tsybius");
    p -> next = new Student;
    p -> next -> last = p;
    p = p -> next;
    p -> id = 2;
    strcpy(p -> name, "Aurelia");
    p -> next = NULL;

    //打印链表b
    printf("打印链表b\n");
    for(p = b; p; p = p -> next)
    {
        printf("num:%d\t%s\n", p -> id, p ->name);
    }

    //删去链表a中也存在于链表b的元素
    for(p = a; p; p = p -> next)
    {
        for(q = b; q; q = q -> next)
        {
            if(p -> id == q -> id)
            {
                printf("Delete: %s\n", p -> name);
                if(p -> last == NULL)
                {
                    a = p -> next;
                    if(p -> next != NULL)
                    {
                        p -> next -> last = NULL;
                    }
                }
                else
                {
                    p -> last -> next = p -> next;
                    if(p -> next != NULL)
                    {
                        p -> next -> last = p -> last;
                    }
                }
            }
        }
    }

    //打印清理后的链表a
    printf("打印清理后的链表a\n");
    for(p = a; p; p = p -> next)
    {
        printf("num:%d\t%s\n", p -> id, p ->name);
    }
}

11.11)建立一个链表,每个结点包括:学号、姓名、性别、年龄。输入一个年龄,如果链表中的结点包含的年龄等于此年龄,则将此结点删去

#include<stdio.h>
#include<string.h>

struct Student
{
    int id;
    char name[100];
    int sex; //男:1 女:0
    int age;
    Student* next;
    Student* last;
};

void main()
{
    Student *p;

    Student *a = new Student;
    p = a;
    p -> last = NULL;
    p -> id = 0;
    strcpy(p -> name, "Tsybius");
    p -> sex = 1;
    p -> age = 23;
    p -> next = new Student;
    p -> next -> last = p;

    p = p -> next;
    p -> id = 1;
    strcpy(p -> name, "Galatea");
    p -> sex = 0;
    p -> age = 21;
    p -> next = new Student;
    p -> next -> last = p;

    p = p -> next;
    p -> id = 2;
    strcpy(p -> name, "Aurelia");
    p -> sex = 0;
    p -> age = 22;
    p -> next = NULL;
    
    int input;
    scanf("%d", &input);

    for(p = a; p; p = p -> next)
    {
        if(p -> id == input)
        {
            printf("Delete: %s\n", p -> name);
            if(p -> last == NULL)
            {
                a = p -> next;
                if(p -> next != NULL)
                {
                    p -> next -> last = NULL;
                }
            }
            else
            {
                p -> last -> next = p -> next;
                if(p -> next != NULL)
                {
                    p -> next -> last = p -> last;
                }
            }
        }
    }
}

11.12)将一个链表按逆序排列,即将链头当链尾,链尾当链头

#include<stdio.h>

struct Node
{
    int number;
    Node* next;
};

void main()
{ 
    Node *p, *q, *r;

    //建立链表a
    Node* a = new Node;
    p = a;

    p -> number = 0;
    p -> next = new Node;
    p = p -> next;

    p -> number = 1;
    p -> next = new Node;
    p = p -> next;
    
    p -> number = 2;
    p -> next = new Node;
    p = p -> next;
    
    p -> number = 3;
    p -> next = NULL;

    //打印链表
    for(p = a; p; p = p -> next)
    {
        printf("%d\t", p -> number);
    }
    printf("\n");

    //将链表首位互换逆序排列,指针全部指向反向
    p = a;
    q = p -> next;
    p -> next = NULL;
    while(q)
    {
        r = q -> next;
        q -> next = p;
        p = q;
        q = r;
    }
    a = p;
    
    //打印链表
    for(p = a; p; p = p -> next)
    {
        printf("%d\t", p -> number);
    }
    printf("\n");
}

END


转载于:https://my.oschina.net/Tsybius2014/blog/310302

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值