1.通过结构体二级指针可以引用结构体指针
1、回顾选票系统中的initXms函数:实际上是通过指针函数的返回值修改结构体指针的指向。
struct Candidate* initXms(struct Candidate *xm, int len)
{
assert(xm == NULL);
int i;
xm = (struct Candidate*)malloc(len*sizeof(struct Candidate));
for(i=0; i<len; i++){
xm[i].tickets = 0;
printf("请输入第%d个选民的名字:\n", i+1);
gets(xm[i].name);
}
return xm;
}
int main(int argc, char const *argv[])
{
struct Candidate *xm = NULL;
int len = 0; //结构体数组长度,即选民人数
puts("请输入参选的人数");
scanf("%d%*c", &len); //学习指针后能深刻体会到scanf为啥用&取地址
xm = initXms(xm, len); //1.初始化环节
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
}
2、另一种方法是:通过结构体二级指针间接修改结构体指针的指向
int main(int argc, char const *argv[])
{
struct Candidate *xm = NULL;
int len = 0; //结构体数组长度,即选民人数
puts("请输入参选的人数");
scanf("%d%*c", &len); //学习指针后能深刻体会到scanf为啥用&取地址
struct Candidate **pxm = &xm; //结构体二级指针指向结构体指针
if(*pxm == NULL){
*pxm = (struct Candidate*)malloc(len*sizeof(struct Candidate));
}
int i;
for(i=0; i<len; i++){
(*pxm)->tickets = 0;
printf("请输入第%d个选民的名字:\n", i+1);
gets((*pxm)->name);
(*pxm)++; //指针自加法
}
*pxm = *pxm - len; //指针自加法间接访问后,记得复位
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
}
3、我们将上述方法写到函数中,封装起来即可
void initXms(struct Candidate **pxm, int len)
{
if(*pxm == NULL){
*pxm = (struct Candidate*)malloc(len*sizeof(struct Candidate));
}
int i;
for(i=0; i<len; i++){
(*pxm)->tickets = 0;
printf("请输入第%d个选民的名字:\n", i+1);
gets((*pxm)->name);
(*pxm)++;
}
*pxm = *pxm - len; //指针自加法间接访问后,记得复位
}
2.选票系统的另一种写法
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
struct Candidate
{
char name[32];
int tickets;
};
void initXms(struct Candidate **pxm, int len);
void printXms(struct Candidate *xm, int len);
int doVote(struct Candidate *xm, int len);
struct Candidate* getMax(struct Candidate *xm, int len);
int main(int argc, char const *argv[])
{
struct Candidate *xm = NULL;
int len = 0; //结构体数组长度,即选民人数
int invalidTickets;
struct Candidate *final;
puts("请输入参选的人数");
scanf("%d%*c", &len);
initXms(&xm, len); //1.初始化环节
// xm = initXms(xm, len); //1.初始化环节(另一种方法,作废)
printXms(xm, len); // 1.展示选民(姓名和票数)
invalidTickets = doVote(xm, len); //2.唱票环节
printXms(xm, len); // 2.展示选民(姓名和票数)和废票
printf("废票共计%d张\n", invalidTickets); // 2.展示废票
final = getMax(xm, len);
printf("%s以%d票当选!!!\n", final->name, final->tickets); //3.公布结果
return 0;
}
void initXms(struct Candidate **pxm, int len)
{
if(*pxm == NULL){
*pxm = (struct Candidate*)malloc(len*sizeof(struct Candidate));
}
int i;
for(i=0; i<len; i++){
(*pxm)->tickets = 0;
printf("请输入第%d个选民的名字:\n", i+1);
gets((*pxm)->name);
(*pxm)++;
}
*pxm = *pxm - len; //指针自加法间接访问后,记得复位
}
void printXms(struct Candidate *xm, int len)
{
int i;
for(i=0; i<len; i++){
printf("选民:%s,得票数:%d\n", xm[i].name, xm[i].tickets);
}
}
int doVote(struct Candidate *xm, int len)
{
int i;
int j;
int mark = 0;
char tempName[32];
int invalidTickets = 0;
for(i=0; i<5; i++){
mark = 0;
printf("第%d个同学,请输入你投票给谁:\n", i+1);
memset(tempName, '\0', sizeof(tempName)); //将临时名字每次进行清空
scanf("%[^\n]%*c", tempName);
for(j=0; j<len; j++){ //遍历候选者,试着找出用户输入的人名
if( strcmp(tempName, xm[j].name) == 0 ){
xm[j].tickets++;
mark = 1;
break;
}
}
if(mark == 0){ //一次唱票后,判断本次投票是否有效
puts("没有此候选人,视为弃票");
invalidTickets++;
}
}
return invalidTickets;
}
struct Candidate* getMax(struct Candidate *xm, int len)
{
struct Candidate *max = xm;
int i;
for(i=0; i<len; i++){
if(max->tickets < xm->tickets){
max = xm;
}
xm++;
}
return max;
}