c语言绿皮书第三版第十一章习题

1.习题11.1

c 复制代码
#include<stdio.h>

int main() {
    struct date_ {
        int year;
        int month;
        int day;
    };
    int leap = 0;
    int sumday = 0;
    struct date_ date;
    printf("Please input year: ");
    scanf("%d", &date.year);
    printf("Please input month: ");
    scanf("%d", &date.month);
    printf("Please input day: ");
    scanf("%d", &date.day);

    if (date.year % 400 == 0 || date.year % 4 == 0 && date.year % 100 != 0) {
        leap = 1;
    }
    switch (date.month) {
        case 1: sumday = date.day;
            break;
        case 2: sumday = 31 + date.day;
            break;
        case 3: sumday = 59 + date.day;
            break;
        case 4: sumday = 90 + date.day;
            break;
        case 5: sumday = 120 + date.day;
            break;
        case 6: sumday = 151 + date.day;
            break;
        case 7: sumday = 181 + date.day;
            break;
        case 8: sumday = 212 + date.day;
            break;
        case 9: sumday = 243 + date.day;
            break;
        case 10: sumday = 273 + date.day;
            break;
        case 11: sumday = 304 + date.day;
            break;
        case 12: sumday = 334 + date.day;
            break;
    }
    if (leap && date.month > 2) {
        sumday++;
    }
    printf("%d-%d-%d shi di %d tian\n", date.year, date.month, date.day, sumday);

    return 0;
}

2.习题11.2

c 复制代码
#include<stdio.h>

struct date {
    int year;
    int month;
    int day;
};

int main() {
    struct date date_;
    int sum_day;
    int calcday(struct date *);

    printf("Please input year: ");
    scanf("%d", &date_.year);
    printf("Please input month: ");
    scanf("%d", &date_.month);
    printf("Please inout day: ");
    scanf("%d", &date_.day);

    sum_day = calcday(&date_);
    printf("sum_day=%d\n", sum_day);

    return 0;
}

int calcday(struct date *date_p) {
    int leap = 0;
    int sumday;

    if (date_p->year % 400 == 0 || date_p->year % 4 == 0 && date_p->year % 100 != 0) {
        leap = 1;
    }
    switch (date_p->month) {
        case 1: sumday = date_p->day;
            break;
        case 2: sumday = 31 + date_p->day;
            break;
        case 3: sumday = 59 + date_p->day;
            break;
        case 4: sumday = 90 + date_p->day;
            break;
        case 5: sumday = 120 + date_p->day;
            break;
        case 6: sumday = 151 + date_p->day;
            break;
        case 7: sumday = 181 + date_p->day;
            break;
        case 8: sumday = 212 + date_p->day;
            break;
        case 9: sumday = 243 + date_p->day;
            break;
        case 10: sumday = 273 + date_p->day;
            break;
        case 11: sumday = 304 + date_p->day;
            break;
        case 12: sumday = 334 + date_p->day;
            break;
    }
    if (leap && date_p->month > 2) {
        sumday++;
    }

    return sumday;
}

3.习题11.3

c 复制代码
#include<stdio.h>
#define N 5

struct student {
    int num;
    char name[20];
    int score[3];
};

int main() {
    struct student stu[5];
    void print(struct student *);
    int i, j;

    for (i = 0; i < N; i++) {
        printf("Please input informantion of %dth:\n", i);
        printf("num: ");
        scanf("%d", &stu[i].num);
        printf("name: ");
        scanf("%s", stu[i].name);

        for (j = 0; j < 3; j++) {
            printf("score[%d]: ", j);
            scanf("%d", &stu[i].score[j]);
        }
    }
    printf("\n\n");
    print(stu);

    return 0;
}

void print(struct student *stu_p) {
    int i, j;

    for (i = 0; i < N; i++, stu_p++) {
        printf("num: %d", stu_p->num);
        printf("\t");
        printf("name: %s\t", stu_p->name);

        for (j = 0; j < 3; j++) {
            printf("score[%d]: %d\t", j, stu_p->score[j]);
        }
        putchar('\n');
    }
}

4.习题11.4

c 复制代码
#include<stdio.h>
#define N 5

struct student {
    int num;
    char name[10];
    int score[3];
};

