📜  C 程序的输出 |第 44 组(结构和联合)(1)

📅  最后修改于: 2023-12-03 15:29:45.029000             🧑  作者: Mango

C 程序的输出 | 第 44 组(结构和联合)

在 C 语言中,结构体和联合体被广泛应用来组织复杂的数据结构。掌握它们的使用方法对于程序员来说是非常重要的。本文将介绍如何使用结构体和联合体,并展示一个例子程序,便于大家理解它们的应用场景。

结构体和联合体

结构体和联合体都是 C 语言中用来组织复杂的数据结构的方式。结构体是一种可以包含多个不同类型数据成员的数据类型。它的使用非常灵活,可以用来组织各种各样的数据结构,例如链表、树等等。联合体则是一种特殊的结构体,它的所有成员共用同一块内存空间。它主要的应用场景是在需要多个不同的方式来解释同一块内存空间中数据的时候。

结构体的一般形式如下:

struct struct_name {
    type1 member1;
    type2 member2;
    /* ... */
    typen membern;
};

联合体的一般形式如下:

union union_name {
    type1 member1;
    type2 member2;
    /* ... */
    typen membere;
};

结构体和联合体的使用方法和访问成员的方式和其他变量并没有太大的区别。我们可以直接使用 .-> 运算符来访问结构体成员,使用 . 运算符来访问联合体成员,例如:

struct student {
    char name[20];
    int age;
    double score;
};

union data {
    int i;
    char ch[4];
};

int main() {
    struct student s;
    s.age = 20;
    strcpy(s.name, "Jack");
    s.score = 89.5;

    union data d;
    d.i = 0x12345678;
    printf("%x %x %x %x\n", d.ch[0], d.ch[1], d.ch[2], d.ch[3]);
}

上面的程序中,我们定义了一个 student 结构体,包含了 nameagescore 等成员变量。我们同时也定义了一个 data 联合体,其中包含了一个 int 类型的成员和一个 char 数组类型的成员。

程序中的最后一行通过 printf 函数展示了联合体的使用效果,将一个 int 类型的数据在内存中的表示方式按照 char 数组的形式输出出来。这个例子展示了一个简单的联合体的使用方法,它的实际应用中会更加灵活和复杂。

例子程序

为了更好地理解结构体和联合体的使用方法,在这里我们编写了一个简单的例子程序,用来演示如何使用它们来处理一些复杂的数据结构。这个程序的主要功能是读取一个文件中的学生成绩信息,将它们存储在一个结构体数组中,并按照平均分从高到低的顺序输出所有的学生信息。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_STUDENT_NUM 100

struct student {
    char name[20];
    int num;
    double score[3];
    double avg_score;
};

int read_students(struct student *students, char *filename);
void sort_students(struct student *students, int num);
void print_students(struct student *students, int num);

int main(int argc, char **argv) {
    char *filename;
    struct student students[MAX_STUDENT_NUM];
    int num;

    if (argc == 2) {
        filename = argv[1];
    } else {
        perror("Usage: ./a.out <filename>");
        exit(EXIT_FAILURE);
    }

    num = read_students(students, filename);

    if (num > 0) {
        sort_students(students, num);
        print_students(students, num);
    }

    return 0;
}

int read_students(struct student *students, char *filename) {
    FILE *fp;
    int num = 0;
    fp = fopen(filename, "r");
    if (fp == NULL) {
        perror("Error opening file");
        exit(EXIT_FAILURE);
    }
    while (num < MAX_STUDENT_NUM && fscanf(fp, "%d %s %lf %lf %lf",
                                            &(students[num].num),
                                            students[num].name,
                                            &(students[num].score[0]),
                                            &(students[num].score[1]),
                                            &(students[num].score[2])) != EOF) {
        students[num].avg_score = (students[num].score[0] +
                                   students[num].score[1] +
                                   students[num].score[2]) / 3.0;
        num++;
    }
    fclose(fp);
    return num;
}

void sort_students(struct student *students, int num) {
    int i, j;
    struct student temp;
    for (i = 0; i < num - 1; i++) {
        for (j = 0; j < num - 1 - i; j++) {
            if (students[j].avg_score < students[j + 1].avg_score) {
                temp = students[j + 1];
                students[j + 1] = students[j];
                students[j] = temp;
            }
        }
    }
}

void print_students(struct student *students, int num) {
    int i;
    printf("num\tname\tscore1\tscore2\tscore3\tavg_score\n");
    for (i = 0; i < num; i++) {
        printf("%d\t%s\t%.1lf\t%.1lf\t%.1lf\t%.1lf\n",
            students[i].num, students[i].name,
            students[i].score[0], students[i].score[1],
            students[i].score[2], students[i].avg_score);
    }
}

这个程序主要分为三个部分。第一个部分是 read_students 函数,它用来读取文件中的学生信息,并将它们存储到一个结构体数组中。第二个部分是 sort_students 函数,它用来对学生数组按照平均分从高到低排序。第三个部分是 print_students 函数,它用来输出排序后的所有学生信息。

在这个程序中,我们定义了一个名为 student 的结构体,它包含了每个学生的姓名、学号、三门课的成绩和平均分等信息。我们在 read_students 函数中使用 fscanf 函数从文件中读入这些信息,并计算出每个学生的平均分。在 sort_students 函数中,我们使用了冒泡排序来按照平均分从高到低对学生数组进行排序。最后在 print_students 函数中,我们按照一定的格式输出了学生的所有信息。

为了方便大家更好地理解这个程序,我们准备了一个样例输入文件 students.txt 和一个对应的输出文件 result.txt。如果您需要运行这个程序来检验它的正确性,请将这个样例文件放在程序的当前工作目录下,并执行以下命令:

$ gcc program.c -o program
$ ./program students.txt > result.txt

这个程序的输出结果将会被重定向到 result.txt 文件中,您可以使用一个文本编辑器来查看这个文件以验证程序的正确性。

总结

在本文中,我们介绍了 C 语言中结构体和联合体的使用方法,并提供了一个例子程序来演示如何使用它们来处理复杂的数据结构。这些知识点在程序员的工作中非常重要,因此大家务必掌握它们的基本概念和使用方法。