1、结构体
#include <stdio.h>
#include <string.h>
struct Student
{
int num;
char name[20];
char sex;
int age;
double score;
char addr[32];
};
int main()
{
struct Student s1;
//struct Student s2 = {2,"zs",'g',17,99.8,"上海"};
s1.num = 1;
s1.age = 21;
s1.score = 99.9;
strcpy(s1.name,"wy");
strcpy(s1.addr,"北京");
printf("学号:%d\n年龄:%d\n分数:%.1f\n名字:%s\n地址:%s\n",
s1.num,s1.age,s1.score,s1.name,s1.addr);
return 0;
}
每个成员都是结构体中的一个域,也成为域表,又称成员列表
注意:1、关键字struct;2、结构体名大写开头;3、封号
2、结构体与数组的结合
#include <stdio.h>
struct Student
{
int num;
char name[20];
char sex;
int age;
double score;
char addr[32];
};
int main()
{
int i;
int len;
struct Student arr[3] =
{
{1,"张三",'g',17,99.4,"北京"},
{2,"李四",'m',19,92.1,"广州"},
{3,"王五",'g',16,89.8,"上海"}
};
len = sizeof(arr)/sizeof(arr[0]);
for(i=0;i<len;i++)
{
printf("学号:%d\n年龄:%d\n分数:%.1f\n名字:%s\n地址:%s\n",
arr[i].num,arr[i].age,arr[i].score,arr[i].name,arr[i].addr);
}
}
例题:投票系统
//投票系统
#include <stdio.h>
#include <string.h>
struct Xuanmin
{
char name[32];
int tickets;
};
int main()
{
struct Xuanmin xm[3];
struct Xuanmin max;
int i;
int flag=0; //用来标记弃票的情况
int feipiao;//记录废票次数
int len = sizeof(xm)/sizeof(xm[0]);
char tmpname[32]; //定义一个临时姓名,用来唱票时的名字承接
int j;
for(i=0;i<len;i++) //初始化选民信息
{
xm[i].tickets = 0;
printf("请输入被选人姓名:\n");
scanf("%s",xm[i].name);
}
//唱票,假设有5票
for(i=0;i<5;i++)
{
printf("你投票给谁?\n");
memset(tmpname,'\0',sizeof(tmpname));//每次选之前,清空临时姓名
scanf("%s",tmpname);//输入被选人姓名
for(j=0;j<len;j++)
{
if(strcmp(tmpname,xm[j].name)==0)//如果临时姓名与选民姓名一样
{
xm[j].tickets++;
flag = 1;
}
}
if(flag == 0)
{
printf("没有此候选人,弃票处理!\n");
feipiao++;
}
}
//公布结果
for(i=0;i<len;i++)
{
printf("姓名:%s,票数:%d\n",xm[i].name,xm[i].tickets);
}
printf("弃票为:%d",feipiao);
}
3、结构体指针
#include <stdio.h>
struct Student
{
int num;
char name[32];
};
int main()
{
struct Student s1 = {18,"mike"};
struct Student *p = &s1;
return 0;
}
通过结构体指针访问结构体内容
#include <stdio.h>
#include <string.h>
struct Student
{
int num;
char name[32];
};
int main()
{
struct Student s1 = {18,"mike"};
struct Student *p = &s1;//定义一个指针指向s1
//变量名访问,用.运算符
printf("s1的序号为:%d s1的姓名为:%s\n",s1.num,s1.name);
//指针地址访问,用->运算符
printf("s1的序号为:%d s1的姓名为:%s\n",p->num,p->name);
//通过指针修改姓名
strcpy(p->name,"nike");
printf("s1的姓名为:%s",p->name);
return 0;
}
注意:指针遍历时,下次遍历记得重新指向数组头
4、结构体、指针、函数综合应用
5、联合体/共用体
#include <stdio.h>
//结构体
struct TestT
{
int ti;
char tc;
double td;
};
//联合体,关键字union
union TestU
{
int ui;
char uc;
double ud;
};
int main()
{
struct TestT t1;
union TestU u1;
printf("结构体t1的大小为:%d\n",sizeof(t1));//16
printf("联合体u1的大小为:%d\n",sizeof(u1));//8
puts("");
printf("ti:%p\n",&t1.ti);//ti:000000000061FE10
printf("tc:%p\n",&t1.tc);//tc:000000000061FE14
printf("td:%p\n",&t1.td);//td:000000000061FE18
printf("ui:%p\n",&u1.ui);//ui:000000000061FE08
printf("uc:%p\n",&u1.uc);//uc:000000000061FE08
printf("ud:%p\n",&u1.ud);//ud:000000000061FE08
return 0;
}
联合体占用多大空间取决于里面最大的元素占用的空间(共用)
联合体中值会存在覆盖问题,后面的数据会覆盖前面的数据
例题:若干个人员的数据,其中有学生和教师,学生的数据中包括:姓名、号码、性别、职业、班级。教师的数据中包括:姓名、号码、性别、职业、职务。要求用同一个表格来处理。
#include <stdio.h>
//结构体
struct Person
{
char name[32];
int age;
char zhiye;
union{
int class;
char abj[12];
}AD;
};
int main()
{
struct Person p[2];
int i;
for(i=0;i<2;i++)
{
printf("请输入职业,s代表学生,t代表老师:\n");
scanf("%c",&(p[i].zhiye));
if(p[i].zhiye == 's')
{
printf("请输入学生班级:\n");
scanf("%d",&(p[i].AD.class));
printf("请输入学生姓名:\n");
scanf("%s",p[i].name);
}
else
{
printf("请输入老师职务:\n");
scanf("%s",p[i].AD.abj);
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].AD.class,p[i].name);
}
else
{
printf("老师职务为:%s 老师姓名为:%s\n",p[i].AD.abj,p[i].name);
}
}
return 0;
}
!!!注意:后三个scanf没有取地址,前两个取了地址,是因为后面三个变量都是数组,可以直接调用变量名
6、枚举类型
关键字:enum
enum Weekday{sun,mon,tus,wed,thi,fri,sat};
7、typedef关键字
允许用户使用 typedef 关键字来定义自己习惯的数据类型名称,来替代系统默认的基本类型名称、数组类型名称、指针类型名称与用户自定义的结构型名称、共用型名称、枚举型名称等。
① 为基本数据类型定义新的类型名;
②为自定义数据类型(结构体、共用体和枚举类型)定义简洁的类型名称;
③ 为数组定义简洁的类型名称;
④为指针定义简洁的名称。
参考于:http://c.biancheng.net/view/298.html
#include <stdio.h>
//typedef使用
typedef struct
{
int num;
char name[32];
char sex;
}Person,*pPerson;
//使用变量名
void printfInfo(Person p)
{
printf("%d号学生是%s,性别%c\n",p.num,p.name,p.sex);
}
//使用指针1
void printfInfo1(pPerson pp)
{
printf("%d号学生是%s,性别%c\n",pp->num,pp->name,pp->sex);
}
//使用指针2
void printfInfo2(Person *p)
{
printf("%d号学生是%s,性别%c\n",p->num,p->name,p->sex);
}
int main()
{
//使用变量名
Person p1 = {1,"乐乐",'b'};
Person p2 = {2,"佳佳",'g'};
printfInfo(p1);
printfInfo(p2);
//使用指针1
pPerson p3 = &p1;
pPerson p4 = &p2;
printfInfo1(p3);
printfInfo1(p4);
//使用指针2
Person *p5 = &p1;
Person *p6 = &p2;
printfInfo1(p5);
printfInfo1(p6);
return 0;
}