1.1结构体引入
1.为什么要用结构体?——>可以用来表示多个不同类型为一个结构体、比如学生信息(名字、性别、年龄、地址都是不同的类型)
对比于数组——>数组的类型要相同组成一个集合,而结构体里的类型可以不同组成一个集合
定义一个结构体——>结构体为模板不赋值
struct Student //struct作用是告知系统是一个结构体 Student中的S开头要大写
{
int num;
char name[32];
char sex;
int age;
double score;
char addr[32];
};//分号要加
它算是一个模板,一般不给赋具体的值,每一项在实际应用中并不是都要使用,(就好比做excel电子表格)
1.2定义结构体和使用变量
int a;
int 相当于结构体的struct Student
a相当于给结构体定义一个变量名stu1、stu2
struct Student stu1
struct Student stu2
a = 10;
在结构体中赋值相当于stu1.num = 1;
stu1.num = 1;//点是运算符来访问结构体中的成员变量(域)
#include "stdio.h" //包含头文件
#include "string.h" //包含头文件
struct Student
{
int num;
char name[32];
char sex;
int age;
double score;
char addr[32];
};
int main()
{
int a;
struct Student stu1;
struct Student stu2;
a = 10;
stu1.num = 1;//点是运算符来访问结构体中的成员变量(域)
stu1.age = 10;
stu1.score = 98.5;
strcpy(stu1.name,"aabbccdd");
strcpy(stu1.addr,"福州");
printf("学号:%d,年龄:%d,分数:%lf,名字:%s,地址:%s",stu1.num,stu1.age,stu1.score,stu1.name,stu1.addr);
return 0;
}
strcpy函数是复制字符串的,接受两个参数,一个是被复制字符串,另一个新字符串。
strcpy(stu1.name,"aabbccdd");
直接初始化: struct Student stu2 = {2,”张三“,‘g’,17,98.5,"北京"};
1.3小应用
例:输入两个学生的名字,学号,成绩,输出成绩高的学生的信息
方法一:if-else判断两个同学哪个成绩好
/*题目:输入两个学生的名字,学号,成绩,输出成绩高的学生的信息*/
#include "stdio.h"
#include "string.h"
struct Student
{
int num;
char name[32];
char sex;
int age;
double score;
char addr[32];
};
int main()
{
int a;
struct Student stu1;
struct Student stu2 ={2,"张三",'g',17,99.5,"北京"};
a = 10;
stu1.num = 1;
stu1.age = 10;
stu1.score = 98.5;
strcpy(stu1.name,"chenlichen");
strcpy(stu1.addr,"福州");
//方法一:利用if-else的方法比较两个同学的成绩
if(stu1.score < stu2.score)
{
printf("成绩比较好的是:\n");
printf("学号:%d,年龄:%d,分数:%lf,名字:%s,地址:%s\n",
stu2.num,stu2.age,stu2.score,stu2.name,stu2.addr);
}
else
{
printf("成绩比较好的是:\n");
printf("学号:%d,年龄:%d,分数:%lf,名字:%s,地址:%s\n",
stu1.num,stu1.age,stu1.score,stu1.name,stu1.addr);
}
return 0;
}
方法二:利用max变量进行程序优化
/*题目:输入两个学生的名字,学号,成绩,输出成绩高的学生的信息*/
#include "stdio.h"
#include "string.h"
struct Student
{
int num;
char name[32];
char sex;
int age;
double score;
char addr[32];
};
int main()
{
int a;
struct Student stu1;
struct Student stu2 ={2,"张三",'g',17,99.5,"北京"};
struct Student max;//定义一个变量存放最大成绩
a = 10;
stu1.num = 1;
stu1.age = 10;
stu1.score = 98.5;
strcpy(stu1.name,"chenlichen");
strcpy(stu1.addr,"福州");
max = stu1;//比较之前默认等于stu1
if(stu1.score < stu2.score)
{
max = stu2;//如果stu2大于stu1改变输出时候的变量
}
printf("成绩比较好的是:\n");
printf("学号:%d,年龄:%d,分数:%lf,名字:%s,地址:%s\n",
max.num,max.age,max.score,max.name,max.addr);//输出时候用max替代变量
return 0;
}
1.4结构体和数组的结合
int arr [3] = {1,2,3}; //普通定义3个整形函数
前面说过int就相当于struct Student
struct Student arr2[3] = {
{2,"张三",'g',17,99.5,"北京"},
{3,"李四",'m',18,89.2,"上海"},
{4,"王五",'f',19,100,"内蒙"}
};每一项都是结构体可以不同的类型
下面进行结构体数组的遍历输出
#include "stdio.h"
#include "string.h"
//结构体
struct Student
{
int num;
char name[32];
char sex;
int age;
double score;
char addr[32];
};
int main()
{
int arr[3] = {1,2,3};
int len; //存放计算数组的长度的值
int i;
struct Student arr2[3] = {
{2,"张三",'g',17,99.5,"北京"},
{3,"李四",'m',18,89.2,"上海"},
{4,"王五",'f',19,100,"内蒙"}
};//定义一个结构体数组
len = sizeof(arr2)/sizeof(arr2[0]);//计算数组长度
for(i=0;i<len;i++)//遍历访问数组
{
printf("学号:%d,年龄:%d,分数:%lf,名字:%s,地址:%s\n",
arr2[i].num,arr2[i].age,arr2[i].score,arr2[i].name,arr2[i].addr);
}
return 0;
}
1.5结构体数组应用之选票系统
1.定义结构体初始化选民信息
2.唱票环节
3.公布结果
4.加入没有此人弃票的提示,查找票数最高的,计算废票
1.定义结构体初始化选民信息
#include "stdio.h"
struct Xuanmin
{
char name[32];
int tickets;
};
int main()
{
struct Xuanmin xm[3];
int len;
int i = 0;
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);
}
return 0;
}
2.唱票环节
memset说明:
函数原型: void* memset(void* mem_loc, int c, size_t n);
参数说明:
第一个参数void* mem_loc:已开辟内存空间的首地址,通常为数组名或指针,由于其为void*,故函数能为任何类型的数据进行初始化。
第二个参数int c:初始化使用的内容,取器低字节部分。
第三个参数size_t n:需要初始化的字节数。
函数功能: 将已开辟内存空间 mem_loc 的首 n 个字节的值设为值 c。
memset(tmpName,'\0',sizeof(tmpName));
strcmp比较两个字符串的大小,一个字符一个字符比较,按ASCLL码比较
标准规定:
第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字
if(strcmp(tmpName,xm[j].name) == 0)
代码:
#include "stdio.h"
#include "string.h"
struct Xuanmin
{
char name[32];
int tickets;
};
int main()
{
struct Xuanmin xm[3];
int len;
int i = 0;
int j = 0;
char tmpName[32];
//初始化选民信息
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++)
{
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++;
}
}
}
3. 公布结果
#include "stdio.h"
#include "string.h"
struct Xuanmin
{
char name[32];
int tickets;
};
int main()
{
struct Xuanmin xm[3];
int len;
int i = 0;
int j = 0;
char tmpName[32];
//初始化选民信息
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++)
{
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++;
}
}
}
//公布结果
for(i=0;i<len;i++){
printf("名字:%s票数:%d\n",xm[i].name,xm[i].tickets);
}
return 0;
}
4.加入没有此人弃票的提示,查找票数最高的,计算废票
#include "stdio.h"
#include "string.h"
struct Xuanmin
{
char name[32];
int tickets;
};
int main()
{
struct Xuanmin xm[3];
struct Xuanmin max;
int len;
int i = 0;
int j = 0;
int mark = 0;
char tmpName[32];
int feipiao = 0;
//初始化选民信息
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(tmpName,'\0',sizeof(tmpName));
scanf("%s",tmpName);
for(j=0;j<len;j++){
if(strcmp(tmpName,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=i;i<len;i++){
if(max.tickets < xm[i].tickets){
max = xm[i];
}
}
printf("%s以%d票当选!!!废票是%d\n",max.name,max.tickets,feipiao);
return 0;
}
1.6结构体指针变量的引入
回忆:指针就是地址
指针变量就是存放地址的变量
结构体也是变量
变量访问有两方式1.变量名 2.地址之前案例,是用变量名访问
通过结构体变量地址来访问该结构体需要一个变量来保持这个地址:这和之前说的指针,其实是一样的只是指针类型是结构体
普通的定义:
int a = 10;
int *p = &a;
char c = 'c';
char *pc = &c;
结构体:
struct Test t1 = {10,'c'};//1.类型 2.名字 3.值 4.地址
struct Test *ps = &t1;
1.7通过结构体指针来访问结构体内容
变量名访问用.运算符 t1.data
利用指针间接访问结构体变量用-> ps->data
通过指针的间接访问将cdata修改为R输出
#include "stdio.h"
struct Test
{
int idata;
char cdata;
};
int main()
{
struct Test t1 = {10,'c'};//1.类型 2.名 3.值 4.地址
struct Test *ps = &t1;
printf("t1的idata=%d\n",t1.idata);//变量名访问,用点运算符
printf("t1的idata=%d\n",ps->idata);//变量名访问,用"->"运算符
ps->cdata = 'R';
printf("t1的cdata=%c\n",t1.cdata);//变量名访问,用点运算符
printf("t1的cdata=%c\n",ps->cdata);//变量名访问,用"->"运算符
return 0;
}
1.8结构体指针应用01
利用结构体指针遍历数组,p = arr2记得返回
#include "stdio.h"
#include "string.h"
//结构体
struct Student
{
int num;
char name[32];
char sex;
int age;
double score;
char addr[32];
};
int main()
{
int len; //存放计算数组的长度的值
int i;
struct Student arr2[3] = {
{2,"张三",'g',17,99.5,"北京"},
{3,"李四",'m',18,89.2,"上海"},
{4,"王五",'f',19,100,"内蒙"}
};//定义一个结构体数组
struct Student *p;
p = arr2;
len = sizeof(arr2)/sizeof(arr2[0]);//计算数组长度
for(i=0;i<len;i++)//遍历访问数组
{
printf("学号:%d,年龄:%d,分数:%lf,名字:%s,地址:%s\n",
p->num,p->age,p->score,p->name,p->addr);
p++;
}
p = arr2;
for(i=0;i<len;i++)//遍历访问数组
{
printf("学号:%d,年龄:%d,分数:%lf,名字:%s,地址:%s\n",
p->num,p->age,p->score,p->name,p->addr);
p++;
}
return 0;
}
1.9结构体指针应用02之改写选票系统
把以前的普通变量名,或者下标访问的.运算符,改成结构体指针的->
指针++,每次遍历会到数组尾巴,下次遍历之前记得回来(重新指数组头)!
#include "stdio.h"
#include "string.h"
struct Xuanmin
{
char name[32];
int tickets;
};
/*
1.把以前的普通变量名,或者下标访问的.运算符,改成结构体指针的->
2.指针++,每次遍历会到数组尾巴,下次遍历之前记得回来(重新指数组头)!
*/
int main()
{
struct Xuanmin xm[3];
struct Xuanmin max;
struct Xuanmin *p = xm;
int len;
int i = 0;
int j = 0;
int mark = 0;
char tmpName[32];
int feipiao = 0;
//初始化选民信息
len = sizeof(xm)/sizeof(xm[0]);
for(i=0;i<len;i++)
{
p->tickets = 0;
printf("请输入第%d个选民的名字\n",i+1);
scanf("%s",p->name);
p++;
}
//唱票环节
for(i=0;i<5;i++)
{
mark = 0;
printf("请输入你投给谁:\n");
memset(tmpName,'\0',sizeof(tmpName));
scanf("%s",tmpName);
p = xm;
for(j=0;j<len;j++){
if(strcmp(tmpName,p->name) == 0){
p->tickets++;
mark = 1;
}
p++;
}
if(mark == 0){
printf("没有此候选人,放弃!\n");
feipiao++;
}
}
p = xm;
//公布结果
for(i=0;i<len;i++){
printf("名字:%s票数:%d\n",p->name,p->tickets);
p++;
}
max = xm[0];
for(i=i;i<len;i++){
if(max.tickets < p->tickets){
max = xm[i];
}
p++;
}
printf("%s以%d票当选!!!废票是%d\n",max.name,max.tickets,feipiao);
return 0;
}
1.10结构体指针函数综合应用改写选票系统
利用结构体的指针、结构体的函数、结构体的数组综合应用
#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 n;
int i;
if(p == NULL)
{
printf("请输入有几个人参选:\n");
scanf("%d",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 feipiao = 0;
int mark;
char tmpName[32];
struct XuanMin *pbak = p;
for(i=0;i<5;i++)
{
mark = 0;
printf("请输入你投给谁:\n");
memset(tmpName,'\0',sizeof(tmpName));
scanf("%s",tmpName);
p = pbak;
for(j=0;j<len;j++){
if(strcmp(tmpName,p->name) == 0){
p->tickets++;
mark = 1;
}
p++;
}
if(mark == 0){
printf("没有此候选人,放弃!\n");
feipiao++;
}
}
return feipiao;
}
/*
1.把以前的普通变量名,或者下标访问的.运算符,改成结构体指针的->
2.指针++,每次遍历会到数组尾巴,下次遍历之前记得回来(重新指数组头)!
*/
struct XuanMin* getMax(struct XuanMin *p,int len)
{
struct XuanMin* max;
int i;
max = p;
for(i=i;i<len;i++){
if(max->tickets < p->tickets){
max = p;
}
p++;
}
return max;
}
int main()
{
struct XuanMin *xm = NULL;
struct XuanMin *final;
int total = 0;
xm = initXms(xm,&total);
printXms(xm,total);
int feip = doVot(xm,total);
printf("废票数是:%d\n",feip);
printXms(xm,total);
final = getMax(xm,total);
printf("%s以%d票当选!!!废票是%d\n",final->name,final->tickets,feip);
return 0;
}
1.11结构体二级指针
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct XuanMin
{
char name[32];
int tickets;
};
void initXms(struct XuanMin **pxm,int *pt)
{
int i;
//*pt = 0;
//*pxm = NULL;
if(*pxm == NULL){
printf("请输入有几个人参选:\n");
scanf("%d",pt);
printf("一共%d个人参选\n",*pt);
*pxm = (struct XuanMin*)malloc(*pt * sizeof(struct XuanMin));
}
for(i=0;i<*pt;i++){
(*pxm)->tickets == 0;
printf("请输入第%d个选民的名字:\n",i+1);
scanf("%s",(*pxm)->name);
(*pxm)++;
}
*pxm = *pxm - *pt;
}
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 feiPiao = 0;
int mark;
char tmpName[32];
struct XuanMin *pbak = p;
for(i=0;i<5;i++){
mark = 0;
printf("请输入你投给谁:\n");
memset(tmpName,'\0',sizeof(tmpName)); //每次清空一下
scanf("%s",tmpName);//输入选中的选民名字,像拆开一个选票,看到名字一样
p = pbak;
for(j = 0;j<len; j++){ //拿到名字,对应候选人票数加1
if(strcmp(tmpName, 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 *final;
int total = 0;
initXms(&xm,&total);
printXms(xm,total);
int feip = doVot(xm,total);
printf("废票数是:%d\n",feip);
printXms(xm,total);
final = getMax(xm,total);
printf("%s以%d票当选!!废票是%d\n",final->name,final->tickets,feip);
return 0;
}
1.12联合体共用体概念引入
共用体/联合体 union
1.结构体元素有各自单独空间 共用体元素共享空间,空间大小由最大类型确定
2.结构体元素互不影响 共用体赋值会导致覆盖
1.查看结构体和公共体的大小
#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("结构体t1的大小是:%d\n",sizeof(t1));
printf("联合体u1的大小是:%d\n",sizeof(u1));
return 0;
}
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("结构体t1的大小是:%d\n",sizeof(t1));
printf("联合体u1的大小是:%d\n",sizeof(u1));
printf("idata:%p\n",&t1.idata);
printf("cdata:%p\n",&t1.cdata);
printf("ddata:%p\n",&t1.ddata);
printf("idata:%p\n",&u1.idata);
printf("cdata:%p\n",&u1.cdata);
printf("ddata:%p\n",&u1.ddata);
return 0;
}
1.13共用体注意数据覆盖的问题
#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("结构体t1的大小是:%d\n",sizeof(t1));
printf("联合体u1的大小是:%d\n",sizeof(u1));
t1.idata = 10;
t1.cdata = 'a';
t1.ddata = 20;
printf("idata:%p\n",&t1.idata);
printf("cdata:%p\n",&t1.cdata);
printf("ddata:%p\n",&t1.ddata);
u1.idata = 10;
u1.ddata = 20;
u1.cdata = 'a';
printf("idata = %d\n",u1.idata);
printf("idata:%p\n",&u1.idata);
printf("cdata:%p\n",&u1.cdata);
printf("ddata:%p\n",&u1.ddata);
return 0;
}
1.14共用体开发案例
例:有若干个人员的数据,其中有学生和教师。学生的数据中包括,姓名,号码、性别、职业、班级、教师的数据包括:姓名、号码、性别、职业、职务。要求用同一个表格处理。
这里有的用到了&地址有的没有是因为:字符串的赋值不用&
#include "stdio.h"
struct Person{
char name[32];
int age;
char zhiYe;
char addr[32];
union D{
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("学生的名字是:%s,班级是:%d\n",p[i].name,p[i].mes.class);
}
else{
printf("老师的名字是:%s,科目是:%s",p[i].name,p[i].mes.keMu);
}
}
return 0;
}
1.15枚举类型介绍
枚举:neum
什么是枚举? 如果一个变量只有几种可能的值,比如星期几
怎么定义枚举类型? 列表中的名字,可以自己定义,无需像变量一样去申请
定义:enum WeekDay{sun,mon,tus,wed,thr,fri,sat};
#include "stdio.h"
enum WeekDay{sun,mon,tus,wed,thr,fri,sat};
int main()
{
enum WeekDay w;
w = sun;
printf("w = %d\n",w);
return 0;
}
1.16typedef关键字介绍
typedef:给已有的变量类型起名字
#include "stdio.h"
typedef int zhengshu;
typedef char zifu;
typedef double xiaoshu;
int main()
{
zhengshu a = 10;
printf("%d\n",a);
zifu c = 'c';
printf("c=%c\n",c);
return 0;
}
1.17typedef和结构体案例
#include "stdio.h"
typedef struct{
int num;
char name[32];
int sex;
}Person,*pPerson;
void print(Person p)
{
printf("%d号姐姐:%s %c\n",p.num,p.name,p.sex);
}
void print2(pPerson pp)
{
printf("%d号姐姐:%s %c\n",pp->num,pp->name,pp->sex);
}
int main()
{
Person p1 = {1,"丽丽",'g'};
Person p2 = {2,"妹妹",'g'};
print(p1);
print(p2);
pPerson pp1 = &p1;
pPerson pp2 = &p2;
print2(pp1);
print2(pp2);
return 0;
}