目录
第九章(结构体和枚举)第十章(指针的高级运用)链表思维导图
答案:
作业1:结构体相关
(a) 下面结构体类型的变量的内存布局是怎样的?请使用VS的debug模式展示内存布局并截图
typedef struct stundent_s { int number; char name[25]; char gender; int chinese; int math; int english; } Student; Student s;
(b) 如何通过结构体获取成员,如何通过指向结构体的指针获取成员?
(c)(学生信息处理)有这样一种学生结构体类型,其数据成员有包括学号,姓名和3门课程的成绩。实现下列功能:
-
从键盘输入5个学生的信息,将这些同学的信息采用结构体数组的方式存储起来。
-
输出每门课程最高分的学生信息。
-
输出每门课程的平均分。
-
按照总分从高到低对学生进行排序,并输出排序后的学生信息。(排序话自己写个选择或冒泡排序即可)
解答:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
typedef struct stundent_s {
int number;
char name[25];
char gender;
int chinese;
int math;
int english;
} Student;
int main(void) {
Student s1 = { 1,"liuyifei",'f',30,30,30 };
Student* ps1 = &s1;
printf("%3d%10s%3c%5d%5d%5d\n",
s1.number,
s1.name,
s1.gender,
s1.chinese,
s1.math,
s1.english);
printf("%3d%10s%3c%5d%5d%5d\n",
ps1->number,
ps1->name,
ps1->gender,
ps1->chinese,
ps1->math,
ps1->english);
return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
typedef struct {
int s_id;
char name[25];
int ch_grade;
int en_grade;
int ma_grade;
}Stu;
Stu* up_to_low(Stu* student[],int len) {
int sum; int sum2; int temp; Stu* stemp;
for (int i = 0; i < len; i++) {
sum = student[i]->ch_grade + student[i]->ma_grade + student[i]->en_grade;
temp = i;
for (int j = i+1; j < len; j++) {
sum2= student[j]->ch_grade + student[j]->ma_grade + student[j]->en_grade;
if (sum < sum2) { //注意是找到最大的值不只是比第一个大的
temp = j;
sum = sum2;//更新最大总分值,除非把SUM放在内循环
}
}
//交换两个元素
stemp = student[i];
student[i] = student[temp];
student[temp] = stemp;
}
}
Stu* print_stu(Stu* student[],int len) {
printf("\n");
for (int i = 0; i < len; i++) {
printf("%5d%10s%5d%5d%5d\n",
student[i]->s_id,
student[i]->name,
student[i]->ch_grade,
student[i]->en_grade,
student[i]->ma_grade);
}
printf("\n");
}
void average_max(Stu* studet[], int len, double*ma_ar,double *en_ar, double* ch_ar,
int *ma_max,int* en_max,int*ch_max)
{
for (int i = 0; i < len; i++) {
*ma_ar += studet[i]->ma_grade;
*en_ar += studet[i]->en_grade;
*ch_ar += studet[i]->ch_grade;
if (*ma_max < studet[i]->ma_grade) { *ma_max = studet[i]->ma_grade; }
if (*en_max < studet[i]->en_grade) { *en_max = studet[i]->en_grade; }
if (*ch_max < studet[i]->ch_grade) { *ch_max = studet[i]->ch_grade; }
}
*ma_ar /= 5.0;
*en_ar /= 5.0;
*ch_ar /= 5.0;
}
int main(void) {
Stu s[5]; Stu* sp[5];
printf(" id name chineses_grade english_grade math_grade\n");
for (int i = 0; i < 5; i++) {
scanf("%d%s%d%d%d",
&s[i].s_id,
s[i].name,
& s[i].ch_grade,
&s[i].en_grade,
&s[i].ma_grade);
sp[i] = s+i;
}
up_to_low(sp, 5);
print_stu(sp, 5);
double ma_ar=0.0, en_ar= 0.0, ch_ar= 0.0;
int ma_max=0, en_max=0, ch_max=0;
//神他妈调用栈堆冲突,传了个S
average_max(sp, 5, &ma_ar, &en_ar, &ch_ar, &ma_max, &en_max, &ch_max);
printf("chineses_average_grade is %3.2f ,max is %3d\n"
"english_grade_average_grade is %3.2f ,max is %3d\n"
"math_grade_average_grade is %3.2f ,max is %3d\n",ch_ar,ch_max,en_ar,en_max,ma_ar,ma_max);
return 0;
}
答案:
函数分解------自己写的
void sort_students(Student* arr[], int n) {
// 选择排序
for (int i = 0; i < n - 1; i++) {
int minIdx = i;
for (int j = i + 1; j < n; j++) {
if (cmp(arr[j], arr[minIdx]) < 0) {
minIdx = j;
}
}
swap(arr, i, minIdx);
}
}(c) #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> // 不要给指针类型起别名 typedef struct student_s { int number; char name[25]; char gender; int chinese; int math; int english; } Student; void print_stu_info(const struct student_s* p) { printf("%d %s %c %d %d %d\n", p->number, p->name, p->gender, p->chinese, p->math, p->english); } int total_score(Student* p) { return p->chinese + p->english + p->math; } int cmp(Student* p1, Student* p2) { // p1 < p2 返回负值 // p1 = p2 返回0 // p1 > p2 返回正值 int total1 = total_score(p1); int total2 = total_score(p2); return total2 - total1; } void swap(Student* arr[], int i, int j) { Student* tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } void sort_students(Student* arr[], int n) { // 选择排序 for (int i = 0; i < n - 1; i++) { int minIdx = i; for (int j = i + 1; j < n; j++) { if (cmp(arr[j], arr[minIdx]) < 0) { minIdx = j; } } swap(arr, i, minIdx); } } void print_score(Student students[], int n) { // p[i] = *(p + i) int idx1 = 0; int idx2 = 0; int idx3 = 0; for (int i = 1; i < n; i++) { if (students[i].chinese > students[idx1].chinese) { idx1 = i; } if (students[i].math > students[idx2].math) { idx2 = i; } if (students[i].english > students[idx3].english) { idx3 = i; } } print_stu_info(&students[idx1]); print_stu_info(&students[idx2]); print_stu_info(&students[idx3]); } void print_average_score(Student students[], int n) { double avg1 = 0; double avg2 = 0; double avg3 = 0; for (int i = 0; i < n; i++) { avg1 += students[i].chinese; avg2 += students[i].math; avg3 += students[i].english; } printf("Average score of chinese: %.2lf\n", avg1 / n); printf("Average score of math: %.2lf\n", avg2 / n); printf("Average score of english: %.2lf\n", avg3 / n); } int main(void) { Student students[5]; for (int i = 0; i < 5; i++) { scanf("%d%s %c%d%d%d", &students[i].number, students[i].name, &students[i].gender, &students[i].chinese, &students[i].math, &students[i].english); } // 打印单科最高分学生的信息 print_score(students, 5); // 输出没门课程的平均分 print_average_score(students, 5); // 按照总分从高到低对学生进行排序,并输出排序后的学生信息。 Student* pstus[] = { students, students + 1, students + 2, students + 3, students + 4 }; sort_students(pstus, 5); for (int i = 0; i < 5; i++) { print_stu_info(pstus[i]); } return 0; }
作业2:简答题(动态分配内存相关)
(a) 为什么需要在堆上申请空间?
(b) 动态内存分配函数有哪些?它们的功能是什么?
解答:
(a)
1,栈帧的大小必须在编译期确定,所以不能存储动态大小的数据
2,栈的大小是有限的,栈空间不能存储太大的数据
3,栈空间不适合存放线程之间的共享数据
(B)
1,malloc,分配 size 个字节的内存块,不对内存块进行清零;如果无法分配指定大小的内存块,返回空指针。
2,calloc,为NMEMB个元素的数组分配内存块,每个元素占SIZE个字节,并且对内存块进行清零,如果无法分配指定大小的内存块,返回空指针
3,rea