C语言:结构体数组

news2024/11/23 22:06:23

结构体数组

  • 介绍
    • 定义结构体
    • 定义结构体数组
    • 初始化结构体数组
    • 访问和修改结构体数组的元素
    • 遍历结构体数组
  • 示例
  • 高级用法
    • 动态分配结构体数组
      • 使用 `malloc` 动态分配
      • 使用 `calloc` 动态分配
    • 结构体数组作为函数参数
    • 结构体数组与指针
    • 多维结构体数组
    • 使用 `typedef` 简化结构体定义
    • 结构体数组的常见应用场景
    • 结构体数组的排序
    • 结构体数组与文件操作
      • 写入结构体数组到文件
      • 从文件读取结构体数组
    • 使用嵌套结构体

介绍

在C语言中,结构体数组是指一个由结构体类型的元素组成的数组。这种数组允许我们存储多个结构体实例,并可以通过索引来访问每个结构体。

定义结构体

首先,我们需要定义一个结构体类型。例如,定义一个代表学生信息的结构体:

#include <stdio.h>

struct Student {
    char name[50];
    int age;
    float gpa;
};

定义结构体数组

接下来,我们可以定义一个结构体数组。例如,定义一个包含100个学生的数组:

struct Student students[100];

初始化结构体数组

我们可以在定义时初始化结构体数组:

struct Student students[3] = {
    {"Alice", 20, 3.5},
    {"Bob", 21, 3.7},
    {"Charlie", 19, 3.8}
};

或者在程序运行时逐个初始化:

strcpy(students[0].name, "Alice");
students[0].age = 20;
students[0].gpa = 3.5;

strcpy(students[1].name, "Bob");
students[1].age = 21;
students[1].gpa = 3.7;

strcpy(students[2].name, "Charlie");
students[2].age = 19;
students[2].gpa = 3.8;

注意:strcpy 函数用于将字符串复制到结构体成员中。

访问和修改结构体数组的元素

我们可以通过数组索引来访问和修改结构体数组的元素:

printf("Name: %s, Age: %d, GPA: %.2f\n", students[0].name, students[0].age, students[0].gpa);

students[1].age = 22; // 修改Bob的年龄
printf("Name: %s, Age: %d, GPA: %.2f\n", students[1].name, students[1].age, students[1].gpa);

遍历结构体数组

可以使用循环来遍历结构体数组:

for (int i = 0; i < 3; i++) {
    printf("Name: %s, Age: %d, GPA: %.2f\n", students[i].name, students[i].age, students[i].gpa);
}

示例

下面是一个完整的示例程序,它定义了一个结构体数组,初始化并输出其中的元素:

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

struct Student {
    char name[50];
    int age;
    float gpa;
};

int main() {
    struct Student students[3];

    // 初始化
    strcpy(students[0].name, "Alice");
    students[0].age = 20;
    students[0].gpa = 3.5;

    strcpy(students[1].name, "Bob");
    students[1].age = 21;
    students[1].gpa = 3.7;

    strcpy(students[2].name, "Charlie");
    students[2].age = 19;
    students[2].gpa = 3.8;

    // 输出
    for (int i = 0; i < 3; i++) {
        printf("Name: %s, Age: %d, GPA: %.2f\n", students[i].name, students[i].age, students[i].gpa);
    }

    return 0;
}

输出结果:
在这里插入图片描述

高级用法

动态分配结构体数组

在某些情况下,数组的大小可能在编译时未知。这时可以使用动态内存分配来创建结构体数组。

使用 malloc 动态分配

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

struct Student {
    char name[50];
    int age;
    float gpa;
};

int main() {
    int n;
    printf("Enter the number of students: ");
    scanf("%d", &n);

    // 动态分配内存
    struct Student *students = (struct Student*)malloc(n * sizeof(struct Student));
    if (students == NULL) {
        printf("Memory allocation failed\n");
        return 1;
    }

    // 初始化
    for (int i = 0; i < n; i++) {
        printf("Enter name, age, and GPA for student %d:\n", i + 1);
        scanf("%s %d %f", students[i].name, &students[i].age, &students[i].gpa);
    }

    // 输出
    for (int i = 0; i < n; i++) {
        printf("Name: %s, Age: %d, GPA: %.2f\n", students[i].name, students[i].age, students[i].gpa);
    }

    // 释放内存
    free(students);

    return 0;
}

使用 calloc 动态分配

calloc 函数可以分配并初始化为零的内存块:

struct Student *students = (struct Student*)calloc(n, sizeof(struct Student));
if (students == NULL) {
    printf("Memory allocation failed\n");
    return 1;
}

