C语言:结构体数组

结构体数组

  • 介绍
    • 定义结构体
    • 定义结构体数组
    • 初始化结构体数组
    • 访问和修改结构体数组的元素
    • 遍历结构体数组
  • 示例
  • 高级用法
    • 动态分配结构体数组
      • 使用 `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.mzph.cn/pingmian/40610.shtml

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

相关文章

ClickHouse概述

ClickHouse概述 文章目录 ClickHouse概述ClickHouse是什么ClickHouse快的理由什么是OLAPClickHouse的特点列式存储DBMS 的功能多样化引擎高吞吐写入能力数据分区与线程级并行 ClickHouse的应用合适场景不适合场景 ClickHouse是什么 ClickHouse 是俄罗斯的 Yandex 于 2016 年开…

ubuntu20.04配置调试工具

1.准备工作&#xff1a;安装g或者gdb sudo apt updatesudo apt install gg --versionsudo apt install gdbgdb --version 2.配置环境 2.1在本地新建一个main.cpp #include <iostream> #include <vector> #include <string>using namespace std;int main(…

MySQL资讯|2024年MySQL第一个长期支持版本8.4发布

&#x1f4eb; 作者简介&#xff1a;「六月暴雪飞梨花」&#xff0c;专注于研究Java&#xff0c;就职于科技型公司后端工程师 &#x1f3c6; 近期荣誉&#xff1a;华为云云享专家、阿里云专家博主、腾讯云优秀创作者、ACDU成员 &#x1f525; 三连支持&#xff1a;欢迎 ❤️关注…

【漏洞复现】Emlog Pro 2.3.4——任意用户登入、会话持久化(CVE-2024-5044)

声明&#xff1a;本文档或演示材料仅供教育和教学目的使用&#xff0c;任何个人或组织使用本文档中的信息进行非法活动&#xff0c;均与本文档的作者或发布者无关。 文章目录 漏洞描述漏洞复现 漏洞描述 漏洞编号&#xff1a;CVE-2024-5044 漏洞成因&#xff1a; 在Emlog Pro …

黑马点评DAY5|商户查询缓存

商户查询缓存 缓存的定义 缓存就是数据交换的缓冲区&#xff08;Cache&#xff09;&#xff0c;是存储数据的临时地方&#xff0c;一般读写性能较高。 比如计算机的CPU计算速度非常快&#xff0c;但是需要先从内存中读取数据再放入CPU的寄存器中进行运算&#xff0c;这样会限…

【C语言】union 关键字

在C语言中&#xff0c;union关键字用于定义联合体。联合体是一种特殊的数据结构&#xff0c;它允许不同的数据类型共享同一段内存。所有联合体成员共享同一个内存位置&#xff0c;因此联合体的大小取决于其最大成员的大小。 定义和使用联合体 基本定义 定义一个联合体类型时…

SiCat:一款多功能漏洞利用管理与搜索工具

关于SiCat SiCat是一款多功能漏洞利用管理与搜索工具&#xff0c;该工具基于纯Python 3开发&#xff0c;旨在帮助广大研究人员有效地识别和收集来自开源和本地存储库的漏洞信息。 SiCat专注于网络安全管理方面的实践工作&#xff0c;允许研究人员快速实现在线搜索&#xff0c;…

2024亚太赛(中文赛)数学建模竞赛选题建议+初步分析

提示&#xff1a;DS C君认为的难度&#xff1a;B<C<A&#xff0c;开放度&#xff1a;C<A<B。 综合评价来看 A题适合有较强计算几何和优化能力的团队&#xff0c;难度较高&#xff0c;但适用面较窄。 B题数据处理和分析为主&#xff0c;适合数据科学背景的团队…

Android TextView的属性与用法

文本控件包括TextView、EditText、AutoCompleteTextView、CheckedTextView、MultiAutoCompleteTextView、TextInputLayout等&#xff0c;其中TextView、EditText是最基本最重要的文本控件&#xff0c;是必须要掌握的文本控件。 1.TextView TextView控件用于显示文本信息&…

自然语言处理学习--3

对自然语言处理领域相关文献进行梳理和总结&#xff0c;对学习的文献进行梳理和学习记录。希望和感兴趣的小伙伴们一起学习。欢迎大家在评论区进行学习交流&#xff01; 论文&#xff1a;《ChineseBERT: Chinese Pretraining Enhanced by Glyph and Pinyin Information》 下面…

原厂商是什么意思?云管平台原厂商有哪些企业?

最近不少IT小伙伴在问关于原厂商相关问题&#xff0c;今天我们就来简单回答一下&#xff0c;仅供参考&#xff01; 原厂商是什么意思&#xff1f; 原厂商&#xff0c;或称原厂&#xff0c;是指生产特定产品或零部件的原始厂家。 软件原厂商是什么意思&#xff1f; 软件原厂…

QT截屏,截取控件为图片,指定范围截屏三种截屏方式

项目中我们常用到截取屏幕&#xff0c;Qt给我的们多种方式&#xff1a; 主要有以下三种&#xff1a; 截取全屏&#xff1b;截取控件为图片&#xff1b;指定位置截屏三种截屏方式&#xff1b; 1.截取全屏 常用&#xff1a; 实现&#xff1a; QScreen *screen QGuiApplicat…

数据结构(一)C语言补

数据结构 内存空间划分 一个进程启动后&#xff0c;会生成4G的内存空间 0~3G是用户空间(应用层) 3~4G是内核空间(底层) 0~3G 3~4G 所有的进程都会共享3G~4G的内核空间&#xff0c; 但是每个进程会独立拥有0~3G的用户空间。 栈区 存放数据特点 栈区存放数据的申请空间的先后…

面试篇-Redis-2+持久化+过期key删除+内存淘汰

文章目录 前言一、你知道Redis 数据是怎么持久化的1.1 Redis 持久化的方式Rdb&#xff1a;1.1.1 主动备份save 命令&#xff1a;1.1.2 Redis 中使用bgsave 进行Rdb 的持久化 &#xff1a; 1.2 Redis 持久化的方式Aof&#xff1a;1.2.1 使用AOF 模式进行数据存储&#xff1a;1.2…

明星代言方式8种助力品牌占领市场-华媒舍

1. 明星代言的重要性和市场价值 明星代言是一种常见的品牌推广方式&#xff0c;通过联系知名度高的明星来推广产品或服务&#xff0c;从而提升品牌的知名度和美誉度。明星代言能够借助明星的影响力和粉丝基础&#xff0c;将品牌信息传达给更广泛的受众&#xff0c;从而提高销量…

Web Based Quiz System v1.0 SQL 注入漏洞(CVE-2022-32991)

前言 CVE-2022-32991 是一个影响 Web Based Quiz System v1.0 的 SQL 注入漏洞。这个漏洞存在于 welcome.php 文件中的 eid 参数处。攻击者可以通过此漏洞在数据库中执行任意 SQL 语句&#xff0c;从而获取、修改或删除数据库中的数据。 具体细节如下&#xff1a; 攻击向量&…

Es结合springboot(笔记回忆)

导包 <!--导入es--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> <dependency><groupId>org.springframework.boot<…

【代码随想录】【算法训练营】【第53天】 [739]每日温度 [496]下一个更大元素I [503]下一个更大元素II

前言 思路及算法思维&#xff0c;指路 代码随想录。 题目来自 LeetCode。 day 48&#xff0c;周六&#xff0c;不能再坚持~ 题目详情 [739] 每日温度 题目描述 739 每日温度 解题思路 前提&#xff1a;寻找任一个元素的右边比自己大的元素的位置 思路&#xff1a;通常…

软信天成:您的数据仓库真的“达标”了吗?

在复杂多变的数据环境中&#xff0c;您的数据仓库是否真的“达标”了&#xff1f;本文将深入探讨数据仓库的定义、合格标准及其与数据库的区别&#xff0c;帮助您全面审视并优化您的数据仓库。 一、什么是数据仓库&#xff1f; 数据仓库是一个面向主题的、集成的、相对稳定的、…

一个R包完成单细胞基因集富集分析 (全代码)

singleseqgset是用于单细胞RNA-seq数据的基因集富集分析的软件包。它使用简单的基础统计量&#xff08;variance inflated Wilcoxon秩和检验&#xff09;来确定不同cluster中感兴趣的基因集的富集。 Installation library(devtools) install_github("arc85/singleseqgse…