师承陈立臣
结构体的三种定义赋值方法
#include <stdio.h>
#include <string.h>
struct student
{
int englishScore;
int mathScore;
int chineseScore;
char name[128];
};//此处分号易漏
int main()
{
//一、在结构体变量定义的时候就赋值,此时要全部赋值
struct student stu1={100,100,100,"周星星"};
//二、先定义,后赋值,不需要全部赋值
struct student stu2;
stu2.englishScore = 90;
//stu2.name = "张大大";
strcpy(stu2.name,"张大大");
//三、常用的部分赋值方式,多见于内核源码对结构体的定义
struct student stu3={
.name = "华天朱",
.englishScore = 90,
.mathScore = 80, //此处是逗号
};//分号易漏
printf("stu1的名字是:%s,分数:%d\n",stu1.name,stu1.englishScore);
printf("stu2的名字是:%s,分数:%d\n",stu2.name,stu2.englishScore);
printf("stu3的名字是:%s,分数:%d\n",stu3.name,stu3.englishScore);
return 0;
}
运行结果:
stu1的名字是:周星星,分数:100
stu2的名字是:张大大,分数:90
stu3的名字是:华天朱,分数:90
为什么使用
strcpy
?
如果不在结构体变量初始化的时候就对具有数组类型的表达式赋值,则要使用strcpy,即不能直接赋值。
结构体数组
做个简单应用就好:输入4个学生的名字成绩,找出最高分。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct student
{
char* name;
int score;
};
int main()
{
int i;
struct student stu[4] = {0};
for(i=0;i<4;i++){
printf("请输入第%d个学生的名字\n",i+1);
stu[i].name = (char* )malloc(sizeof(char)*16);
memset(stu[i].name,0,sizeof(char)*16);
scanf("%s",stu[i].name);
printf("请输入他的成绩\n");
scanf("%d",&stu[i].score);
}
struct student stuMax = stu[0];//就像正常的变量一样,可以相互赋值
for(i=1;i<3;i++){
if(stu[i].score > stuMax.score){
stuMax = stu[i];
}
}
printf("最高分是%s:%d\n",stuMax.name,stuMax.score);
return 0;
}
结果:
请输入第1个学生的名字
喜羊羊
请输入他的成绩
90
请输入第2个学生的名字
懒羊羊
请输入他的成绩
60
请输入第3个学生的名字
美羊羊
请输入他的成绩
80
请输入第4个学生的名字
废羊羊
请输入他的成绩
30
最高分是喜羊羊:90
跟结构体指针真的好像。
结构体指针(在指针中已有介绍)
结构体的综合运用👉学生成绩处理
因为呢结构体比较重要,搞个稍微复杂一点的练练手。
主要运用结构体指针,输入学生的学号,语文数学英语成绩。
要求封装功能函数(初始化学生成绩,找到分数最高的学生,算出班级平均分)。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct student
{
char* name;
int chinese;
int math;
int english;
int total;
}STU,*PSTU;
PSTU initStu(int num)
{
int i;
//要想返回结构体指针,就要先创建并开创空间。
PSTU p = (PSTU)malloc(sizeof(STU) * num);
for(i=0;i<num;i++){
printf("请输入第%d个学生的学号\n",i+1);
p->name = (char* )malloc(16);//为字符指针开辟空间才能赋值,否则就等着段错误吧。
memset(p->name,0,16);
scanf("%s",p->name);
printf("请分别输入语文,数学,英语成绩,以逗号隔开,以回车结束\n");
scanf("%d,%d,%d",&p->chinese,&p->math,&p->english);
p++;
}
return p-num;
}
void print(PSTU stuSum,PSTU stuMax,int ave,int num)
{
int i;
PSTU p = stuSum;//这样不会导致stuSum指针偏移
for(i=0;i<num;i++){
printf("%s>>>>语文:%d,数学:%d,英语:%d\n\n",p->name,p->chinese,p->math,p->english);
p++;
}
printf("总分最高分是%s:%d\n",stuMax->name,stuMax->total);
printf("班级平均分是:%d\n",ave);
// free(p-num);
// p = NULL;
}
PSTU findMax(PSTU stuSum,int num)
{
int i;
PSTU max = stuSum;
PSTU p = stuSum;
for(i=0;i<num;i++){
if(p->total > max->total){
max = p;
}
p++;
}
return max;
}
void getTotalAndAve(PSTU stuSum,int num,int* ave)
{
int i;
int sum = 0;
PSTU p = stuSum;
for(i=0;i<num;i++){
p->total = p->chinese + p->math + p->english;
p++;
}
p -= num;
for(i=0;i<num;i++){
sum += p->total;
p++;
}
*ave = sum / num;
// free(p-num);
// p=NULL;
}
int main()
{
int num;//学生人数
int ave;//班级均分
printf("需要录入几人的成绩?\n");
scanf("%d",&num);
PSTU stuSum = initStu(num);//初始化学生信息
getTotalAndAve(stuSum,num,&ave);//计算各个学生的总分以及班级均分
PSTU stuMax = findMax(stuSum,num);//找到总分最高的学生
print(stuSum,stuMax,ave,num);//打印学生信息,最高分的人,班级均分
return 0;
}
结果:
18001>>>>语文:90,数学:80,英语:70
18002>>>>语文:98,数学:9,英语:76
18003>>>>语文:54,数学:89,英语:90
总分最高分是18001:240
班级平均分是:218
小问题:不会释放指针,或者需不需要释放?
free(p);
p = NULL;
报错:释放了一个自由的地址?释放错了?
double free or corruption (!prev): 0x0017d848 ***
可能是因为p++的影响,释放错了地址,于是
free(p-num);
p = NULL;
嘿嘿,还是不行,懂了再回来更新。我还是先注释掉吧。