C的实用笔记40——结构体数组

文章介绍了C语言中结构体数组的定义、初始化和遍历方法,并提供了一个实现选票系统的示例,包括候选人信息存储、唱票过程以及结果公布。选票系统使用结构体数组存储候选人信息,通过strcmp函数比对投票人选择的候选人并更新得票数。
摘要由CSDN通过智能技术生成

1.结构体数组的定义及初始化

结构体数组看起来像二维数组,但并不是

#include <stdio.h>
struct Student
{
    int num;
    char name[32];
    char sex;
    int age;
    double score;
    char addr[32];
};
int main(int argc, char const *argv[])
{
    struct Student arr[3] = {
        {2,"张三",'M',17,98,"北京"},
        {3,"李四",'F',18,89.5,"上海"},
        {4,"王五",'M',18,100,"深圳"}
    };
    return 0;
}

2.结构体数组的遍历

1、知识点:

  1. 与计算数组长度相同,可以通过sizeof计算结构体数组长度
  2. 结构体数组每个元素都是结构体变量,因此也是用点运算符引用结构体变量的成员变量。

2、举例:

#include <stdio.h>
struct Student
{
    int num;
    char name[32];
    char sex;
    int age;
    double score;
    char addr[32];
};
int main(int argc, char const *argv[])
{
    int i;
    int len;
    struct Student arr[3] = {
        {2,"张三",'M',17,98,"北京"},
        {3,"李四",'F',18,89.5,"上海"},
        {4,"王五",'M',18,100,"深圳"}
    };
    len = sizeof(arr) / sizeof(arr[0]);
    for(i=0; i<len; i++){
        printf("学号:%d,名字:%s,年龄:%d,分数:%lf,地址:%s\n", \
            arr[i].num, arr[i].name, arr[i].age, arr[i].score, arr[i].addr);
    }
    return 0;
}

3.习题

习题1:试完成选票系统,功能包括确定候选人、群众唱票、公布结果

  1. 思路:
    声明结构体1: struct Candidate { char name[32]; int tickets; };	代表候选人的名字和得票数
    1. 假设候选人有三个,定义一个结构体数组保存三人信息: struct Candidate xm[3]; 
    2. 假设不知道数组长度,需要用sizeof运算符计算数组长度,保存在变量len中: 
    	int len = sizeof(xm) / sizeof(xm[0]);
    //1.初始化环节
    3. for循环,代表结构体数组下标(第i个选民)的循环变量i从0开始,<len 时,进入循环
    	3.1 初始化第i位选民的得票数为0: xm[i].tickets = 0;
        3.2 通过键盘输入的方式来确认结构体数组中每位候选人的名字,将字符串保存在每个结构体变量的name中:
    		scanf("%[^\n]%*c", xm[i].name);      或者      gets(xm[i].name);
    //2.唱票环节
    4. for循环,代表投票人的循环变量i从0开始,<total 时进入循环	//变量total代表总投票人数
        4.1 令标记废票的变量mark,从开始进入循环时变成0,用0代表找不到候选人,用1代表找到候选人
        4.2 通过键盘输入的方式来确认投票人投给的对象,将字符串保存在一个临时字符数组tempName[32]中
        	需要注意的是,每次进入唱票循环时,调用memset()函数用'\0'清空tempName
        4.3 for循环,代表结构体数组下标(第j个选民)的循环变量j从0开始,<len 时,进入循环
        //内在逻辑:每个人投完票后,需要将他输入的字符串与结构体数组中每个候选人的名字进行比较
        	4.3.1 用strcmp()函数判断,tempName是否和xm[j].name完全相同,
            	4.3.2 如果是,说明能找到候选人
                	4.3.2.1 让这个人的得票数加1: xm[j].tickets++;
    				4.3.2.2 修改代表找到候选人的变量mark: mark = 1;	//12行
    				4.3.2.3 找到人后就不用继续往下找了,用break提前退出内层循环
        4.4 经过4.3的投票人名比对环节后,判断代表找到候选人的变量mark是否等于0	//12行
        	4.4.1 如果是,说明这是个弃票
            		那么,修改记录弃票的循环变量invalidTickets: invalidTickets++;
    //3.公布结果
    5. for循环,代表结构体数组下标(第i个选民)的循环变量i从0开始,<len 时,进入循环
    	5.1 打印每个候选人的名字和得票数
    6. 下面要比对候选人得票数,选出大者,不妨暂时认为第0个选民xm[0]得票数最多,令: max = xm[0];
    	//这里max是和xm[0]、xm[1]、xm[2]一样类型的结构体变量,需要提前定义
    7. for循环,代表结构体数组下标(第i个选民)的循环变量i从1开始,<len 时,进入循环
    	7.1 判断max.tickets是否小于xm[i].tickets
        	7.1.1 如果是,
            		那么,认为xm[i]选民的得票数最多,令: max = xm[i];
    8. 打印候选人中得票数最多的候选人、票数,以及弃票情况

  2. 代码:
    #include <stdio.h>
    #include <string.h>
    struct Candidate
    {
        char name[32];
        int tickets;
    };
    int main(int argc, char const *argv[])
    {
        struct Candidate xm[3];
        struct Candidate max;
        int i;
        int total = 5;                                      
        char tempName[32];
        int len = sizeof(xm) / sizeof(xm[0]);  
        int j;
        int mark;
        int invalidTickets = 0;
        /* 1.初始化,清空选票数,确认候选者 */
        for(i=0; i<len; i++){           
            xm[i].tickets = 0;
            printf("请输入第%d个选民的名字:\n", i+1);
            gets(xm[i].name);
        }  
        /* 2.唱票环节,有total个投票者 */
        for(i=0; i<total; 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++;
            }
        }
        /* 3.公布投票结果 */
        for(i=0; i<len; i++){           
            printf("候选人:%s,得票数:%d\n", xm[i].name, xm[i].tickets);
        }
        max = xm[0];
        for(i=1; i<len; i++){           
            if(max.tickets < xm[i].tickets){
                max = xm[i];
            }
        }
        printf("%s以%d票当选\n", max.name, max.tickets);
        printf("废票共计%d张\n", invalidTickets);
        return 0;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值