结构体数组作为函数参数

我们可以将结构体数组传递给函数来处理。例如:

void printStudents(struct Student *students, int n) {
    for (int i = 0; i < n; i++) {
        printf("Name: %s, Age: %d, GPA: %.2f\n", students[i].name, students[i].age, students[i].gpa);
    }
}

int main() {
    struct Student students[3] = {
        {"Alice", 20, 3.5},
        {"Bob", 21, 3.7},
        {"Charlie", 19, 3.8}
    };

    printStudents(students, 3);

    return 0;
}

在这个例子中,printStudents 函数接受一个指向结构体数组的指针和数组大小。

结构体数组与指针

在C语言中,数组名可以作为指向数组第一个元素的指针使用。这在处理结构体数组时也适用:

struct Student *ptr = students;
printf("Name: %s, Age: %d, GPA: %.2f\n", ptr->name, ptr->age, ptr->gpa);

这里 ptr 是一个指向 students 数组第一个元素的指针,使用 -> 操作符访问其成员。

多维结构体数组

我们还可以定义多维结构体数组。例如,假设我们有一个3x2的学生数组:

struct Student students[3][2] = {
    {{"Alice", 20, 3.5}, {"Bob", 21, 3.7}},
    {{"Charlie", 19, 3.8}, {"David", 22, 3.9}},
    {{"Eve", 20, 4.0}, {"Frank", 23, 3.6}}
};

访问和初始化多维结构体数组的方式类似于普通的多维数组。例如:

printf("Name: %s, Age: %d, GPA: %.2f\n", students[1][0].name, students[1][0].age, students[1][0].gpa);

使用 typedef 简化结构体定义

为了使代码更简洁,可以使用 typedef 定义结构体类型:

typedef struct {
    char name[50];
    int age;
    float gpa;
} Student;

Student students[3];

这样定义和使用结构体数组会更加简洁:

Student students[3] = {
    {"Alice", 20, 3.5},
    {"Bob", 21, 3.7},
    {"Charlie", 19, 3.8}
};

结构体数组的常见应用场景

结构体数组在各种场景中都非常有用,包括但不限于以下几种:

  1. 数据库记录:存储数据库查询结果。
  2. 图形处理:存储图像的像素信息。
  3. 游戏开发:存储游戏对象,如玩家、敌人、道具等。
  4. 文件处理:存储从文件读取的数据,如日志记录。

结构体数组的排序

可以使用标准库函数 qsort 对结构体数组进行排序。需要定义比较函数来确定排序规则。例如,按GPA对学生数组排序:

#include <stdlib.h>

// 比较函数
int compareByGPA(const void *a, const void *b) {
    struct Student *studentA = (struct Student *)a;
    struct Student *studentB = (struct Student *)b;

    if (studentA->gpa < studentB->gpa) return -1;
    if (studentA->gpa > studentB->gpa) return 1;
    return 0;
}

int main() {
    struct Student students[3] = {
        {"Alice", 20, 3.5},
        {"Bob", 21, 3.7},
        {"Charlie", 19, 3.8}
    };

    // 排序
    qsort(students, 3, sizeof(struct Student), compareByGPA);

    // 输出排序结果
    for (int i = 0; i < 3; i++) {
        printf("Name: %s, Age: %d, GPA: %.2f\n", students[i].name, students[i].age, students[i].gpa);
    }

    return 0;
}

结构体数组与文件操作

结构体数组经常用于文件操作,例如将数据保存到文件或从文件读取数据。

写入结构体数组到文件

#include <stdio.h>

int main() {
    struct Student students[3] = {
        {"Alice", 20, 3.5},
        {"Bob", 21, 3.7},
        {"Charlie", 19, 3.8}
    };

    FILE *file = fopen("students.dat", "wb");
    if (file == NULL) {
        printf("Unable to open file\n");
        return 1;
    }

    fwrite(students, sizeof(struct Student), 3, file);
    fclose(file);

    return 0;
}

从文件读取结构体数组

#include <stdio.h>

int main() {
    struct Student students[3];

    FILE *file = fopen("students.dat", "rb");
    if (file == NULL) {
        printf("Unable to open file\n");
        return 1;
    }

    fread(students, sizeof(struct Student), 3, file);
    fclose(file);

    // 输出读取的数据
    for (int i = 0; i < 3; i++) {
        printf("Name: %s, Age: %d, GPA: %.2f\n", students[i].name, students[i].age, students[i].gpa);
    }

    return 0;
}

