结构体成员可以是标量、数组、指针或其他结构体。
*结构体类型和结构体变量
**关于 . 和 -> **
例题1:输入输出
定义一个结构体student,存储学生的学号、名字、性别和年龄,读入每个学生的所有信息,保存在结构体中,并输出。结构体student的定义如下:
struct student {
int num;
char name[20];
char sex;
int age;
};
本题要求使用指向结构体数组进行输入和输出。
输入
第一行有一个整数n,表示以下有n个学生的信息将会输入。保证n不大于20。
以后的n行中,每一行包含对应学生的学号、名字、性别和年龄,用空格隔开。保证每一个人名都不包含空格且长度不超过15,性别用M和F两个字符来表示。
输出
有n行,每行输出一个学生的学号、名字、性别和年龄,用空格隔开。
请注意行尾输出换行。
#include <stdio.h>
#include <stdlib.h>
struct student {
int num;
char name[20];
char sex;
int age;
};
int main() {
int n;
scanf("%d", &n);
//struct student students[n];
struct student* students = (struct student*)malloc(n * sizeof(struct student));
for (int i = 0; i < n; i++) {
scanf("%d %s %c %d", &students[i].num, students[i].name, &students[i].sex, &students[i].age);
}
for (int i = 0; i < n; i++) {
printf("%d %s %c %d", students[i].num, students[i].name, students[i].sex, students[i].age);
}
free(students);
return 0;
}
例题2:成绩统计
题目描述
有10个学生,每个学生的数据包括学号、姓名、3门课程的成绩。读入这10个学生的数据,要求输出3门课程的总平均成绩,以及个人平均分最高的学生的数据(包括学号、姓名、3门课程成绩、平均分数)。
输入
共有10行,每行包含了一个学生的学号(整数)、名字(长度不超过19的无空格字符串)和3门课程的成绩(0至100之间的整数),用空格隔开。
输出
第一行包含了3个实数,分别表示3门课程的总平均成绩,保留2位小数,每个数之后输出一个空格。
第二行输出个人平均分最高的学生的数据(如何实现输出该生的数据,之前学的是输出平均分最高的分数),与输入数据格式相同。如果有多位个人平均分最高的学生,输出按照输入顺序第一个最高分的学生数据。
请注意行尾输出换行。
样例输入 Copy
101 AAA 80 81 82 102 BBB 83 84 85 103 CCC 86 87 88 104 DDD 89 90 91 105 EEE 92 93 94 106 FFF 80 90 100 107 GGG 85 90 95 108 HHH 80 85 90 109 III 90 91 92 110 JJJ 91 88 87
样例输出 Copy
85.60 87.90 90.40 105 EEE 92 93 94
#include <stdio.h>
struct person
{
int num;
char name[20];
int a;
int b;
int c;
};
int main()
{
float A = 0, B = 0, C = 0;
int index = 0;
struct person students[10];
for (int i = 0; i < 10; i++) {
scanf("%d%s%d%d%d", &students[i].num, students[i].name, &students[i].a, &students[i].b, &students[i].c);
A = A + students[i].a;
B = B + students[i].b;
C = C + students[i].c;
if ((students[i].a + students[i].b + students[i].c) > (students[index].a + students[index].b + students[index].c))
{
index = i;
}
}
printf("%.2f %.2f %.2f\n", A/10,B/10,C/10);
printf("%d %s %d %d %d", students[index].num, students[index].name, students[index].a, students[index].b, students[index].c);
}
例题3:二维向量加法
定义二维向量 struct Vector { int x; int y; };
要求:实现函数 struct Vector f(struct Vector a,struct Vector b) 计算向量a、b加法,函数返回值为向量a、b相加的结果(也是向量)
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
struct Vector
{
int x;
int y;
};
struct Vector f(struct Vector a, struct Vector b)
//函数 f 的返回类型是结构体类型 struct Vector。
//它接受两个 struct Vector 类型的参数 a 和 b,并返回一个新的 struct Vector 类型的结果。
{
struct Vector result;
result.x = a.x + b.x;
result.y = a.y + b.y;
return result;
};
int main()
{
struct Vector a, b, c;
scanf("%d%d%d%d", &a.x, &a.y, &b.x, &b.y);
c = f(a,b);
printf("(%d,%d)", c.x,c.y);
}
例题4:去掉最高分和最低分求平均值
输入
输入有多组数据。每组2行,第一行是一个N,代表有N个评委。然后第二行有N个数,每个数用空格隔开,代表每个评委的打分。
当输入的N为0的时候结束输入。
输出
对于每组输入,输入最终这个选手的得分(小数点后面保留2位有效数字)。
样例输入 Copy
3 74 36 34 7 16 97 27 26 74 96 88 0
样例输出 Copy
36.00 62.20
使用结构体可以提高代码的可读性和可维护性。通过定义结构体,我们可以给评委的分数赋予更具有意义的名称,而不仅仅是使用简单的变量。此外,如果以后需要扩展评委的信息,比如加入评委的姓名、ID 等,结构体还可以方便地进行修改。
在定义结构体类型时,需要使用 struct
关键字进行声明,例如 struct judge
。但是在函数声明和函数调用时,可以省略 struct
关键字,只使用结构体类型的名称即可。这是 C 语言的语法规定。
#include <stdio.h>
#include <stdlib.h>
struct judge
{
int score;
};
float calculate(struct judge judgenum[], int n)
{
int max = 0, min = 0;
for (int i = 1; i < n; i++) {
if (judgenum[i].score > judgenum[max].score)
max = i;
}
for (int i = 1; i < n; i++) {
if (judgenum[i].score < judgenum[min].score)
min = i;
}
float sum = 0;
for (int i = 0; i < n; i++)
{
sum = sum + judgenum[i].score;
}
float average = (sum - judgenum[min].score - judgenum[max].score) / (n-2);
return average;
}
int main()
{
int n;
int score;
float average;
//while (~(scanf("%d", &score)))
while(scanf("%d",&n)!=EOF)
{
if (n == 0)
break;
struct judge* judgenum = (struct judge*)malloc(n * sizeof(struct judge));
if (judgenum == NULL) {
printf("内存分配失败\n");
exit(1);//如果内存分配失败会终止程序
for (int i = 0; i < n; i++) {
scanf("%d", & judgenum[i].score);
average = calculate(judgenum,n);
}
printf("%.2f", average);
free(judgenum);
}
return 0;
}
例题5:晨跑次数统计
题目描述
某学校为鼓励学生锻炼身体,要求学生周一到周五早晨在操场跑步,并进行刷卡记录,作为期末评优的依据。
刷卡机器中记录的数据格式为学号和刷卡时间,其中学号N为10位数字,时间T格式为yyyymmddhhmmss
读卡程序确保每天不会多次记录同一名学生的晨跑刷卡时间
要求:统计学生晨跑次数,并按学号升序输出学号+次数。
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
struct student
{
int id;
int time;
int num;
};
int main()
{
int n = 0;
struct student students[1005] = { 0 };
while (scanf("%d%d", &students[n].id, &students[n].time) != EOF)
{
students[n].num = 1;
for (int i = 0; i < n; i++)
{
if (students[i].id == students[n].id)
{
students[i].num++;
n--;
break;
}
}
n++;
}
for (int i = 0; i < n; i++)
{
printf("%d %d\n", students[i].id, students[i].num);
}
return 0;
}
排序的时候要注意,学号在使用排序方法排序之后,其次数也要跟着交换
选择排序👇
选择排序 已知n个数据 按学号升序排列
for (int i = 0; i < n - 1; i++) {
int m = i;
for (int j = i + 1; j < n; j++) {
if (students[m].id > students[j].id) {
m = j;
}
}
if (m != i) {
int t = students[i].id;
students[i].id = students[m].id;
students[m].id = t;
int f=students[i].num;
students[i].num=students[m].num;
students[m].num=f;
}
}
冒泡排序
int f = 0;
for (int i = 0; i < n - 1; i++)
{
for (int t = 0; t < n - 1 - i; t++) {
if (students[t].id > students[t+1].id) {
int g = students[t].id;
students[t].id = students[t + 1].id;
students[t + 1].id = g;
int h = students[t].num;
students[t].num = students[t+1].num;
students[t+1].num = h;
f = 1;
}
}
if (f = 0)break;
}