int main() {
    struct student stu[10];
    void input(struct student stu[]);
    void print(struct student *);

    input(stu);
    printf("\n\n");
    print(stu);

    return 0;
}

void input(struct student stu[]) {
    int i, j;

    for (i = 0; i < N; i++) {
        printf("Please input informantion of %dth:\n", i);
        printf("num: ");
        scanf("%d", &stu[i].num);
        printf("name: ");
        scanf("%s", stu[i].name);

        for (j = 0; j < 3; j++) {
            printf("score[%d]: ", j);
            scanf("%d", &stu[i].score[j]);
        }
    }
}

void print(struct student *stu_p) {
    int i, j;

    for (i = 0; i < N; i++, stu_p++) {
        printf("num: %d", stu_p->num);
        printf("\t");
        printf("name: %s\t", stu_p->name);

        for (j = 0; j < 3; j++) {
            printf("score[%d]: %d\t", j, stu_p->score[j]);
        }
        putchar('\n');
    }
}

5.习题11.5

c 复制代码
#include<stdio.h>
#define N 10

struct student {
    int num;
    char name[20]; // 增大名字长度
    int score[3];
};

// 函数声明放在全局
void input(struct student *);

void stu_f(struct student *);

int main() {
    struct student stu[N];
    input(stu);
    return 0;
}

void input(struct student *p) {
    int i, j;

    for (i = 0; i < N; i++) {
        printf("请输入第%d个学生信息:\n", i + 1);
        printf("学号: ");
        scanf("%d", &(p + i)->num);
        printf("姓名: ");
        scanf("%s", (p + i)->name);

        for (j = 0; j < 3; j++) {
            printf("课程%d成绩: ", j + 1);
            scanf("%d", &(p + i)->score[j]);
        }
        printf("\n");
    }
    stu_f(p);
}

void stu_f(struct student *q) {
    double stu_ave[N] = {0};
    double max = 0;
    int maxl = 0; // 初始化
    int i, j;

    // 1. 计算每门课程的总平均分
    double total_score[3] = {0};
    double course_avg[3] = {0};
    for (i = 0; i < N; i++) {
        for (j = 0; j < 3; j++) {
            total_score[j] += (q + i)->score[j];
        }
    }
    printf("===== 3门课程总平均成绩 =====\n");
    for (j = 0; j < 3; j++) {
        course_avg[j] = total_score[j] / N;
        printf("课程%d: %.2f\n", j + 1, course_avg[j]);
    }
    printf("\n");

    // 2. 计算每个学生的平均分并找出最高分
    printf("===== 每个学生的平均分 =====\n");
    for (i = 0; i < N; i++) {
        stu_ave[i] = 0;
        for (j = 0; j < 3; j++) {
            // 修正整数除法问题
            stu_ave[i] += (double) (q + i)->score[j] / 3;
        }
        printf("学生%d的平均分: %.2f\n", i + 1, stu_ave[i]);

        if (stu_ave[i] > max) {
            max = stu_ave[i];
            maxl = i;
        }
    }

    // 3. 输出最高分学生数据
    printf("\n===== 平均分最高的学生 =====\n");
    printf("学号: %d\n", (q + maxl)->num);
    printf("姓名: %s\n", (q + maxl)->name);
    for (i = 0; i < 3; i++) {
        printf("课程%d成绩: %d\n", i + 1, (q + maxl)->score[i]);
    }
    printf("平均分: %.2f\n", stu_ave[maxl]);
}

6.习题11.6


c 复制代码
#include<stdio.h>
#include<stdlib.h>

// 题目要求的函数名是new,这里用new_避免和C++关键字冲突
char *new_(int n);

int main()
{
    int n;
    char *p; 

    printf("请输入要分配的字符数:");
    scanf("%d", &n);
    
    p = new_(n);
    if (p == NULL) {
        printf("内存分配失败!\n");
        return 1;
    }

    printf("为 %d 个字符分配的内存地址:%p\n", n, (void*)p);

    // 测试写入字符(可选)
    for(int i = 0; i < n-1; i++) {
        p[i] = 'a' + i;
    }
    p[n-1] = '\0'; // 字符串结束符
    printf("测试写入的字符串:%s\n", p);

    free(p); // 释放内存
    return 0;
}

