关于结构体的初步使用的学习记录

第六次实验

Lab 6-1 结构体类型memory layout练习

Task: 请用 sizeof() 输出以下结构体所占内存空间字节数的大小,并简述原因,参见结构体数据对齐的原理及示例,注意32位机器和64位机器上数据类型字节数的差异。

序号(1)(2)(3)
结构体

struct test1
{
char a;
float c;
double d;
int e;
char f;
};

struct test2
{
char c;
int *p1;
int t;
double *p2;
};

struct s1
{
char c1;
int i;
};
struct test3
{
char c2;
struct s1 s;
char c3
};
sizeof()
run on x86
24
16
16
原因 由于结构体内每个成员的存储地址相对于结构体首地址的偏移量是该成员所占空间字节数的整数倍,故元素a不能只占据1个字节,而是应该占据4个字节。以此类推,占据字节数为4+4+8+4+4=24。
以此类推,占据字节数为4+4+8+4+4=24。
与前一结构体同理,c占据4个字节,占据字节数为4+4+4+4=16。
内层结构体中的c1的偏移量应当是被展开的结构体中空间占用字节数最大的成员的整数倍,也就是i的大小的1倍,即4个字节。那么相应的c2也就占据4字节。剩下的与之前同理,占据字节数为4+4+4+4=16。
Lab 6-2 有关结构体的排序打印输出

Task: 尝试用结构体,结构体数组,结构体指针将学生的三门成绩分数和对应姓名学号,分别从高到低进行排序并按序输出。
任务代码:

#include <stdio.h>
#include <stdlib.h>

typedef struct Subject
{
    int mathScore;
    int physicsScore;
    int programScore;
} Sub;
typedef struct Student
{
    char *id;
    char *name;
    Sub sub;
} Stu;
void Swap(int *a, int *b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
}
void bubbleSort(Stu *stu, int sz)
{
    int i = 0;
    int j = 0;
    for (i = 0; i < sz - 1; i++)
    {
        for (j = 0; j < sz - 1 - i; j++)
        {
            if (stu[j].sub.mathScore < stu[j + 1].sub.mathScore)
            {
                Swap(&stu[j].id, &stu[j + 1].id);
                Swap(&stu[j].name, &stu[j + 1].name);
                Swap(&stu[j].sub.mathScore, &stu[j + 1].sub.mathScore);
                Swap(&stu[j].sub.physicsScore, &stu[j + 1].sub.physicsScore);
                Swap(&stu[j].sub.programScore, &stu[j + 1].sub.programScore);
            }
        }
    }
}
void printMathScore(struct Student *stu, const int len)
{
    int i = 0;
    bubbleSort(stu, len);
    for (i = 0; i < len; i++)
    {
        printf("Name:%s, Id:%s, Score:%d.\n", stu[i].name, stu[i].id, stu[i].sub.mathScore);
    }
}
int main()
{
    Sub sub[10] = {
        {99, 100, 60},
        {98, 88, 90},
        {87, 100, 100},
        {89, 88, 87},
        {78, 90, 93},
        {100, 100, 100},
        {80, 94, 99},
        {100, 88, 78},
        {78, 77, 76},
        {90, 90, 97}};
    Stu stu[10] = {
        {"20221101", "A", sub[0]},
        {"20221102", "B", sub[1]},
        {"20221103", "C", sub[2]},
        {"20221104", "D", sub[3]},
        {"20221105", "E", sub[4]},
        {"20221106", "F", sub[5]},
        {"20221107", "G", sub[6]},
        {"20221108", "H", sub[7]},
        {"20221109", "I", sub[8]},
        {"20221110", "J", sub[9]}};
    printMathScore(stu, 10);

    system("pause");
    return 0;
}

输出结果:

Name:F, Id:20221106, Score:100.
Name:H, Id:20221108, Score:100.
Name:A, Id:20221101, Score:99.
Name:B, Id:20221102, Score:98.
Name:J, Id:20221110, Score:90.
Name:D, Id:20221104, Score:89.
Name:C, Id:20221103, Score:87.
Name:G, Id:20221107, Score:80.
Name:E, Id:20221105, Score:78.
Name:I, Id:20221109, Score:78.
Lab 6-3

Task 1:实现函数void printEvent(struct Event *event, int len),该函数的目的是将活动按照开始时间升序的形式打印,如果开始时间相同,则结束时间在前的先打印。
任务代码:

#include <stdio.h>
#include <stdlib.h>
typedef struct Event
{
    int begin_hour;
    int end_hour;
} Event;
void Swap(int *a, int *b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
}
void eventSort(Event *event, int len)
{
    int i = 0;
    int j = 0;
    for (i = 0; i < len - 1; i++)
    {
        for (j = 0; j < len - 1 - i; j++)
        {
            if (event[j].begin_hour > event[j + 1].begin_hour)
            {
                Swap(&event[j].begin_hour, &event[j + 1].begin_hour);
                Swap(&event[j].end_hour, &event[j + 1].end_hour);
            }
            else if(event[j].begin_hour == event[j + 1].begin_hour && event[j].end_hour > event[j + 1].end_hour)
            {
                Swap(&event[j].begin_hour, &event[j + 1].begin_hour);
                Swap(&event[j].end_hour, &event[j + 1].end_hour);
            }
        }
    }
}
void printEvent(Event *event, int len)
{
    eventSort(event, len);
    int i = 0;
    printf("Event | Begin | End\n");
    for(i = 0; i < len;i++)
    {
        printf("%5d | %5d | %3d\n", i+1, event[i].begin_hour, event[i].end_hour);
    }
}

