抖音线上学习嵌入式是否可靠???我用一篇博文告诉你。#C语言结构体_抖音有嵌入式岗位吗 (1)

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.判断最高得票数同票算法**  
 ![判断最高得票数同票算法](https://img-blog.csdnimg.cn/ae00850d7a504a9cb5faafa0e4fa779e.png)  
 **代码如下:**



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;

}


[6.看见指针茫然,可以点击这里去看指针知识。]( )


#### 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.ticketstickets)
{
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->ticketstickets)
{
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.内存指向图**  
 ![内存指向图](https://img-blog.csdnimg.cn/fde30e845241494d8af4961780a11e5c.png)  
 **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.什么是共用体


**C语言中的共用体(Union)是一种特殊的数据类型,它允许在相同的内存位置存储不同的数据类型。共用体可以包含多个成员变量,但任何给定时间只能保存其中的一个成员变量的值。**


#### 2.内存空间


**共用体的内存分配是基于其最大成员的大小。这是因为共用体的多个成员共享同一块内存空间。因此,共用体的大小等于最大成员的大小。**


#### 3.与结构体的区别


**1.结构体元素有各自单独空间共用体元素共享空间,空间大小有最大类型确定**  
 **2.结构体元素互不影响共用体赋值会导致覆盖**  
 **3.程序代码**



#include <stdio.h>
/*
时间: 2023年7月15日23:25:55
程序功能:初识联合体共用体
*/
struct TestS
{
int idata;
char cdata;
double ddata;
};

union TestU //定义一个联合体共用体TestU
{
int idata;
char cdata;
double ddata;
};

int main()
{
struct TestS t1;
union TestU u1;

puts("程序功能:初识联合体共合体\n\n");

printf("结构体t1的大小为 %d字节\n",sizeof(t1));
printf("联合体u1的大小为 %d字节\n",sizeof(u1));

puts("\n");
puts("下面输出结构体变量的地址。\n");
printf("idata的地址为:0x%p\n",&t1.idata);
printf("cdata的地址为:0x%p\n",&t1.cdata);
printf("ddata的地址为:0x%p\n",&t1.ddata);

puts("\n");
puts("下面输出联合体变量的地址。\n");
printf("idata的地址为:0x%p\n",&u1.idata);
printf("cdata的地址为:0x%p\n",&u1.cdata);
printf("ddata的地址为:0x%p\n\n",&u1.ddata);

puts("结论如下:");
puts("联合体:同一个内存空间存放类型不同,不同类型的变量共享一块空间。\n");
puts("结构体元素有各自单独空间,共用体元素共享空间,空间大小有最大类型确定。\n");
puts("union TestU //定义一个联合体共用体TestU\n");

return 0;

}


#### 4.使用时注意数据覆盖


**以下代码是使用共用体数据覆盖示例**



#include <stdio.h>
/*
时间: 2023年7月16日00:54:05
程序功能:共用体数据覆盖问题
*/
struct TestS
{
int idata;
char cdata;
double ddata;
};

union TestU //定义一个联合体共用体TestU
{
int idata;
char cdata;
double ddata;
};

int main()
{
struct TestS t1;
union TestU u1;
t1.idata = 10;
t1.cdata = ‘c’;
t1.ddata = 15.69;

u1.idata = 10;
u1.cdata = 'c';
u1.ddata = 15.69;

puts("程序功能:共用体数据覆盖问题\n\n");

printf("结构体t1的大小为 %d字节\n",sizeof(t1));
printf("联合体u1的大小为 %d字节\n",sizeof(u1));

puts("\n");
puts("下面输出结构体变量的地址。\n");
printf("idata的地址为:0x%p\n",&t1.idata);
printf("cdata的地址为:0x%p\n",&t1.cdata);
printf("ddata的地址为:0x%p\n",&t1.ddata);

puts("\n");
puts("下面输出联合体变量的地址。\n");
printf("idata的地址为:0x%p\n",&u1.idata);
printf("cdata的地址为:0x%p\n",&u1.cdata);
printf("ddata的地址为:0x%p\n\n",&u1.ddata);

puts("\n");
puts("下面输出结构体变量的值。\n");
printf("idata的值为:%d\n",t1.idata);
printf("cdata的值为:%c\n",t1.cdata);
printf("ddata的值为:%lf\n\n",t1.ddata);

puts("\n");
puts("下面输出共用体变量的值。\n");
printf("idata的值为:%d\n",u1.idata);
printf("cdata的值为:%c\n",u1.cdata);
printf("ddata的值为:%lf\n\n",u1.ddata);

puts("\n问题分析:");
puts("1.共用体元素共享空间,空间大小有最大类型确定。");
puts("2.数据赋值会出现覆盖,输出乱码。");

return 0;

}


#### 5.联合体/共用体应用


**1.使用共用体完成如下题目:**


**有若干个人员的数据,其中有学生和老师。学生的数据包括姓名,号码,性别,职业,班级。教师的数据包括姓名,号码,性别,职业,职务要求用同一个表格来处理。**  
 **2.程序代码**



#include <stdio.h>
/*
时间: 2023年7月16日01:47:37
程序功能:有若干个人员的数据,其中有学生和老师。学生的数据包括姓名,号码,性别,职业,班级。
教师的数据包括姓名,号码,性别,职业,职务要求用同一个表格来处理。
*/
struct Information //结构体联合体结合定义
{
char name[32];
int age;

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年嵌入式&物联网开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上嵌入式&物联网开发知识点,真正体系化!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新!!

printf("ddata的值为:%lf\n\n",u1.ddata);

puts("\n问题分析:");
puts("1.共用体元素共享空间,空间大小有最大类型确定。");
puts("2.数据赋值会出现覆盖,输出乱码。");

return 0;

}


#### 5.联合体/共用体应用


**1.使用共用体完成如下题目:**


**有若干个人员的数据,其中有学生和老师。学生的数据包括姓名,号码,性别,职业,班级。教师的数据包括姓名,号码,性别,职业,职务要求用同一个表格来处理。**  
 **2.程序代码**



#include <stdio.h>
/*
时间: 2023年7月16日01:47:37
程序功能:有若干个人员的数据,其中有学生和老师。学生的数据包括姓名,号码,性别,职业,班级。
教师的数据包括姓名,号码,性别,职业,职务要求用同一个表格来处理。
*/
struct Information //结构体联合体结合定义
{
char name[32];
int age;

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年嵌入式&物联网开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

[外链图片转存中…(img-R0DOKINS-1715743797258)]

[外链图片转存中…(img-MZNxtS6B-1715743797259)]

[外链图片转存中…(img-hcScq2LA-1715743797260)]

[外链图片转存中…(img-YudB2XUr-1715743797260)]

[外链图片转存中…(img-UlWA0RbL-1715743797261)]

[外链图片转存中…(img-43uRHylR-1715743797261)]

[外链图片转存中…(img-ECKXdfbj-1715743797262)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上嵌入式&物联网开发知识点,真正体系化!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新!!

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值