为什么要用结构体
1.整型数,浮点型数,字符串湿分散的数据表示,有时候我们需要用很多类型的数据来表示一个整体,比如学生信息。
类比与数组:数组是元素类型一样的数据集合,如果是元素类型不同的数据集合,就要用到结构体。
定义一个结构体:
#include<stdio.h>
//告知系统是一个结构体
struct Student//编程习惯大写开头
{
int num;
char name[32];
char sex;
int age;
double score;
char addr[32];
};//分号不能忘
struct Day
{
int year;
int month;
int day;
};
struct XuanMin
{
char name[32];
int tickets;
};
int main()
{
return 0;
}
成员列表——也称为域表——每个成员都是结构体的一个域
在声明的同时,定义变量,尽量少用:
初始一个结构体变量并引用
初始化:
#include<stdio.h>
#include<string.h>
struct Student
{
int num;
char name[32];
char sex;
int age;
double score;
char addr[32];
};
int main()
{
struct Student stu1;
struct Student stu2;
stu1.num=1;
stu1.age=18;//点运算符来访问结构体中的成员变量(域);
stu1.score=98.5;
strcpy(stu1.name,"chenlichen");
strcpy(stu1.addr,"广州");
printf("学号:%d,年龄:%d,分数:%.2lf,名字:%s,地址:%s\n",
stu1.num,stu1.age,stu1.score,stu1.name,stu1.addr);
}
引用:
重点认知:结构体没什么特殊的,只是把变量藏在结构体里面,而内部的变量,以前学习的东西是通用的,只是触达的方式不同。
例题:输入两个学生名字,学号,成绩,输出成绩高的学生的信息
#include<stdio.h>
struct Student
{
int num;
char name[32];
char sex;
int age;
double score;
char addr[32];
};
int main()
{
struct Student stu1;
struct Student stu2;
struct Student max;
printf("请输入第一个学生的学号,姓名,成绩:\n");
scanf("%d%s%lf",&stu1.num,&stu1.name,&stu1.score);
printf("请输入第二个学生的学号,姓名,成绩:\n");
scanf("%d%s%lf",&stu2.num,&stu2.name,&stu2.score);
max=stu1;
if(stu1.score<stu2.score){
max=stu2;
}
printf("成绩高的学生的学号,姓名,成绩:%d,%s,%.2lf",max.num,max.name,max.score);
}
结构体数组
#include<stdio.h>
struct Student
{
int num;
char name[32];
char sex;
int age;
double score;
char addr[32];
};
int main()
{
int i;
int len;
struct Student arr[3]={
{2,"张三",'g',17,99.5,"广州"}
,{3,"李四",'f',18,89.5,"深圳"}
,{4,"李四",'h',19,100,"北京"},
};
len=sizeof(arr)/sizeof(arr[0]);
for(i=0;i<len;i++){
printf("学号:%d,年龄:%d,分数:%.2lf,名字:%s,地址:%s\n",
arr[i].num,arr[i].age,arr[i].score,arr[i].name,arr[i].addr);
}
return 0;
}
应用练习:选票系统
#include<stdio.h>
#include<string.h>
struct XuanMin
{
char name[32];
int tickets;
};
int main()
{
int i,j;
struct XuanMin xm[3];
struct XuanMin max;
int feipiao=0;
int mark=0;
int total=5;
char tempname[32];
int len=sizeof(xm)/sizeof(xm[0]);
for(i=0;i<len;i++){
xm[i].tickets=0;
printf("请输入第%d个选民的名字:\n",i+1);
scanf("%s",xm[i].name);
}
//唱票环节
for(i=0;i<5;i++){
mark=0;
printf("请问你要投给谁:\n");
memset(tempname,'\0',sizeof(tempname));
scanf("%s",tempname);
for(j=0;j<len;j++){
if(strcmp(tempname,xm[j].name)==0){
xm[j].tickets++;
mark=1;
}
}
if(mark==0){
printf("没有此候选人,弃票\n");
feipiao++;
}
}
for(i=0;i<len;i++){
printf("名字:%s,票数:%d\n",xm[i].name,xm[i].tickets);
}
max=xm[0];
for(i=0;i<len;i++){
if(max.tickets<xm[i].tickets){
max=xm[i];
}
}
printf("%s以%d票当选!!废票是%d\n",max.name,max.tickets,feipiao);
}
结构体指针
与之前的指针一模一样:只是指针类型是结构体
通过结构体指针访问结构体:
#include<stdio.h>
struct Test
{
int idata;
char cdata;
};
int main()
{
int a=10;
int *p=&a;
char c='c';
char *pc=&c;
struct Test t1={10,'c'};
struct Test *ps=&t1;
printf("t1的idata=%d\n",t1.idata);
printf("t1的idata=%d\n",ps->idata);//间接访问用->符号
ps->cdata='R';
printf("c1的idata=%c\n",t1.cdata);
printf("c1的idata=%c\n",ps->cdata);
return 0;
}
结构体数组,指针,函数应用
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct XuanMin
{
char name[32];
int tickets;
};
struct XuanMin* initXms(struct XuanMin *p,int *pn)
{
int i;
if(p==NULL){
printf("有多少个人参选:\n");
scanf("%s",pn);
p=(struct XuanMin*)malloc(*pn*sizeof(struct XuanMin));
}
for(i=0;i<*pn;i++){
p->tickets=0;
printf("请输入第%d个选民的名字:\n",i+1);
scanf("%s",p->name);
p++;
}
return p-*pn;
}
void printXms(struct XuanMin *p,int len)
{
int i;
for(i=0;i<len;i++){
printf("名字:%s,票数:%d\n",p->name,p->tickets);
p++;
}
}
int dovot(struct XuanMin *p,int len)
{
int i;
int j;
int mark;
int feipiao=0;
char tempName[32];
struct XuanMin *pbak=p;
for(i=0;i<5;i++){
mark=0;
printf("你要投给谁\n");
memset(tempName,'\0',sizeof(tempName));
scanf("%s",tempName);
p=pbak;
for(j=0;j<len;j++){
if(strcmp(tempName,p->name)==0){
p->tickets++;
mark=1;
}
p++;
if(mark=0){
printf("没有此人,放弃\n");
feipiao++;
}
}
}
return feipiao;
}
struct XuanMin *getmax(struct XuanMin *p,int len)
{
struct XuanMin *max;
int i;
max=p;
for(i=0;i<len;i++){
if(max->tickets<p->tickets){
max=p;
}
p++;
}
return max;
}
int main()
{
struct XuanMin *xm=NULL;
struct XuanMin *max;
int total=0;
xm=initXms(xm,&total);
printXms(xm,total);
int feip=dovot(xm,total);
printf("废票数是:%d\n",feip);
printXms(xm,total);
max=getmax(xm,total);
printf("%s以%d票当选",max->name,max->tickets);
return 0;
}
共用体/联合体
1.有时候同一个内存空间存放类型不同,不同类型的变量共享一块空间。
2.结构体元素有各自单独空间
共用体元素共享空间,空间大小由最大类型确定
结构体元素互不影响共用体赋值会导致覆盖******
#include<stdio.h>
struct TestT
{
int idata;
char cdata;
int ddata;
};
union TestU
{
int idata;
char cdata;
int ddata;
};
int main()
{
struct TestT t1;
union TestU u1;
printf("结构体的大小是:%d\n",sizeof(t1));
printf("结构体的大小是:%d\n",sizeof(u1));
t1.idata=10;
t1.cdata='a';
t1.ddata=20;
printf("idata:%p,%d\n",&t1.idata,t1.idata);
printf("cdata:%p,%d\n",&t1.cdata,t1.cdata);
printf("ddata:%p,%d\n",&t1.ddata,t1.ddata);
u1.idata=10;
u1.ddata=20;
u1.cdata='a';
printf("idata=%d\n",u1.idata);
printf("idata:%p,%d\n",&u1.idata,u1.idata);
printf("cdata:%p,%d\n",&u1.cdata,u1.cdata);
printf("ddata:%p,%d\n",&u1.ddata,u1.ddata);
return 0;
}
注意共用体的的数据覆盖
应用:
#include<stdio.h>
struct Person
{
char name[32];
int age;
char zhiye;
char addr[32];
union{
int class;
char keMu[12];
}mes;
};
int main()
{
struct Person p[2];
int i;
for(i=0;i<2;i++){
printf("请输入职业:t代表老师,s代表学生\n");
scanf("%c",&(p[i].zhiye));
if(p[i].zhiye=='s'){
printf("请输入学生班级:\n");
scanf("%d",&(p[i].mes.class));
printf("请输入学生名字:\n");
scanf("%s",p[i].name);
}
else{
printf("请输入老师科目:\n");
scanf("%s",p[i].mes.keMu);
printf("请输入老师名字:\n");
scanf("%s",p[i].name);
}
getchar();
}
for(i=0;i<2;i++){
if(p[i].zhiye=='s'){
printf("学生班级是:%d,学生名字是:%s\n",p[i].mes.class,p[i].name);
}else{
printf("老师职业是:%s,老师名字是:%s\n",p[i].mes.keMu,p[i].name);
}
}
return 0;
}
枚举类型
如果一个变量只有几种可能的值,比如星期几son,mon,tus,wed,thu,fri,sat.
typedef关键字
给已有的变量类型起名字,一般配合结构体用,方便,不用每次都要struct开头。
#include<stdio.h>
typedef unsigned int u8;
typedef int u16;
typedef int arr[10];
struct Test
{
int data;
int data2;
};
typedef struct Test T;
typedef struct
{
int data1;
int data;
}Demo;//常规用法
void printfInfo(T,t)
{
printf("%d",t.data);
}
int main()
{
arr a;
a[0]=10;
printf("%d\n",a[0]);
struct Test t1;
t1.data=100;
printf("%d",t1.data);
T t2;
t2.data=1000;
//printf("%d",ti.data);
printInfo(t2);
Demo d;
d.data1=999;
printf("%d ",d.data1);
return 0;
}
案例:加深记忆
#include<stdio.h>
typedef struct
{
int num;
char name[32];
char sex;
}Person,*pPerson;
void printInfo(Person P)
{
printf("%d号姐姐:%s %c\n",P.num,P.name,P.sex);
}
void printInfo3(Person *p)
{
printf("%d号姐姐:%s %c\n",p->num,p->name,p->sex);
}
void printInfo2(pPerson pp)
{
printf("%d号姐姐:%s %c\n",pp->num,pp->name,pp->sex);
}
int main()
{
Person p1={1,"莉莉",'g'};
Person p2={2,"美美",'g'};
printInfo(p1);
printInfo(p2);
pPerson pp1=&p1;
pPerson pp2=&p2;
printInfo2(pp1);
printInfo2(pp2);
Person *pp3=&p1;
Person *pp4=&p2;
printInfo3(pp3);
printInfo3(pp4);
return 0;
}