参考:五大板块(3)—— 结构体
作者:丶PURSUING
发布时间: 2021-03-18 16:02:43
网址:https://blog.csdn.net/weixin_44742824/article/details/114981743
目录
- 结构体的三种定义赋值方法
- 结构体数组
- 结构体指针(在指针中已有介绍)
- 结构体的综合运用👉学生成绩处理
- 小问题:不会释放指针,或者需不需要释放?
- 结构体大小计算方法
结构体的三种定义赋值方法
#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 = "张大大"; //结构体(类)中:JAVA c++可以这么赋值 C语言不可以!strcpy(stu2.name,"张大大");//C语言中字符串必须通过strcpy进行赋值//char *str="我爱你"; 初始化可以直接用指针变量指向该字符串//chat *str; 指针和值分开要用到strcpy进行赋值//str = (char*)malloc(128);//memset(str,'\0',128);//strcpy(str,"我爱你"); //三、常用的部分赋值方式,多见于内核源码对结构体的定义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
- 1
- 2
- 3
为什么使用
strcpy
?
如果不在结构体变量初始化的时候就对具有数组类型的表达式赋值,则要使用strcpy,即不能直接赋值。
线下班常犯下的致命问题
struct data1{
char*p;
};struct data2{
char p[128];
};
两者区别在于前者为野指针,不清楚指向什么地址,访问时(使用strcpy())会报错
必须要先经过malloc和memset这两步操作
结构体数组
做个简单应用就好:输入4个学生的名字成绩,找出最高分。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>struct student
{char* name; //char name[128];这种方法浪费空间 在linux环境下,一个指针只占用8个字节int score;
};int main()
{int i;struct student stu[4];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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
跟结构体指针真的好像。
结构体指针(在指针中已有介绍)
结构体的综合运用👉学生成绩处理
因为呢结构体比较重要,搞个稍微复杂一点的练练手。
主要运用结构体指针,输入学生的学号,语文数学英语成绩。
要求封装功能函数(初始化学生成绩,找到分数最高的学生,算出班级平均分)。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>typedef struct student
{char* name;int chinese;int math;int english;int total;
}STU,*PSTU; //typedef 为一种数据类型定义一个新名字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
- 1
- 2
- 3
- 4
- 5
小问题:不会释放指针,或者需不需要释放?
free(p);
p = NULL;
- 1
- 2
报错:释放了一个自由的地址?释放错了?
double free or corruption (!prev): 0x0017d848 ***
- 1
可能是因为p++的影响,释放错了地址,于是
free(p-num);
p = NULL;
- 1
- 2
嘿嘿,还是不行,懂了再回来更新。我还是先注释掉吧。