// 第一组样例
#define n 12
int main()
{
    // struct Event event[n] = {0};
    Event event[n] = {{1, 4}, {2, 3}, {3, 4}, {1, 3}, {10, 20}, {6, 9}, {1, 7}, {4, 10}, {4, 20}, {5, 9}, {12, 23}, {17, 20}};
    // for (i = 0; i < n; i++)
    // {
    //     scanf("[%d, %d]", &event[i].begin_hour, &event[i].end_hour);
    // }

    printEvent(event, n);

    system("pause");
    return 0;
}

// 第二组样例
#define n 10
int main()
{
    // struct Event event[n] = {0};
    Event event[n] = {{1, 4}, {20, 22}, {7, 9}, {4, 6}, {6, 7}, {14, 16}, {13, 14}, {10, 12}, {17, 19}, {22, 24}};
    // {
    //     scanf("[%d, %d]", &event[i].begin_hour, &event[i].end_hour);
    // }

    printEvent(event, n);

    system("pause");
    return 0;
}

输出结果:
(1)

Event | Begin | End
    1 |     1 |   3
    2 |     1 |   4
    3 |     1 |   7
    4 |     2 |   3
    5 |     3 |   4
    6 |     4 |  10
    7 |     4 |  20
    8 |     5 |   9
    9 |     6 |   9
   10 |    10 |  20
   11 |    12 |  23
   12 |    17 |  20

(2)

Event | Begin | End
    1 |     1 |   4
    2 |     4 |   6
    3 |     6 |   7
    4 |     7 |   9
    5 |    10 |  12
    6 |    13 |  14
    7 |    14 |  16
    8 |    17 |  19
    9 |    20 |  22
   10 |    22 |  24

Task 2: 输出 “是” 或 “否” 来表示这些活动是否能够被有序安排,如果任意两个活动有重合部分,则输出“否”,否则输出“是”。
任务代码在Task 1的代码的基础上进行一定修改,保留void eventSort(Event *event, int len)函数,增加int judgeConflict(Event *event, int len)函数。
代码如下:

#include <stdio.h>
#include <stdlib.h>
typedef struct Event
{
    int begin_hour;
    int end_hour;
} Event;
void Swap(int *a, int *b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
}
void eventSort(Event *event, int len)
{
    int i = 0;
    int j = 0;
    for (i = 0; i < len - 1; i++)
    {
        for (j = 0; j < len - 1 - i; j++)
        {
            if (event[j].begin_hour > event[j + 1].begin_hour)
            {
                Swap(&event[j].begin_hour, &event[j + 1].begin_hour);
                Swap(&event[j].end_hour, &event[j + 1].end_hour);
            }
            else if (event[j].begin_hour == event[j + 1].begin_hour && event[j].end_hour > event[j + 1].end_hour)
            {
                Swap(&event[j].begin_hour, &event[j + 1].begin_hour);
                Swap(&event[j].end_hour, &event[j + 1].end_hour);
            }
        }
    }
}
int judgeConflict(Event *event, int len)
{
    eventSort(event, len);
    int i = 0;
    int j = 0;
    for (i = 0; i < len - 1; i++)
    {
        for (j = i + 1; j < len; j++)
        {
            if (event[j].begin_hour < event[i].end_hour)
                return 1;
        }
    }
    return 0;
}

//第一组样例
#define n 12
int main()
{
    // struct Event event[n] = {0};
    Event event[n] = {{1, 4}, {2, 3}, {3, 4}, {1, 3}, {10, 20}, {6, 9}, {1, 7}, {4, 10}, {4, 20}, {5, 9}, {12, 23}, {17, 20}};
    // for (i = 0; i < n; i++)
    // {
    //     scanf("[%d, %d]", &event[i].begin_hour, &event[i].end_hour);
    // }

    int ret = judgeConflict(event, n);
    switch (ret)
    {
    case 0:
        printf("否\n");
        break;
    case 1:
        printf("是\n");
        break;
    }
    
    system("pause");
    return 0;
}

//第二组样例
#define n 10
int main()
{
    // struct Event event[n] = {0};
    Event event[n] = {{1, 4}, {20, 22}, {7, 9}, {4, 6}, {6, 7}, {14, 16}, {13, 14}, {10, 12}, {17, 19}, {22, 24}};
    // for (i = 0; i < n; i++)
    // {
    //     scanf("[%d, %d]", &event[i].begin_hour, &event[i].end_hour);
    // }

    int ret = judgeConflict(event, n);
    switch (ret)
    {
    case 0:
        printf("否\n");
        break;
    case 1:
        printf("是\n");
        break;
    }

    system("pause");
    return 0;
}

输出结果:
(1)

(2)

如有不足之处请批评指正,谢谢!

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值