1.什么是结构体
C语言结构体是一种用户自定义的数据类型,它允许你将不同类型的数据项组合在一起,形成一个新的复合类型。结构体可以包含多个成员变量,每个成员可以是不同的数据类型,如整型、浮点型、字符型、数组等。
结构体的定义使用关键字"struct",后面跟着结构体的名称,然后是结构体的成员列表,成员列表由成员类型和成员名称组成,多个成员之间使用逗号分隔,在结构体末尾需要加上分号。
struct Person {
char name[20];
int age;
float height;
};
在上面的示例中,我们定义了一个名为Person的结构体,它包含三个成员变量:一个字符数组name,一个整型变量age,一个浮点型变量height。
2.为什么要用结构体
1.整型数,浮点型,字符串是分散的数据表示有时候我们需要用很多类型数据表示一个整体,比如学生信息。
2.类比于数组:数组是元素类型一样的数据集合,如何是元素类型不同的数据集合,就要用到结构体了
3.定义一个结构体
它算是一个模版,一般不给赋值,每一项在实际应用中并不是都要使用。
结构体示意图如下:
结构体示例代码如下
#include <stdio.h>
/\*
时间: 2023年7月9日16:58:37
程序功能:定义一个结构体
\*/
struct Student //
{
int mum;
char name[32];
char sex;
int age;
double score;
char addr[32];
};
struct Day
{
int year;
int month;
int day;
};
struct Voter
{
char name[32];
int tickets;
};
int main()
{
return 0;
}
4.什么是成员列表
1.结构体成员列表指的是在结构体定义中,用于描述结构体包含的各个成员的部分。它由结构体的成员类型和成员名称组成,多个成员之间使用逗号进行分隔。
2.在C语言中,每个结构体成员都有其类型和名称。类型可以是基本数据类型(如整型、浮点型、字符型等),也可以是其他结构体类型、指针类型等。名称是用来标识该成员的唯一标识符。
3.示例代码
struct Person {
char name[20]; // 成员1:字符数组类型的name
int age; // 成员2:整型类型的age
float height; // 成员3:浮点型类型的height
};
4.成员列表也称域表,每个成员都是结构体的一个域。
5.特殊定义方式之在声明的同时,定义变量,尽量少用
struct Student
{
char name[32];
int age;
int StudentID;
char sex[32];
},Student1,Student2; //Student1,Student2 就是在定义变量
6.初始化一个结构体变量并引用
1.初始化
struct Student stu2 = {"李白",99,1024,"男"};
2.引用
scanf("%s",&stu1.name); //点运算符用来访问结构体的成员变量(域) 字符串可以输入汉字
7.重点知识
结构体没什么特殊的,只是把变量藏在结构体里面,而内部的变量,以前学习的东西是通用的,只是“触达的方式”不同。
8.例题:输入两个学生的名字,学号,成绩,输出成绩高的学生的信息
#include <stdio.h>
/\*
时间: 2023年7月9日23:00:54
程序功能:例题:输入两个学生的名字,学号,成绩,输出成绩高的学生的信息
\*/
struct Student
{
char name[32];
int age;
int StudentID;
double score;
char sex[32];
};
struct Student stu1;
struct Student stu2;
struct Student max;
void initStuct()
{
puts("请输入第一个学生的信息\n");
puts("姓名");
scanf("%s",&stu1.name);
puts("年龄");
scanf("%d",&stu1.age);
puts("学号");
scanf("%d",&stu1.StudentID);
puts("成绩");
scanf("%lf",&stu1.score);
puts("性别");
scanf("%s",&stu1.sex);
puts("请输入第二个学生的信息\n");
puts("姓名");
scanf("%s",&stu2.name);
puts("年龄");
scanf("%d",&stu2.age);
puts("学号");
scanf("%d",&stu2.StudentID);
puts("成绩");
scanf("%lf",&stu2.score);
puts("性别");
scanf("%s",&stu2.sex);
}
void compare()
{
if(stu1.score > stu2.score)
{
max = stu1;
}else
{
max = stu2;
}
}
void outPut()
{
printf("姓名\t年龄\t学号\t成绩\t性别 \n");
printf("%s\t%d\t%d\t%.2lf\t%s\t \n",
max.name,max.age,max.StudentID,max.score,max.sex);
}
void introduce()
{
puts("程序功能:例题:输入两个学生的名字,学号,成绩,输出成绩高的学生的信息");
}
int main()
{
char yesOrNoc;
introduce();
do
{
initStuct();
compare();
outPut();
puts("是否继续判断 y/n");
getchar();
scanf("%c",&yesOrNoc);
}while(yesOrNoc=='y' || yesOrNoc=='Y');
puts("程序退出!!!");
return 0;
}
2.结构体数组
1.什么是结构体数组
1.C语言结构体数组是一种由结构体元素组成的数组。它允许你在同一个数组中存储多个结构体对象,并且每个对象都包含了多个成员变量。
2.结构体数组的定义方式与普通数组类似,只是需要在数组元素的类型上加上结构体的定义。例如,假设有一个表示人员信息的结构体Person,包含成员变量name和age,那么可以定义一个存储多个人员信息的结构体数组如下:
struct Person {
char name[20];
int age;
};
struct Person people[5]; // 定义一个包含5个Person结构体元素的数组
上述代码中,我们定义了一个名为people的结构体数组,该数组的元素类型为struct Person,并且数组的大小为5,即可以存储5个人的信息。
3.结构体数组的元素可以通过索引来访问和修改,索引从0开始计数,例如:
people[0].age = 25; // 对数组中的第一个结构体元素的age成员进行赋值
people[1].age = 30; // 对数组中的第二个结构体元素的age成员进行赋值
你还可以使用循环语句来遍历整个结构体数组,访问或修改每个结构体元素的成员变量。
4.通过结构体数组,你可以方便地存储和处理多个结构体对象,例如存储学生信息、员工信息等。它在C语言中提供了一种灵活的方式来组织和处理结构化的数据。
2.结构体数组输入
int i;
for(i=0; i<3; i++)
{
printf("请输入第%d个同学的信息\n",i+1);
puts("姓名:");
scanf("%s",&arr[i].name);
puts("年龄:");
scanf("%d",&arr[i].age);
puts("学号:");
scanf("%d",&arr[i].StudentID);
puts("成绩:");
scanf("%lf",&arr[i].score);
puts("性别:");
scanf("%s",&arr[i].sex);
}
3.结构体数组输出
int i;
for(i=0; i<3; i++)
{
printf("%s\t%d\t%d\t%0.2lf\t%s \n",
arr[i].name,arr[i].age,arr[i].StudentID,arr[i].score,arr[i].sex);
}
4.结构体数组完成输入输出
#include <stdio.h>
/\*
时间: 2023年7月10日14:44:56
程序功能:结构体数组
\*/
struct Student
{
char name[32];
int age;
int StudentID;
double score;
char sex[32];
};
struct Student arr[3]; //定义一个结构体数组
void initStruct()
{
int i;
puts("开始输入程序!!!\n");
for(i=0; i<3; i++)
{
printf("请输入第%d个同学的信息\n",i+1);
puts("姓名:");
scanf("%s",&arr[i].name);
puts("年龄:");
scanf("%d",&arr[i].age);
puts("学号:");
scanf("%d",&arr[i].StudentID);
puts("成绩:");
scanf("%lf",&arr[i].score);
puts("性别:");
scanf("%s",&arr[i].sex);
}
}
void outputStruct()
{
int i;
puts("开始输出程序!!!\n");
printf("姓名\t年龄\t学号\t成绩\t性别 \n");
for(i=0; i<3; i++)
{
printf("%s\t%d\t%d\t%0.2lf\t%s \n",
arr[i].name,arr[i].age,arr[i].StudentID,arr[i].score,arr[i].sex);
}
}
int main()
{
char yesOrNoC;
puts("程序功能:结构体数组\n\n");
puts("struct Student arr[3]; //定义一个结构体数组\n\n");
do
{
initStruct();
outputStruct();
getchar();
puts("是否继续输入输出 y/n");
scanf("%c",&yesOrNoC);
}while(yesOrNoC=='Y' || yesOrNoC=='y');
puts("程序结束!!!");
return 0;
}
5.结构体数组应用——选票系统
1.选票系统主要功能为:
第一步登记候选人姓名——第二步进行投票和唱票环节——第三步公布选票结果。
2.判断最高得票数同票算法
代码如下:
if(xm[0].tickets == xm[1].tickets && xm[1].tickets > xm[2].tickets)
{
printf("候选人%s和%s是最大得票数相同,此次选举失效,下次选举请听通知!!!\n",
xm[0].name,xm[1].name);
return 0;
}else if(xm[1].tickets == xm[2].tickets && xm[2].tickets > xm[0].tickets)
{
printf("候选人%s和%s是最大得票数相同,此次选举失效,下次选举请听通知!!!\n",
xm[1].name,xm[2].name);
return 0;
}else if(xm[0].tickets == xm[2].tickets && xm[2].tickets > xm[1].tickets)
{
printf("候选人%s和%s是最大得票数相同,此次选举失效,下次选举请听通知!!!\n",
xm[0].name,xm[2].name);
return 0;
}else
{
printf("%s以%d票当选!!废票%d\n",max.name,max.tickets,wasteTickets);
}
3.结构体指针
1.什么是结构体指针
1.C语言结构体指针是指向结构体的指针变量。它可以用于访问和操作结构体的成员变量,而不需要使用结构体变量本身。
2.结构体指针的定义方式和普通指针类似,只是需要在指针变量的类型上加上结构体的名称。例如,假设有一个表示人员信息的结构体Person,包含成员变量name和age,那么可以定义一个指向该结构体的指针如下:
struct Person {
char name[20];
int age;
};
struct Person person1;
struct Person \*personPtr; // 定义一个指向Person结构体的指针变量
上述代码中,我们定义了一个名为personPtr的指针变量,它的类型是struct Person ,表示一个指向Person结构体的指针。
3.通过结构体指针,可以通过两种方式来访问和操作结构体的成员变量:
1.使用->操作符:结构体指针和成员变量之间使用->操作符来访问成员变量。例如:personPtr->age,表示访问指针personPtr所指向的结构体的age成员变量。
2.使用( )操作符:可以先通过指针解引用得到结构体对象,然后再使用.操作符来访问成员变量。例如:(*personPtr).age,表示访问指针personPtr所指向的结构体的age成员变量。
4.下面是一个示例,展示如何使用结构体指针来访问和修改结构体的成员变量:
struct Person {
char name[20];
int age;
};
struct Person person1;
struct Person \*personPtr; // 定义一个指向Person结构体的指针变量
personPtr = &person1; // 将指针变量指向某个结构体对象
(\*personPtr).age = 25; // 使用指针解引用,然后通过`.`操作符访问成员变量
personPtr->age = 25; // 使用指针和`->`操作符访问成员变量
5.通过结构体指针,你可以更灵活地操作结构体对象,特别是在函数传参或动态内存分配等场景下。它允许你直接访问和修改结构体的成员变量,而无需创建额外的结构体变量。
2.知识回顾
1.指针就是地址;指针变量就是存放地址的变量
2.结构体也是变量。
3.变量访问有两种方式:1.变量名 2.地址
4通过结构体变量地址来访问该结构体需要一个变量来保存这个地址:这和之前说的指针,其实是一样的只是指针类型是结构体。
5.知识回顾代码
#include <stdio.h>
/\*
时间: 2023年7月10日23:26:28
程序功能:初识结构体指针
\*/
struct pointer //定义一个名为指针的结构体
{
int data;
char cdata;
};
int main()
{
//变量的4要素:1、名 2、值 3、类型 4、地址
int a = 10; //定义一个整型变量a = 10
int \*p = &a; //定义一个整型指针变量指向整型变量a
char c = 'a'; //定义一个字符型变量c = 'a';
char \*pc = &c; //定义一个字符型指针变量指向字符型变量c
struct pointer data; //定义一个名为指针的结构体变量data
struct pointer \*pdata = &data; //定义一个名为指针的结构体指针变量pdata指向
//名为指针的结构体变量data
return 0;
}
3.通过结构体指针来访问结构体
以下代码是通过结构体指针来访问结构体示例
#include <stdio.h>
/\*
时间: 2023年7月11日00:10:18
程序功能:通过结构体指针来访问结构体
\*/
struct pointer //定义一个名为指针的结构体
{
int idata;
char cdata;
};
void introduce()
{
puts("程序功能:通过结构体指针来访问结构体\n\n");
puts("struct pointer //定义一个名为指针的结构体\n");
puts("struct pointer data = {10,'c'}; //定义一个名为指针的结构体变量data = {10,'c'};\n");
puts("struct pointer \*pdata = &data; //定义一个名为指针的结构体指针变量pdata指向");
puts("//名为指针的结构体变量data\n");
puts("printf(“data的idata = %d\n”,data.idata); //变量名访问,用点运算符\n");
puts("printf(“data的idata = %d\n”,pdata->idata); //指针变量名访问,用“->”运算符\n");
puts("pdata->cdata = 'R'; //通过结构体指针变量来修改结构体中cdata的值\n\n");
}
int main()
{
//变量的4要素:1、名 2、值 3、类型 4、地址
int a = 10; //定义一个整型变量a = 10
int \*p = &a; //定义一个整型指针变量指向整型变量a
char c = 'a'; //定义一个字符型变量c = 'a';
char \*pc = &c; //定义一个字符型指针变量指向字符型变量c
introduce();
struct pointer data = {10,'c'}; //定义一个名为指针的结构体变量data = {10,'c'};
struct pointer \*pdata = &data; //定义一个名为指针的结构体指针变量pdata指向
//名为指针的结构体变量data
printf("data的idata = %d\n",data.idata); //变量名访问,用点运算符
printf("data的idata = %d\n",pdata->idata); //指针变量名访问,用“->”运算符
pdata->cdata = 'R'; //通过结构体指针变量来修改结构体中cdata的值
printf("data的cdata = %c\n",data.cdata); //变量名访问,用点运算符
printf("data的cdata = %c\n",pdata->cdata); //指针变量名访问,用“->”运算符
return 0;
}
4.结构体指针应用1——输入输出人员信息
1.程序功能:
第一步输入人员信息——第二步输出人员信息
2.程序代码:
#include <stdio.h>
/\*
时间: 2023年7月11日21:55:16
程序功能:结构体指针练习
\*/
struct Test
{
char name[32];
int age;
char sex[32];
};
struct Test arr[3];
void initTest()
{
struct Test \*p; //结构体指针变量p不能定义成为全局结构体指针变量,定义后会报错。
p = arr; //结构体指针变量p指向全局结构体数组变量arr
puts("第一步输入人员信息\n\n");
int i;
for(i=0; i<3; i++)
{
printf("请输入第%d个人的信息。\n",i+1);
puts("姓名:");
scanf("%s",&p->name); //结构体指针变量用于scanf输入函数时要加‘&’符号,
puts("年龄:");
scanf("%d",&p->age); //不然会出现段错误
puts("性别:");
scanf("%s",&p->sex);
p++; //指针偏移应用在后面,不能用在scanf printf函数内,
//不然会出现偏移后输出结果错误。
}
}
void outputTest()
{
struct Test \*p;
p = arr;
puts("第二步输出人员信息\n\n");
int i;
puts("姓名\t年龄\t性别 ");
for(i=0; i<3; i++)
{
printf("%s\t%d\t%s \n",
p->name,p->age,p->sex);
p++;
}
}
void introduce()
{
puts("程序功能:结构体指针练习\n\n");
puts("struct Test \*p; //结构体指针变量p不能定义成为全局结构体指针变量,定义后会报错。\n");
puts("p = arr; //结构体指针变量p指向全局结构体数组变量arr\n");
puts("scanf(“%s”,&p->name); //结构体指针变量用于scanf输入函数时要加‘&’符号,");
puts("scanf(“%d”,&p->age); //不然会出现段错误\n");
puts("p++; //指针偏移应用在后面,不能用在scanf printf函数内,");
puts(" //不然会出现偏移后输出结果错误。\n\n");
}
int main()
{
char yesOrNoC;
introduce();
do
{
initTest();
outputTest();
puts("是否继续程序!y/n");
getchar();
scanf("%c",&yesOrNoC);
}while(yesOrNoC=='y' || yesOrNoC=='Y');
puts("程序退出!!!");
return 0;
}
5.结构体指针应用2——改写选票系统
程序代码如下:
#include <stdio.h>
#include <string.h>
/\*
时间: 2023年7月12日00:26:53
程序功能:结构体指针应用2\_改写选票系统
\*/
struct Voter //定义一个选票结构体
{
char name[32];
int tickets;
};
struct Voter xm[3];//定义一个选票结构体数组变量xm[3]
struct Voter max; //定义一个选票结构体变量max
int len; //数组长度变量
int wasteTickets = 0; //废票变量
void initVoter() //初识化选票,输入每个候选人的名字
{
int i;
struct Voter \*p = xm;
puts("第一步登记候选人姓名。\n\n");
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++;
}
}
void singTickets() //唱票
{
char tmpName[32];
int i;
int j;
int person;
int mark; //废票判断变量
struct Voter \*p = xm;
puts("第二步进行投票和唱票环节。\n\n");
puts("请输入参与投票的人数。");
scanf("%d",&person);
for(i=0; i<person; i++)
{
mark = 0; //mark不能在定义时赋值0,如果赋值0,后面的废票判别永远不会执行
memset(tmpName,'\0',sizeof(tmpName));
puts("请输入你支持谁。");
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) //废票判断
{
puts("候选人无此人,选票无效");
wasteTickets++;
}
}
}
int ticketsResult() //选票结果
{
int i;
struct Voter \*p = xm;
puts("第三步公布选票结果。\n\n");
puts("姓名\t得票数\t");
for(i=0; i<len; i++)
{
printf("%s\t%d \n",p->name,p->tickets);
p++;
}
p = xm;
max = xm[0];
for(i=1; i<len; i++)
{
p++;
if(max.tickets<p->tickets)
{
max = xm[i]; //把xm[i]结构体赋给max结构体,实现替代关系
}
}
if(xm[0].tickets == xm[1].tickets && xm[1].tickets > xm[2].tickets)
{
printf("候选人%s和%s是最大得票数相同,此次选举失效,下次选举请听通知!!!\n",
xm[0].name,xm[1].name);
return 0;
}else if(xm[1].tickets == xm[2].tickets && xm[2].tickets > xm[0].tickets)
{
printf("候选人%s和%s是最大得票数相同,此次选举失效,下次选举请听通知!!!\n",
xm[1].name,xm[2].name);
return 0;
}else if(xm[0].tickets == xm[2].tickets && xm[2].tickets > xm[1].tickets)
{
printf("候选人%s和%s是最大得票数相同,此次选举失效,下次选举请听通知!!!\n",
xm[0].name,xm[2].name);
return 0;
}else
{
printf("%s以%d票当选!!废票%d\n",max.name,max.tickets,wasteTickets);
}
return 0;
}
void introduce()
{
puts("程序功能:结构体指针应用2\_改写选票系统\n\n");
puts("1.把以前的普通变量名,或者下标访问的.运算符,改成结构体指针的->\n");
puts("2.指针++,每次遍历会到数组尾巴,下次遍历之前记得回来(重新指向数组首地址)");
puts("但在单独的函数中单独定义结构体指针变量,有些时候不用回到数组首地址。\n\n");
}
int main()
{
char yesOrNoC;
int empty; //定义一个空变量用于承接选票结果函数返回值。
introduce();
do
{
initVoter();
singTickets();
empty = ticketsResult();
puts("是否继续选举?y/n");
getchar();
scanf("%c",&yesOrNoC);
}while(yesOrNoC=='y' || yesOrNoC=='Y');
puts("程序结束!!!");
return 0;
}
/\*
补充知识:
for(i=0; i<len+1; i++)
{
if(xm[i].tickets == xm[i+1].tickets) //当xm[i]>xm[2]时,超出定义的结构体数组元素个数
//系统会为超出的元素变量xm[i]赋0。因此,判断时
//其实没有对前面有效结构体数组元素进行判断,只
//是为后面的无效元素系统赋0后进行判断。此逻辑
//算法可以全覆盖判断最大票数值相同的情况。但认
//真看此算法不严谨,并未判断出有效结构体数组元
//素谁和谁相同。
{
puts("候选人最大得票数相同,此次选举失效,下次选举请听通知!!!");
return 0;
}
}
\*/
6.结构体指针,函数,数组综合应用1——选民系统
1.课程代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/\*
时间: 2023年7月13日20:21:32
程序功能:结构体指针数组函数综合应用改写选票系统
\*/
struct Voter //定义一个选票结构体
{
char name[32];
int tickets;
};
struct Voter\* initVoter(struct Voter \*p,int \*pn)
{
int i;
if(p == NULL)
{
puts("请输入有几个候选人。");
scanf("%d",pn);
p = (struct Voter\*)malloc(\*pn\*sizeof(struct Voter));
}
for(i=0; i<\*pn; i++)
{
p->tickets = 0;
printf("请输入第%d个候选人的名字。\n",i+1);
scanf("%s",&p->name);
p++;
}
return p-\*pn;
}
void outputVoter(struct Voter \*p,int len)
{
int i;
puts("姓名\t得票数\t");
for(i=0; i<len; i++)
{
printf("%s\t%d \n",p->name,p->tickets);
p++;
}
}
int singTickets(struct Voter \*p,int len)
{
char tmpName[32];
int i;
int j;
int person;
int mark; //废票判断变量
int wasteTickets = 0;
struct Voter \*pbak = p; //定义一个结构体指针变量pbak指向结构体指针p的首地址。
//puts("第二步进行投票和唱票环节。\n\n");
puts("请输入参与投票的人数。");
scanf("%d",&person);
for(i=0; i<person; i++)
{
mark = 0; //mark不能在定义时赋值0,如果赋值0,后面的废票判别永远不会执行
memset(tmpName,'\0',sizeof(tmpName));
puts("请输入你支持谁。");
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) //废票判断
{
puts("候选人无此人,选票无效");
wasteTickets++;
}
}
return wasteTickets;
}
struct Voter\* getMax(struct Voter \*p,int len)
{
int i;
struct Voter\* max;
max = p;
for(i=0; i<len; i++)
{
if(max->tickets<p->tickets)
{
max = p; //把xm[i]结构体赋给max结构体,实现替代关系
}
p++;
}
return max;
}
int main()
{
struct Voter \*xm = NULL;
struct Voter \*result;
int total = 0;
int wasteTickets;
xm = initVoter(xm,&total);
printf("total = %d\n",total);
wasteTickets = singTickets(xm,total);
outputVoter(xm,total);
printf("废票为%d\n",wasteTickets);
result = getMax(xm,total)
printf("%s以%d票当选!!废票%d\n",result->name,result->tickets,wasteTickets);
return 0;
}
2.自己实现代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/\*
时间: 2023年7月13日21:55:07
程序功能:结构体指针数组函数综合应用改写选票系统\_自己实现
\*/
struct Voter //定义一个选票结构体
{
char name[32];
int tickets;
};
struct Voter \*initVoter(struct Voter \*p, int \*pn)
{
int i;
getchar();
if(p == NULL)
{
puts("请输入候选人有几位。");
scanf("%d",pn);
p = (struct Voter\*)malloc(\*pn \* sizeof(struct Voter));//(struct Voter\*)将void型的
//malloc函数强制转换成struct Voter\*型
}
for(i=0; i<\*pn; i++)
{
p->tickets = 0;
printf("请输入第%d个候选人的名字。\n",i+1);
scanf("%s",p->name);
p++;
}
return p-\*pn; //回归到指针初始位置
}
int singTickets(struct Voter \*p,int len)
{
int i;
int j;
char tmpName[32];
int person;
int mark; //废票判断变量
int wasteTickets = 0;
struct Voter \*pbak = p; //定义一个结构体指针变量pbak指向形参结构体指针变量p的首地址
puts("请输入参见投票的人数");
scanf("%d",&person);
for(i=0; i<person; i++)
{
mark = 0;
memset(tmpName,'\n',sizeof(tmpName));
puts("你支持谁!");
scanf("%s",tmpName);
p = pbak; //每次进行外层循环时回归结构体指针变量p的首地址。
for(j=0; j<len; j++)
{
if(strcmp(p->name,tmpName)== 0)
{
p->tickets++;
mark = 1;
}
p++; //结构体指针变量p发生了偏移。
}
if(mark == 0)
{
puts("没有此候选人,本张选票报废");
wasteTickets++;
}
}
return wasteTickets;
}
struct Voter\* ticketsResult(struct Voter \*p,int len) //选票结果
{
int i;
int j;
int tmp;
struct Voter \*max; //定义一个结构体指针变量max指向形参结构体指针变量p的首地址
max = p;
for(i=0; i<len; i++)
{
if(max->tickets < p->tickets) //把max内的tickets与p内的tickets进行比较,若小于,则
{ //把当前p赋给max。
max = p;
}
p++;
}
return max;
}
void outputVoter(struct Voter \*p,int len)
{
int i;
puts("姓名\t得票数\t");
for(i=0; i<len; i++)
{
printf("%s\t%d \n",p->name,p->tickets);
p++;
}
}
int main()
{
struct Voter \*xm = NULL;
struct Voter \*result;
int total = 0;
int wasteTickets;
char yesOrNoC;
puts("程序功能:结构体指针数组函数综合应用改写选票系统\_自己实现\n\n");
puts("程序启动成功!按回车键开始运行。");
do
{
xm = NULL;
puts("第一步进行候选人信息登记\n");
xm = initVoter(xm,&total);
puts("第二步进行投票\n");
wasteTickets = singTickets(xm,total);
puts("第三步投票结果公示\n");
result = ticketsResult(xm,total);
outputVoter(xm,total);
printf("%s以%d票当选!!废票%d\n",result->name,result->tickets,wasteTickets);
puts("是否继续选举?y/n");
getchar();
scanf("%c",&yesOrNoC);
}while(yesOrNoC=='y' || yesOrNoC=='Y');
puts("程序退出!!!");
return 0;
}
/\*
if(max[0].tickets == max[1].tickets && max[1].tickets > max[2].tickets)
{
printf("候选人%s和%s是最大得票数相同,此次选举失效,下次选举请听通知!!!\n",
max[0].name,max[1].name);
exit(-1);
}else if(max[1].tickets == max[2].tickets && max[2].tickets > max[0].tickets)
{
printf("候选人%s和%s是最大得票数相同,此次选举失效,下次选举请听通知!!!\n",
max[1].name,max[2].name);
exit(-1);
}else if(max[0].tickets == max[2].tickets && max[2].tickets > max[1].tickets)
{
printf("候选人%s和%s是最大得票数相同,此次选举失效,下次选举请听通知!!!\n",
max[0].name,max[2].name);
exit(-1);
}
else
{
return max;
}
\*/
7.结构体指针,函数,数组综合应用2——结构体二级指针
1.什么是结构体二级指针
1.C语言结构体二级指针是指向结构体指针的指针。它可以用于指向存储结构体指针的变量,或者用于指向结构体指针数组的指针。
2.结构体二级指针的定义方式和普通指针的指针类似,只是需要在指针变量的类型前加上一个(芯)符号来表示二级指针。例如,假设有一个表示人员信息的结构体Person以及一个结构体指针struct Person 芯,那么可以定义一个指向该指针的二级指针如下:
struct Person {
char name[20];
int age;
};
struct Person \*personPtr; // 结构体指针
struct Person \*\*personPtrPtr; // 结构体二级指针
上述代码中,我们定义了一个名为personPtrPtr的结构体二级指针,它可以存储指向struct Person芯类型的指针变量的地址。
3.通过结构体二级指针,可以通过两次解引用操作来访问和操作结构体的成员变量。例如:
struct Person {
char name[20];
int age;
};
struct Person person1;
struct Person \*personPtr = &person1; // 结构体指针
struct Person \*\*personPtrPtr = &personPtr; // 结构体二级指针
(\*personPtrPtr)->age = 25; // 第一层解引用得到结构体指针,第二层解引用访问成员变量
在上述代码中,(芯personPtrPtr)->age 表示通过结构体二级指针 personPtrPtr,首先解引用得到结构体指针 personPtr,然后再解引用结构体指针 personPtr 来访问 age 成员变量。
4.结构体二级指针通常在需要修改指向指针的地址的情况下使用,例如在函数中通过指针参数修改结构体指针的内容或者创建动态的结构体指针数组。它提供了更灵活的方式来操作结构体指针和结构体指针数组。
2.用结构体二级指针完成选民系统
1.内存指向图
2.程序代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/\*
时间: 2023年7月14日22:57:08
程序功能:结构体二级指针
\*/
struct Voter //定义一个选票结构体
{
char name[32];
int tickets;
};
void initVoter(struct Voter \*\*pxm,int \*pn)
{
int i;
if(\*pxm == NULL)
{
puts("请输入有几个候选人。");
scanf("%d",pn);
\*pxm = (struct Voter\*)malloc(\*pn \* sizeof(struct Voter));
}
for(i=0; i<\*pn; i++)
{
(\*pxm)->tickets = 0;
printf("请输入第%d个候选人的名字。\n",i+1);
scanf("%s",(\*pxm)->name); //注意\*pxm加括号,不用挑战编译器的优先级和主管看代码的优先
(\*pxm)++; //级
}
\*pxm = \*pxm - \*pn;
}
void outputVoter(struct Voter \*p,int len)
{
int i;
puts("姓名\t得票数\t");
for(i=0; i<len; i++)
{
printf("%s\t%d \n",p->name,p->tickets);
p++;
}
}
int singTickets(struct Voter \*p,int len)
{
char tmpName[32];
int i;
int j;
int person;
int mark; //废票判断变量
int wasteTickets = 0;
struct Voter \*pbak = p; //定义一个结构体指针变量pbak指向结构体指针p的首地址。
//puts("第二步进行投票和唱票环节。\n\n");
puts("请输入参与投票的人数。");
scanf("%d",&person);
for(i=0; i<person; i++)
{
mark = 0; //mark不能在定义时赋值0,如果赋值0,后面的废票判别永远不会执行
memset(tmpName,'\0',sizeof(tmpName));
puts("请输入你支持谁。");
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) //废票判断
{
puts("候选人无此人,选票无效");
wasteTickets++;
}
}
return wasteTickets;
}
struct Voter\* getMax(struct Voter \*p,int len)
{
int i;
struct Voter\* max;
max = p;
for(i=0; i<len; i++)
{
if(max->tickets < p->tickets)
{
max = p; //把xm[i]结构体赋给max结构体,实现替代关系
}
p++; //\*\*\*注意p++不能乱加,不然会出错\*\*\*
}
return max;
}
int main()
{
struct Voter \*xm = NULL;
struct Voter \*result;
int total = 0;
int wasteTickets;
initVoter(&xm,&total);
printf("total = %d\n",total);
wasteTickets = singTickets(xm,total);
outputVoter(xm,total);
printf("废票为%d\n",wasteTickets);
result = getMax(xm,total);
printf("%s以%d票当选!!废票%d\n",result->name,result->tickets,wasteTickets);
return 0;
}
/\*
int \*pt = &total; //定义一个指针变量pt指向变量tatal
struct Voter \*\*pxm = &xm; //定义一个结构体二级指针变量pxm指向结构体指针变量xm
//二级指针:是否是存放指针变量地址
int i;
if(\*pxm == NULL)
{
puts("请输入有几个候选人。");
scanf("%d",pt);
\*pxm = (struct Voter\*)malloc(\*pt \* sizeof(struct Voter));
}
for(i=0; i<\*pt; i++)
{
(\*pxm)->tickets = 0;
printf("请输入第%d个候选人的名字。\n",i+1);
scanf("%s",(\*pxm)->name); //注意\*pxm加括号,不用挑战编译器的优先级和主管看代码的优先
(\*pxm)++; //级
}
\*pxm = \*pxm - \*pt; //记得指针偏移后回来。
\*/
4.联合体和共用体
1.什么是共用体
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年嵌入式&物联网开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上嵌入式&物联网开发知识点,真正体系化!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新!!
pt = &total; //定义一个指针变量pt指向变量tatal
struct Voter **pxm = &xm; //定义一个结构体二级指针变量pxm指向结构体指针变量xm
//二级指针:是否是存放指针变量地址
int i;
if(*pxm == NULL)
{
puts(“请输入有几个候选人。”);
scanf(“%d”,pt);
*pxm = (struct Voter*)malloc(*pt * sizeof(struct Voter));
}
for(i=0; i<*pt; i++)
{
(*pxm)->tickets = 0;
printf(“请输入第%d个候选人的名字。\n”,i+1);
scanf(“%s”,(*pxm)->name); //注意*pxm加括号,不用挑战编译器的优先级和主管看代码的优先
(*pxm)++; //级
}
*pxm = *pxm - *pt; //记得指针偏移后回来。
*/
### 4.联合体和共用体
#### 1.什么是共用体
## 最后
**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**
**深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。**
**因此收集整理了一份《2024年嵌入式&物联网开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**
[外链图片转存中...(img-ZkRwBt9p-1715743867580)]
[外链图片转存中...(img-3B8sj9uQ-1715743867581)]
[外链图片转存中...(img-R9A2AepX-1715743867582)]
[外链图片转存中...(img-nIko74JY-1715743867582)]
[外链图片转存中...(img-RzrwLE9a-1715743867583)]
[外链图片转存中...(img-OoG9AIkQ-1715743867584)]
[外链图片转存中...(img-GixTbxkl-1715743867584)]
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上嵌入式&物联网开发知识点,真正体系化!**
[**如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!**](https://bbs.csdn.net/topics/618654289)
**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**!!