- 一:为什么要用结构体?
- 二:结构体数组来玩成绩
- 三:结构体指针
- 四:结构体指针函数综合处理学生成绩
- 五:结构体大小的计算方式:
- 六:typedef关键字
1.结构体是类型不同的一组数据集合,数据更多,类型更丰富,信息量更大
#include#include #include //这样定义一个结构体 struct student { int score; char name[128]; };//注意分号要写 int main() { //stu1 是结构体变量名 struct student stu1 = {100,"free"};//大括号里面的是初始值 //访问结构体数据 printf("stu1结构体的: score=%dn",stu1.score); printf("stu1结构体的:name=%sn",stu1.name);//结构体变量名.内部变量名 struct student stu2;//没做初始化的结构体 stu2.score = 99;//给结构体内部数据赋值 //stu2.name = "张三";这样是不行的 strcpy(stu2.name,"张三"); printf("stu2结构体的: score=%dn",stu2.score); printf("stu2结构体的:name=%sn",stu2.name); return 0; }
2.运行结果:
3.注意常犯的错误 “野指针”
#include#include #include struct stu { char *name; }; struct text { char name[128]; }; int main() { struct stu a; struct text b; //第二种 strcpy(b.name,"感觉自己萌萌哒"); printf("text的name = %sn",b.name); return 0; }
第一种运行结果:
因为是对野指针直接赋值,出现段错误,人家都还只是一个地址,都还没有开辟空间呢你就给人家赋值,所以对使用指针一定要注意,要先开辟空间再初始化,最后再赋值!!!
第二种运行结果:
二:结构体数组来玩成绩因为是对字符串数组进行赋值,数组定义出来就已经申请了空间,所以可以直接赋值
#include#include #include struct student { int score; char *name; }; int main() { int i; struct student stu[3];//定义了一个结构体数组,也是通过下标法来访问 for(i=0;i printf("请输入第%d个学生的成绩:n",i+1); scanf("%d",&(stu[i].score)); printf("请输入第%d个学生的名字:n",i+1); stu[i].name = (char *)malloc(128);//注意对结构体内部指针,使用前要申请开辟空间 scanf("%s",stu[i].name); } for(i=0;i printf("你输入的%d个学生的成绩是:%d 名字是:%sn",i+1,stu[i].score,stu[i].name); } struct student maxStu; struct student minStu; maxStu = minStu = stu[0]; for(i=0;i if(maxStu.score < stu[i].score){ maxStu = stu[i]; } if(minStu.score > stu[i].score){ minStu = stu[i]; } } printf("考最高分的是:%s 分数是:%dn",maxStu.name,maxStu.score); printf("考最低分的是:%s 分数是:%dn",minStu.name,minStu.score); return 0; }
运行结果:
1.
1.如果结构体指针,访问结构体中的变量时就不能用点运算符,要用->
2.使用结构体指针时,要注意是否是野指针或者是NULL!!!
3.结构体指针的偏移值是整个结构体的大小
2.看代码
#include#include #include struct student { int score; char name[128]; }; int main() { struct student *p;//这样定义一个结构体指针,不过这是野指针,还没有开辟空间 p = (struct student *)malloc(sizeof(struct student));//开辟空间 p->score = 98;//赋值 strcpy(p->name,"李四"); printf("结构体指针的score=%d name=%sn",p->score,p->name); //看下偏移值 printf("结构体指针的地址是:%pn",p); printf("++后的地址是:%pn",++p); return 0; }
3.运行结果:
#include#include #include struct student { int score; char *name; }; struct student * initStuScore(int len) { int i; //在堆上开辟空间,函数结束调用不会释放 struct student *p = (struct student *)malloc(len * sizeof(struct student)); for(i=0;i printf("请输入第%d个学生的名字:n",i+1); p->name = (char *)malloc(128); scanf("%s",p->name); printf("请输入第%d个学生的成绩:n",i+1); scanf("%d",&(p->score)); p++; } return p - len; } void printMes(struct student *p,int len) { int i; for(i=0;i printf("你输入的第%d个学生的成绩是:%d 名字是:%sn",i+1,p->score,p->name); p++; } } struct student *findMax(struct student *p,int len) { int i; struct student *max; max = p; for(i=0;i if(max->score < p->score){ max = p; } p++; } return max; } struct student *findMin(struct student *p,int len) { int i; struct student *min; min = p; for(i=0;i if(min->score > p->score){ min = p; } p++; } return min; } float getAverage(struct student *p,int len) { int i; int total = 0; for(i=0;i total += p->score; p++; } return (float)total / len; } int findSomeOneName(struct student *p,int len,char *name) { int i; for(i=0;i if(strcmp(name,p->name) == 0){ return 1; } p++; } return -1; } int main() { int len = 0; printf("请输入学生总人数:n"); scanf("%d",&len); struct student *max; struct student *min; struct student *pstus = initStuScore(len); printMes(pstus,len); max = findMax(pstus,len); min = findMin(pstus,len); printf("你输入学生成绩的最高分是:%d 名字是:%sn最低分是:%d 名字是:%s 平均分是:%fn",max->score,max->name,min->score,min->name,getAverage(pstus,len)); if(findSomeOneName(pstus,len,"王五") == -1){ printf("没有此人n"); }else{ printf("恭喜,找到了n"); } return 0; }
>运行结果:
1.结构体成员的偏移量必须是成员大小的整数倍(0被认为是任何数的整数倍)
2.结构体大小必须是所有成员大小(数组除外,结构体除外)的整数倍
注意:对齐方式确实很浪费空间,但是按照计算机的访问规则,这种对齐方式大大提升了效率
代码段:
#include六:typedef关键字#include struct s1 { char ch1; char ch2; int i; }; struct s2 { char ch1; int i; char ch2; }; struct s3 { char ch1; int i; char str[10]; }; struct s4 { char ch1; int i; struct s{ char ch; int j; }; float f; }; struct s5 { char ch1; int i; union{ char ch; int j; }; }; //#pragma pack(4) //指定向4对齐,最大是8,指定的大小没有超过结构体成员的大小,所以指向4对齐 struct s6 { char ch; int i; float f; double d; }; #pragma pack(10)//指定向10对齐,超过了结构体成员最大的大小,所以指向8对齐 struct s7 { char ch; int i; float f; double d; }; int main() { printf("s1:%ldn",sizeof(struct s1));//结果:8 printf("s2:%ldn",sizeof(struct s2));//结果:12 printf("s3:%ldn",sizeof(struct s3));//结果:20 printf("s4:%ldn",sizeof(struct s4));//结果:12 printf("s5:%ldn",sizeof(struct s5));//结果:12 printf("s6:%ldn",sizeof(struct s6));//结果:20 printf("s7:%ldn",sizeof(struct s7));//结果:24 return 0; }
1.typedef为c语言的关键字
2.作用是为一种数据类型定义一个新名字
3.这里的数据类型包括内部数据类型(int ,char 等)和自定义数据类型(struct 等)
4.和struct 来匹配为了代码编写简洁,和普通类型匹配,通过名字来获取一些信息
代码段:
#include#include #include //在单片机开发,寄存器8位,16位,32位 typedef unsigned char u_int8; typedef unsigned short int u_int16; typedef unsigned int u_int32; typedef struct student { int score; char *name; }STU,*PSTU; int main() { u_int8 data1 = 10; u_int16 data2 = 20; u_int32 data3 = 30; printf("%d %d %dn",data1,data2,data3); STU stu1; stu1.score = 99; printf("stu1的score=%dn",stu1.score); PSTU pstu; pstu = (PSTU)malloc(sizeof(STU)); pstu->score = 100; printf("pstu的score=%dn",pstu->score); }
运行结果:



