C的实用笔记42——结构体二级指针

文章介绍了如何通过结构体二级指针在C语言中初始化和管理选票系统的结构体数组。主要展示了两种方法,一是通过函数返回值修改结构体指针的指向,二是使用二级指针间接修改。这两种方法都在main函数和一个名为initXms的辅助函数中进行了实现,用于分配内存并获取用户输入的选民信息。此外,文章还包含了一个完整的选票系统示例,包括唱票、废票统计和结果公布等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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; 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值