// 为n个字符开辟连续的存储空间,返回char*类型指针
char *new_(int n)
{
    // 分配n个字节的内存,并初始化为0
    char *t = (char *)calloc(n, sizeof(char));
    return t;
}

7.习题11.7

c 复制代码
#include <stdio.h>
#include <stdlib.h> // 必须包含calloc/free的头文件

// 题目11.6:分配n个字符的空间,返回指针
char *new_(int n) {
    // 分配n个字节的连续空间(每个char占1字节)
    char *p = (char *)calloc(n, sizeof(char));
    if (p == NULL) { // 分配失败的判断,题目没提但建议加上
        printf("内存分配失败!\n");
        exit(1);
    }
    return p; // 返回指向分配空间的指针,满足题目要求
}

// 题目11.7:释放p指向的内存段
void free_(char *p) {
    if (p != NULL) { // 安全判断,防止释放空指针
        free(p);
        p = NULL; // 释放后置空,避免野指针
    }
}

int main() {
    int n;
    char *str;

    printf("请输入要分配的字符数:");
    scanf("%d", &n);

    // 调用new_分配内存
    str = new_(n);
    printf("分配的内存地址:%p\n", str);

    // 可以在这里使用str指向的空间
    printf("请输入字符串:");
    scanf("%s", str);
    printf("你输入的字符串:%s\n", str);

    // 调用free_释放内存,满足题目要求
    free_(str);
    printf("内存已释放\n");

    return 0;
}

8.习题11.8

c 复制代码
#include<stdio.h>
#define N 3

typedef struct student {
    int num;
    int score;
    struct student *next;
} stu;

void main() {
    stu a1, a2, a3;
    stu b1, b2;
    stu *h1, *h2, *p1, *p2;
    int i = 0;
    void bh(stu *p, stu *q, int);

    h1 = &a1;

    a1.num = 3;
    a1.score = 89;
    a1.next = &a2;

    a2.num = 5;
    a2.score = 78;
    a2.next = &a3;

    a3.num = 1;
    a3.score = 90;
    a3.next = NULL;

    h2 = &b1;

    b1.num = 2;
    b1.score = 59;
    b1.next = &b2;

    b2.num = 4;
    b2.score = 80;
    b2.next = NULL;

    printf("a:\n");
    p1 = h1;
    do {
        printf("num: %d\tscore: %d\n", p1->num, p1->score);
        p1 = p1->next;
        i++;
    } while (p1 != NULL);

    printf("b:\n");
    p2 = h2;
    do {
        printf("num: %d\tscore: %d\n", p2->num, p2->score);
        p2 = p2->next;
        i++;
    } while (p2 != NULL);
    bh(h1, h2, i);
}

void bh(stu *p, stu *q, int n) {
    stu *t, *r, temp;
    int i, j;
    t = p;
    do {
        r = t;
        t = t->next;
    } while (t != NULL);
    r->next = q;

    for (i = 0; i < n - 1; i++) {
        t = p;
        j = 0;
        do {
            if (t->num > (t->next)->num) {
                ;
                temp.num = t->num;
                t->num = (t->next)->num;
                (t->next)->num = temp.num;

                temp.score = t->score;
                t->score = (t->next)->score;
                (t->next)->score = temp.score;
            }
            j++;
            t = t->next;
        } while (j < n - 1 - i);
    }

    t = p;
    printf("\nlink after:\n");
    do {
        printf("num: %d\tscore: %d\n", t->num, t->score);
        t = t->next;
    } while (t != NULL);
}

9.习题11.10

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#define LEN sizeof(stu)

typedef struct student {
    int num;
    char name[10];
    struct student *next;
} stu;

stu* creat_();
stu* del(stu *ha, stu *hb);
void print(stu *h_a);

int main() {
    stu *head_a, *head_b;

    printf("输入链表A(格式:学号,姓名,输入-1结束):\n");
    head_a = creat_();
    printf("输入链表B(格式:学号,姓名,输入-1结束):\n");
    head_b = creat_();

    printf("\n删除相同学号后的链表A:\n");
    head_a = del(head_a, head_b);
    print(head_a);

    return 0;
}

