学期(2024-2025-1) 学号(20241312) 《计算机基础与程序设计》第十三周学习总结
作业信息
这个作业属于哪个课程 | <班级的链接>(如2024-2025-1-计算机基础与程序设计) |
---|---|
这个作业要求在哪里 | <作业要求的链接>(如2024-2025-1计算机基础与程序设计第一周作业) |
这个作业的目标 | 加入云班课,参考本周学习资源 |
自学教材
《C语言程序设计》第12章并完成云班课测试
参考上面的学习总结模板,把学习过程通过博客(随笔)发表,博客标题“学年 学号 《计算机基础与程序设计》第十三周学习总结”|
|作业正文|https://www.cnblogs.com/songjialinsjl/p/18620789|
教材学习内容总结
在 C 语言中,结构体是一种用户自定义的数据类型,它允许将不同类型的数据组合在一起,形成一个新的复合数据类型。以下是结构体的使用和调用的详细介绍:
结构体的定义
使用struct关键字来定义结构体,语法如下:
c
struct 结构体名 {
数据类型 成员1;
数据类型 成员2;
//...
};
例如,定义一个表示学生信息的结构体:
c
struct Student {
char name[20];
int age;
float score;
};
结构体变量的声明和初始化
声明结构体变量:在定义结构体后,可以声明该结构体类型的变量。有以下两种方式:
先定义结构体类型,再声明变量:
c
struct Student stu1, stu2;
在定义结构体类型的同时声明变量:
c
struct Student {
char name[20];
int age;
float score;
} stu1, stu2;
初始化结构体变量:可以在声明结构体变量的同时对其进行初始化,使用花括号{}括起来的初始值列表,按照结构体成员的顺序依次赋值。例如:
c
struct Student stu1 = {"Tom", 18, 90.5};
结构体成员的访问
使用点运算符.来访问结构体变量的成员。例如:
c
include <stdio.h>
int main() {
struct Student stu1 = {"Tom", 18, 90.5};
printf("Name: %s\n", stu1.name);
printf("Age: %d\n", stu1.age);
printf("Score: %.2f\n", stu1.score);
return 0;
}
结构体数组
可以定义结构体数组,即数组中的每个元素都是一个结构体变量。例如:
c
include <stdio.h>
struct Student {
char name[20];
int age;
float score;
};
int main() {
struct Student students[3] = {
{"Tom", 18, 90.5},
{"Jerry", 19, 85.0},
{"Alice", 20, 92.0}
};
for (int i = 0; i < 3; i++) {
printf("Student %d:\n", i + 1);
printf("Name: %s\n", students[i].name);
printf("Age: %d\n", students[i].age);
printf("Score: %.2f\n", students[i].score);
printf("\n");
}
return 0;
}
结构体指针
可以定义指向结构体的指针,通过指针来访问结构体成员。使用箭头运算符->来访问结构体指针所指向的结构体成员。例如:
c
include <stdio.h>
struct Student {
char name[20];
int age;
float score;
};
int main() {
struct Student stu1 = {"Tom", 18, 90.5};
struct Student *p = &stu1;
printf("Name: %s\n", p->name);
printf("Age: %d\n", p->age);
printf("Score: %.2f\n", p->score);
return 0;
}
结构体作为函数参数
结构体可以作为函数的参数进行传递,有以下两种方式:
值传递:将结构体变量的值复制一份传递给函数,函数内对参数的修改不会影响原结构体变量。例如:
c
include <stdio.h>
struct Student {
char name[20];
int age;
float score;
};
void printStudent(struct Student s) {
printf("Name: %s\n", s.name);
printf("Age: %d\n", s.age);
printf("Score: %.2f\n", s.score);
}
int main() {
struct Student stu1 = {"Tom", 18, 90.5};
printStudent(stu1);
return 0;
}
地址传递:将结构体变量的地址传递给函数,函数内通过指针来访问和修改结构体成员,会影响原结构体变量。例如:
c
include <stdio.h>
struct Student {
char name[20];
int age;
float score;
};
void updateScore(struct Student *p, float newScore) {
p->score = newScore;
}
int main() {
struct Student stu1 = {"Tom", 18, 90.5};
updateScore(&stu1, 95.0);
printf("Updated Score: %.2f\n", stu1.score);
return 0;
}
教材学习中的问题和解决过程(先问 AI)
问题:在结构体的使用中stu1、stu2与stu【1】、stu【2】有什么区别?
回答:在 C 语言中,stu1、stu2与stu[1]、stu[2]存在明显区别,以下是具体分析:
定义和性质
stu1、stu2:它们是通过struct结构体类型定义的普通结构体变量。例如,在struct Student { char name[20]; int age; float score; };定义后,使用struct Student stu1, stu2;声明的两个变量。每个变量都独立地存储了一个完整的结构体数据,相互之间没有直接的关联。
stu[1]、stu[2]:这是结构体数组stu中的元素。例如,struct Student stu[3];定义了一个包含 3 个struct Student类型元素的数组,stu[1]和stu[2]分别是数组中的第 2 个和第 3 个元素,它们在内存中是连续存储的,共同构成了一个数组整体。
访问方式
stu1、stu2:通过点运算符.来访问结构体成员。例如,stu1.name、stu2.age等,直接使用变量名加上点运算符和成员名来获取或设置结构体成员的值。
stu[1]、stu[2]:同样使用点运算符来访问成员,但需要先指定数组下标。如stu[1].name、stu[2].score等,先通过下标确定要访问的数组元素,再使用点运算符访问该元素的结构体成员。
内存布局和分配
stu1、stu2:在内存中,stu1和stu2通常是两个独立分配的内存块,它们的存储位置可能不相邻,具体取决于编译器和内存分配策略。每个结构体变量都有自己独立的一套结构体成员变量的存储空间。
stu[1]、stu[2]:结构体数组stu在内存中是连续分配的一块内存空间,stu[1]紧接着stu[0]存储,stu[2]又紧接着stu[1]存储,它们之间的偏移量是固定的,等于一个结构体所占的字节数。
使用场景
stu1、stu2:适用于只需要处理少量独立的结构体数据的情况。例如,定义两个单独的学生结构体变量来分别存储不同学生的信息,方便对单个学生的信息进行单独操作和处理。
stu[1]、stu[2]:常用于需要批量处理多个结构体数据的场景。比如,存储一个班级的学生信息,通过循环遍历结构体数组,可以方便地对所有学生的信息进行统一的操作,如输入输出、统计分析等。
代码:
include <stdio.h>
include <math.h>
include <string.h>
typedef struct
{
long studentID;
char studentname[10];
int score[4];
} STUDENT;
void inputscore(STUDENT stu[],int n);
void totalandaverage(STUDENT stu[],float aver[],int total[],int n);
void compare(STUDENT stu[],float aver[],int total[],int n);
void comparation (STUDENT stu[],float aver[],int total[],int n);
void printscore(STUDENT stu[],float aver[],int total[],int n);
void comparebigfirst(STUDENT stu[],float aver[],int total[],int n);
void writefile(STUDENT stu[],int n);
void readfile(STUDENT stu[],int n);
int main(void)
{
int op;
float aver[40];
int total[40];
char name[10];
int i;
STUDENT stu[40];
int n;
printf("输入学生人数:");
scanf("%d",&n);
do
{
printf("1.Append record\n2.Calculate total and average score of every student\n3.Sort in ascending order by total score of every student\n4.Sort in dictionary order by name\n5.Search by name\n6.Write to a file\n7.Read from a file\n0.Exit\nPlease enter your choice:");
scanf("%d",&op);
switch(op)
{
case 1:
inputscore(stu ,n);
break;
case 2:
totalandaverage(stu,aver,total,n);
printscore(stu,aver,total,n);
break;
case 3:
compare(stu,aver,total,n);
printf("从小到大:\n");
printscore(stu,aver,total,n);
break;
case 4:
printf("按字典顺序:\n");
comparation (stu,aver,total,n);
printscore(stu,aver,total,n);
break;
case 5:
comparebigfirst(stu,aver,total,n);
printf("please input name");
scanf("%s",name);
for(i=0; i<n; i++)
{
if(strcmp(stu[i].studentname,name)==0)
{
printf("排名:%d 成绩:%d",i+1,total[i]);
}
}printscore(stu,aver,total,n);break;case 6:writefile(stu,n);break;case 7:readfile(stu,n);printscore(stu,aver,total,n);break;case 0:break;default :break ;}
}
while (op!=0);
return 0;
}
void inputscore(STUDENT stu[],int n)
{
int i,j;
for (i=0; i<n; i++)
{
printf("input\n");
scanf("%ld",&stu[i].studentID);
scanf("%s",stu[i].studentname);
for (j=0; j<4; j++)
{
scanf("%d",&stu[i].score[j]);
}
}
}
void totalandaverage(STUDENT stu[],float aver[],int total[],int n)
{
int i,j;
for (i=0; i<n; i++)
{
total[i]=0;
for (j=0; j<4; j++)
{
total[i]=total[i]+stu[i].score[j];
}
aver[i]=(float)total[i]/4;
}
}
void compare(STUDENT stu[],float aver[],int total[],int n)
{
int i,j,num;
STUDENT temp;
for(i=0; i<n-1; i++)
{
for (j=i+1; j<n; j++)
{
if (total[i]>total[j])
{
temp = stu[i];
stu[i] = stu[j];
stu[j ] = temp;
num=total[i];
total[i]=total[j];
total[j]=num;
num=aver[i];
aver[i]=aver[j];
aver[j]=num;
}
}
}
}
void printscore(STUDENT stu[],float aver[],int total[],int n)
{
int i;
for (i=0; i<n; i++)
{
printf("%ld\n%s\n",stu[i].studentID,stu[i].studentname);
printf("%d\n%f\n",total[i],aver[i]);
}
}
void comparation (STUDENT stu[],float aver[],int total[],int n)
{
int i,j,num;
STUDENT temp;
for(i=0; i<n-1; i++)
{
for (j=i+1; j<n; j++)
{
if (strcmp(stu[i].studentname,stu[j].studentname)>0)
{
temp = stu[i];
stu[i] = stu[j];
stu[j ] = temp;
num=total[i];
total[i]=total[j];
total[j]=num;
num=aver[i];
aver[i]=aver[j];
aver[j]=num;
}
}
}
}
void comparebigfirst(STUDENT stu[],float aver[],int total[],int n)
{
int i,j,num;
STUDENT temp;
for(i=0; i<n-1; i++)
{
for (j=i+1; j<n; j++)
{
if (total[i]<total[j])
{
temp = stu[i];
stu[i] = stu[j];
stu[j ] = temp;
num=total[i];
total[i]=total[j];
total[j]=num;
num=aver[i];
aver[i]=aver[j];
aver[j]=num;
}
}
}
}
void writefile(STUDENT stu[],int n)
{
FILE *fp = fopen("students", "w");
if (fpNULL)
{
printf("Error opening file");
}
else
{
fwrite(stu,sizeof(STUDENT),n,fp);
}
}
void readfile(STUDENT stu[],int n)
{
FILE *fp = fopen("students", "r");
if (fpNULL)
{
printf("Error opening file");
}
else
{fread(stu,sizeof(STUDENT),n,fp);
}
fclose(fp);
}