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、知识点:
- 与计算数组长度相同,可以通过sizeof计算结构体数组长度
- 结构体数组每个元素都是结构体变量,因此也是用点运算符引用结构体变量的成员变量。
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: 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. 打印候选人中得票数最多的候选人、票数,以及弃票情况
- 代码:
#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; }