// 创建链表,返回头指针
stu* creat_() {
    stu *head = NULL;
    stu *p1, *p2;
    int n = 0;

    p1 = (stu*)malloc(LEN);
    scanf("%d,%s", &p1->num, p1->name);

    while(p1->num != -1) {
        n++;
        if(n == 1) {
            head = p1;
        } else {
            p2->next = p1;
        }
        p2 = p1;
        p1 = (stu*)malloc(LEN);
        scanf("%d,%s", &p1->num, p1->name);
    }
    p2->next = NULL;
    free(p1); // 释放最后那个输入-1的节点
    return head;
}

// 从ha中删除hb中存在的学号节点
stu* del(stu *ha, stu *hb) {
    stu *p_a, *p, *q;

    q = hb;
    while(q != NULL) {
        p = ha;
        p_a = NULL; // p_a是p的前驱节点
        while(p != NULL) {
            if(p->num == q->num) {
                if(p == ha) {
                    // 删除头节点
                    ha = p->next;
                    free(p);
                    p = ha;
                } else {
                    // 删除中间/尾节点
                    p_a->next = p->next;
                    free(p);
                    p = p_a->next;
                }
            } else {
                p_a = p;
                p = p->next;
            }
        }
        q = q->next;
    }
    return ha;
}

// 打印链表
void print(stu *h_a) {
    stu *p = h_a;
    if(p == NULL) {
        printf("链表为空\n");
        return;
    }
    while(p != NULL) {
        printf("num: %d\tname: %s\n", p->num, p->name);
        p = p->next;
    }
}

10.习题11.11

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#define LEN sizeof(stu)

typedef struct student {
    int num;
    char name[10];
    char sex;
    int age;
    struct student *next;
} stu;

stu* creat_(void);
stu* del(stu *h, int age);
void print(stu *h);

int main() {
    stu *head;
    int ag;

    printf("请输入学生信息(学号输入-1结束):\n");
    head = creat_();
    printf("请输入要删除的年龄:");
    scanf("%d", &ag);
    head = del(head, ag);
    print(head);

    return 0;
}

// 创建链表,返回头指针
stu* creat_(void) {
    stu *h = NULL, *p1, *p2;
    int n = 0;

    p1 = (stu*)malloc(LEN);
    printf("num: ");
    scanf("%d", &p1->num);
    if(p1->num == -1) {
        free(p1);
        return NULL;
    }
    printf("name: ");
    scanf("%s", p1->name);
    getchar(); // 吸收换行符
    printf("sex: ");
    scanf("%c", &p1->sex);
    printf("age: ");
    scanf("%d", &p1->age);

    while(1) {
        n++;
        if(n == 1) {
            h = p1;
        } else {
            p2->next = p1;
        }
        p2 = p1;
        p1 = (stu*)malloc(LEN);
        printf("num: ");
        scanf("%d", &p1->num);
        if(p1->num == -1) {
            free(p1);
            break;
        }
        printf("name: ");
        scanf("%s", p1->name);
        getchar();
        printf("sex: ");
        scanf("%c", &p1->sex);
        printf("age: ");
        scanf("%d", &p1->age);
    }
    p2->next = NULL;
    return h;
}

// 删除指定年龄的节点
stu* del(stu *h, int age) {
    stu *p = h, *q = NULL;
    while(p != NULL) {
        if(p->age == age) {
            if(p == h) {
                // 删除头节点
                h = p->next;
                free(p);
                p = h;
            } else {
                // 删除中间/尾节点
                q->next = p->next;
                free(p);
                p = q->next;
            }
        } else {
            q = p;
            p = p->next;
        }
    }
    return h;
}

// 打印链表
void print(stu *h) {
    stu *t = h;
    if(t == NULL) {
        printf("链表为空\n");
        return;
    }
    while(t != NULL) {
        printf("num: %d  name: %s  sex: %c  age: %d\n", 
               t->num, t->name, t->sex, t->age);
        t = t->next;
    }
}

12.习题11.12

c 复制代码
// 第一个版本
#include<stdio.h>
#include <stdlib.h>
#define LEN sizeof(p)
#define NULL 0
int n = 0;

typedef struct st {
    int num;
    char name[10];
    struct st *next;
} p;

void main() {
    p *head;
    p *cr(void);
    void print(p *);
    p *nx(p *);
    head = cr();
    printf("lian biao:\n\n");
    print(head);
    head = nx(head);
    printf("ni xu lian biao:\n");
    print(head);
    printf("Ok!!!\n");
}