使用嵌套结构体

在一些复杂的场景中,结构体内部可能包含另一个结构体。例如,一个学生结构体中包含地址信息:

struct Address {
    char street[100];
    char city[50];
    char state[50];
    int zip;
};

struct Student {
    char name[50];
    int age;
    float gpa;
    struct Address address;
};

int main() {
    struct Student students[3] = {
        {"Alice", 20, 3.5, {"123 Maple St", "Springfield", "IL", 62701}},
        {"Bob", 21, 3.7, {"456 Oak St", "Columbus", "OH", 43215}},
        {"Charlie", 19, 3.8, {"789 Pine St", "Austin", "TX", 73301}}
    };

    for (int i = 0; i < 3; i++) {
        printf("Name: %s, Age: %d, GPA: %.2f\n", students[i].name, students[i].age, students[i].gpa);
        printf("Address: %s, %s, %s, %d\n", students[i].address.street, students[i].address.city, students[i].address.state, students[i].address.zip);
    }

    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1810091.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【EDA】SSTA中最慢路径与最快路径统计计算

假设&#xff08;X1&#xff0c;X2&#xff09;为二元高斯随机向量&#xff0c;均值&#xff08;μ1&#xff0c;μ2&#xff09;&#xff0c;标准差&#xff08;σ1&#xff0c;σ2&#xff09;&#xff0c;相关系数ρ 定义&#xff1a;Xmax&#xff08;X1&#xff0c;X2&…

Keil软件仿真的使用

一、软件的初始化设置 初始设置可以按照下图&#xff0c;这里我使用的是STM32F103C8T6&#xff0c;所以单片机型号为STM32F103C8&#xff0c;这个设置在Debug目录下。然后进行时钟的设置&#xff0c;我们板上晶振为8M&#xff0c;这里将时钟改为8. 或许有人想问如果是别的型号单…

JavaScript基础用法(变量定义、输入输出、转义符、注释和编码规范)

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

基于ensp的园区网络搭建综合实验

核心技术介绍 1、虚拟局域网&#xff08;VLAN&#xff09; 2、链路聚合&#xff08;E-trunk&#xff09; 3、多生成树协议&#xff08;MSTP&#xff09; 4、VLANIF三层逻辑接口 5、虚拟路由冗余协议&#xff08;VRRP&#xff09; 6、开放式最短路径优先&#xff08;OSPF&…

C语言:(动态内存管理)

目录 动态内存有什么用呢 malloc函数 开辟失败示范 free函数 calloc函数 realloc函数 当然realooc也可以开辟空间 常⻅的动态内存的错误 对NULL指针的解引⽤操作 对动态内存开辟的空间越界访问 对⾮动态开辟内存使⽤free释放 使⽤free释放⼀块动态开辟内存的⼀部分 …

G盘文件系统损坏:全面解析与应对策略

在数字时代&#xff0c;数据的重要性不言而喻。然而&#xff0c;G盘文件系统损坏却时常给我们的数据安全带来威胁。当G盘文件系统受损时&#xff0c;可能导致文件丢失、数据无法访问等严重后果。本文将深入探讨G盘文件系统损坏的现象、原因、恢复方案以及预防措施&#xff0c;帮…

Java学习-JDBC(四)

连接池 现有问题 每次操作数据库都需要重新获取新连接&#xff0c;使用完毕后需close释放&#xff0c;频繁的创建和销毁造成资源浪费连接的数量无法把控&#xff0c;对服务器造成巨大压力 连接池 连接池是数据库连接对象的缓冲区&#xff0c;通过配置&#xff0c;由连接池负…

刷机维修进阶教程-----红米k30 nv损坏故障 修复实例教程步骤解析

小米红米系列机型在米8起始就有了串码校验。不得随意更改参数限制。不同于其他机型,可以任意刷入同芯片的基带qcn来修复基带和串码丢失。米系列刷入同芯片基带qcn会提示nv损坏故障。是因为有串码校验。一般在于格机或者全檫除分区后写新参数出现的故障。 这种解决方法通常有两…

OpenAI与核聚变公司寻求合作,白宫拨款1.8亿美元用于核聚变商业化研究

在当下&#xff0c;由 AI 引发的新一轮能源危机已经不再是一个小概率的「黑天鹅」事件&#xff0c;而是一头正在向我们猛冲而来的「灰犀牛」。 Helion Energy&#xff0c;是一家总部位于美国华盛顿州埃弗雷特的能源创业公司。 3.5研究测试&#xff1a;hujiaoai.cn 4研究测试&am…

Pytorch 实现目标检测三(Pytorch 25)

一 目标检测数据集 目标检测领域没有像MNIST和Fashion‐MNIST那样的小数据集。为了快速测试目标检测模型&#xff0c;我们收集并标记了一个小型数据集。首先&#xff0c;我们拍摄了一组香蕉的照片&#xff0c;并生成了1000张不同角度和大小的香蕉图像。然 后&#xff0c;我们在…

基于STM32开发的智能空气质量监控系统

⬇帮大家整理了单片机的资料 包括stm32的项目合集【源码开发文档】 点击下方蓝字即可领取&#xff0c;感谢支持&#xff01;⬇ 点击领取更多嵌入式详细资料 问题讨论&#xff0c;stm32的资料领取可以私信&#xff01; 目录 引言环境准备智能空气质量监控系统基础代码实现&…

Kafka的分区副本机制

目录 生产者的分区写入策略 轮询策略 随机策略 按key分配策略 乱序分区 自定义分区策略 实现步骤&#xff1a; 消费者组Rebalance机制 Rebalance触发时机 Rebalance的不良影响 消费者分区分配策略 Range范围分配策略 RoundRobin轮询策略 Stricky粘性分配策略 生产…

冯喜运:6.11#现货黄金#美原油#行情趋势分析及操作建议

【黄金消息面分析】&#xff1a;随着全球经济的波动&#xff0c;黄金作为传统的避险资产&#xff0c;其价格走势一直备受投资者关注。上周五&#xff0c;美国非农就业报告的强劲表现给美联储降息预期泼了冷水&#xff0c;同时&#xff0c;中国5月份未增持黄金&#xff0c;结束了…

Unity ShaderGraph 扭曲

需要注意的是&#xff1a; HDRP ShaderGraph中 你不能扭曲UI&#xff0c;所以假如你要扭曲视频&#xff0c;请把视频在材质上渲染 播放&#xff0c;这样就可以扭曲视频了喔&#xff0c; ShaderGraph扭曲

3、线性代数

1、矩阵转置 A[i,j]A[j,i] 2、对称矩阵 &#xff1a;A转置A [0,2,3] [2 1 5] [3,5,1] 3、三维矩阵 求和 axis0 两个矩阵相加 axis1 两个向量相加 &#xff0c;axis2 向量内部相加 keepdimsTrue 求和后维度保持不变 4、cumsum累加求和 5、torch.mm() 或 torch.bmm() 【矩…

CleanMyMac2024最新免费电脑Mac系统优化工具

大家好&#xff0c;我是你们的好朋友——软件评测专家&#xff0c;同时也是一名技术博主。今天我要给大家种草一个超级实用的Mac优化工具——CleanMyMac&#xff01; 作为一个长期使用macOS的用户&#xff0c;我深知系统运行时间长了&#xff0c;缓存文件、日志、临时文件等都会…

【高校科研前沿】广西大学博士生冯德东为一作在Habitat Int发文:区域乡村性与贫困治理变化的时空格局及相关效应——以滇桂黔石漠化地区为例

1.文章简介 论文名称&#xff1a;Spatio-temporal patterns and correlation effects of regional rurality and poverty governance change: A case study of the rocky desertification area of Yunnan-Guangxi-Guizhou, China&#xff08;区域乡村性与贫困治理变化的时空格…

Magnet pro for mac v2.14.0中文激活版:高效窗口管理工具

Magnet for Mac是一款专为Mac用户设计的窗口管理工具&#xff0c;旨在帮助用户更高效地管理和布局多个应用程序窗口&#xff0c;提升工作效率。 Magnet pro for mac v2.14.0中文激活版下载 这款软件拥有直观易用的界面和丰富的功能&#xff0c;支持用户将屏幕分割成多个区域&a…

【Linux】用户和组的管理、综合实训

目录 实训1&#xff1a;用户的管理 实训2:组的管理 实训3:综合实训 实训1&#xff1a;用户的管理 (1)创建一个新用户userl&#xff0c;设置其主目录为/home/user 1。 (2)查看/etc/passwd 文件的最后一行&#xff0c;看看是如何记录的。 (3)查看文件/etc/shadow文件的最后一…

QT 使用资源文件的注意点

不要存放没有使用的资源文件 即使在代码中没有使用到的资源文件&#xff0c;也会编译到执行文件或者DLL里面去这样会增大它的体积。如下 在代码没有使用这个资源文件(10.4M的2k图片)&#xff0c;但是编译出来的程序有 12M左右的大小 1 假设我们有一个比较复杂的项目&#…