第六次实验
Lab 6-1 结构体类型memory layout练习
Task: 请用 sizeof()
输出以下结构体所占内存空间字节数的大小,并简述原因,参见结构体数据对齐的原理及示例,注意32位机器和64位机器上数据类型字节数的差异。
序号 | (1) | (2) | (3) |
---|---|---|---|
结构体 | | | |
run on x86 | | | |
原因 | 由于结构体内每个成员的存储地址相对于结构体首地址的偏移量是该成员所占空间字节数的整数倍,故元素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)
否
如有不足之处请批评指正,谢谢!