p *cr(void) {
    p *h, *p1, *p2;
    p1 = p2 = (p *) malloc(LEN);
    scanf("%d,%s", &p1->num, p1->name);
    h = NULL;
    while (p1->num != -1) {
        n++;
        if (n == 1) {
            h = p1;
        } else {
            p2->next = p1;
        }
        p2 = p1;
        p1 = (p *) malloc(LEN);
        scanf("%d,%s", &p1->num, p1->name);
    }
    p2->next = NULL;
    return h;
}

void print(p *head) {
    p *p_;
    p_ = head;
    if (head != NULL) {
        while (p_ != NULL) {
            printf("%d\t%s\n", p_->num, p_->name);
            p_ = p_->next;
        }
    } else {
        printf("kong lian biao!!!\n");
    }
}

p *nx(p *head) {
    p *a, *b, *t, *c;
    int j = 0;
    a = head;
    while (j < n - 1) {
        t = a->next;
        j++;
        b = a;
        if (j == 1) {
            b->next = NULL;
        } else {
            b->next = c;
        }
        c = a;
        a = t;
        head = a;
    }
    head->next = c;
    return head;
}
c 复制代码
// 第二个版本
#include<stdio.h>
#include<malloc.h>
#define LEN sizeof(sv)
#define NULL 0
int n=0;

typedef struct l
{
	struct l *start;
	int num;
	char name[10];
	struct l *over;
}sv;
void main()
{
	sv *head[2];  
	void *cr(sv *head[]);
	void print(sv *,int);
	cr(head);
	printf("shun xu:\n");
	print(head[0],0);//0代表顺序
	printf("\n");
	printf("dao xu:\n");   
	print(head[1],1);   //1代表逆序
}

void *cr(sv *head[])
{
	sv *h[2],*p1,*p2;
	p1=p2=(sv *)malloc(LEN);
	n=0;
	h[0]=h[1]=NULL;
	scanf("%d,%s",&p1->num,p1->name);
	while(p1->num!=-1)
	{
		n++;
		if(n==1)
		{
			h[0]=p1;
			p1->start=NULL;
		}
		else
		{
			p2->over=p1;
			p1->start=p2;
		}
		p2=p1;
		p1=(sv *)malloc(LEN);
		scanf("%d,%s",&p1->num,p1->name);
	}
	p2->over=NULL;
	h[1]=p2;

	if(p1->num!=-1)
	{
		head[0]=h[0];
		head[1]=h[1];
	}
	else
	{
		head[0]=NULL;
		head[1]=NULL;
	}
}

void print(sv *h,int x)
{
	sv *p;
	p=h;
	if(h==NULL)
	{
		printf("kong lian biao\n");
	}
	else
	{
		while(p!=NULL)
		{
			printf("%d\t%s\n",p->num,p->name);
			if(x==0)
			{
				p=p->over;
			}
			else
			{
				p=p->start;
			}
		}
	}
}
相关推荐
段ヤシ.1 小时前
回顾Java知识点,面试题汇总Day3(持续更新)
java·开发语言·windows
计算机安禾1 小时前
【c++面向对象编程】第3篇:类与对象(二):构造函数与析构函数
开发语言·c++·算法
小年糕是糕手1 小时前
【C++】vector 不踩坑指南:用法、底层实现与迭代器失效解析
c++·算法
不会写DN1 小时前
PyScript-GitHubRepo:构建高性能GitHub仓库批量下载工具的技术实践
开发语言·前端·python
SilentSamsara2 小时前
生成器完全指南:`yield` 与惰性求值的工程价值
linux·开发语言·python·算法·机器学习·青少年编程
玛卡巴卡ldf2 小时前
【LeetCode 手撕算法】(二分查找)搜索插入位置、搜索二维矩阵、查找数组相同的所有位置、搜索旋转排序数组、旋转升序数组的最小值
数据结构·算法·leetcode
谷雨不太卷9 小时前
进程的状态码
java·前端·算法
jieyucx9 小时前
Go语言深度解剖:Map扩容机制全解析(增量扩容+等量扩容+渐进式迁移)
开发语言·后端·golang·map·扩容策略
凉茶钱10 小时前
【c语言】动态内存管理:malloc,calloc,realloc,柔性数组
c语言·c++·vscode·柔性数组