C语言——结构体数组、结构体指针、结构体函数与二级指针
C语言中的结构体(struct
)是一种用户自定义的数据类型,它允许你将不同类型的数据项组合成一个单一的类型。结构体数组则是一种特殊的数组,其元素为结构体类型。这意味着你可以在一个数组中存储多个具有相同结构的记录。
定义结构体数组
首先,你需要定义一个结构体类型,然后才能声明该类型的数组。
定义结构体
typedef struct Student {char *num;int age;double score;char *addr;
}Student;
声明结构体数组
struct Student arr[3];
这里,arr
是一个结构体数组,可以存储3个Student
类型的记录。
初始化结构体数组
可以直接在声明时初始化结构体数组的元素。
struct Student arr[3] = {{"001",22,99.9,"云南"},{"002",23,96.35,"上海"},{"003",21,89.956,"广州"}};
访问结构体数组元素
你可以通过数组索引来访问结构体数组中的元素,并通过点操作符.
来访问结构体成员。
len = sizeof(arr)/sizeof(arr[0]);for(i=0;i<len;i++){printf("学号:%s 年龄:%d 成绩:%.3lf 地址: %s\n",arr[i].num,arr[i].age,arr[i].score,arr[i].addr);}
输出为:
学号:001 年龄:22 成绩:99.900 地址:云南
学号:002 年龄:23 成绩:96.350 地址:上海
学号:003 年龄:21 成绩:89.956 地址:广州
结构体数组的使用场景
结构体数组非常有用,特别是在需要处理具有多个属性的数据集合时。例如,你可以使用结构体数组来存储班级中所有学生的信息,然后遍历这个数组来执行各种操作,如计算平均分、查找成绩最高的学生等。
结构体练习:选票系统
#include<stdio.h>
#include<string.h>struct XuanMin{char name[32];int tickets;
};int main()
{struct XuanMin candidate[3];struct XuanMin max = {"0",0};int len;int i;int j;char tempname[32];int abandon;int abandtick = 0;len = sizeof(candidate)/sizeof(candidate[0]);for(i=0;i<len;i++){candidate[i].tickets = 0;printf("请输入候选人的名字:\n",candidate[i]);scanf("%s",candidate[i].name);}for(j=0;j<5;j++){abandon = 0;printf("请输入所要投的候选人的名字:\n");scanf("%s",tempname);for(i=0;i<3;i++){if(strcmp(tempname,candidate[i].name) == 0){candidate[i].tickets++;abandon = 1;}}if(abandon == 0){printf("无所选候选人,弃票!\n");abandtick++;}}for(i=0;i<3;i++){printf("候选人:%s,票数:%d\n",candidate[i].name,candidate[i].tickets);}for(i=0;i<3;i++){if(max.tickets < candidate[i].tickets){max = candidate[i];}}printf("%s当选,票数:%d,弃票:%d",max.name,max.tickets,abandtick);return 0;
}
输出为:
请输入候选人的名字:
aa
请输入候选人的名字:
bb
请输入候选人的名字:
cc
请输入所要投的候选人的名字:
aa
请输入所要投的候选人的名字:
aa
请输入所要投的候选人的名字:
bb
请输入所要投的候选人的名字:
cc
请输入所要投的候选人的名字:
a
无所选候选人,弃票!
候选人:aa,票数:2
候选人:bb,票数:1
候选人:cc,票数:1
aa当选,票数:2,弃票:1
结构体指针
结构体指针是指向结构体变量的指针,它存储的是结构体变量的内存地址,而不是结构体变量的值本身。使用结构体指针可以方便地访问和操作结构体中的成员,特别是在处理大型数据结构或链表等数据结构时。
定义结构体和结构体指针
首先,你需要定义一个结构体类型,然后才能创建结构体变量和结构体指针。
//定义一个结构体
struct Test{ char cdata;int idata;
};//定义结构体指针
struct Test t1 = {'A',0};
struct Test *pt = &t1;
使用结构体指针访问结构体成员
通过结构体指针访问结构体成员需要使用解引用操作符(->
)。
pt->cdata = 'C';
pt->idata = 1;
printf("t1的cdata=%c,idata=%d\n",t1.cdata,t1.idata);
printf("t1的cdata=%c,idata=%d\n",pt->cdata,pt->idata);
输出为:
t1的cdata=C,idata=1
t1的cdata=C,idata=1
使用场景:结构体数组进行打印
struct Student arr[3] = {{"001",22,99.9,"云南"},{"002",23,96.35,"上海"},{"003",21,89.956,"广州"}
};
struct Student *p;
p = arr;len = sizeof(arr)/sizeof(arr[0]);
for(i=0;i<len;i++){printf("学号:%s 年龄:%d 成绩:%.3lf 地址:%s\n",p->num,p->age,p->score,p->addr);p++;
}
练习:使用结构体指针实现选票系统
使用结构体指针要注意:
1.解引用符要使用“->”
2.每次遍历完循环内要使用p++;
循环外要记得让p重新指向数组头
#include<stdio.h>
#include<string.h>struct XuanMin{char name[32];int tickets;
};int main()
{struct XuanMin candidate[3];struct XuanMin max = {"0",0};int len;int i;int j;char tempname[32];int abandon;int abandtick = 0;struct XuanMin *p = candidate;len = sizeof(candidate)/sizeof(candidate[0]);for(i=0;i<len;i++){p->tickets = 0;printf("请输入候选人的名字:\n");scanf("%s",p->name);p++;}for(j=0;j<5;j++){p = candidate;abandon = 0;printf("请输入所要投的候选人的名字:\n");scanf("%s",tempname);for(i=0;i<3;i++){if(strcmp(tempname,p->name) == 0){p->tickets++;abandon = 1;}p++;}if(abandon == 0){printf("无所选候选人,弃票!\n");abandtick++;}}p = candidate;for(i=0;i<3;i++){printf("候选人:%s,票数:%d\n",p->name,p->tickets);p++;}p = candidate;for(i=0;i<3;i++){if(max.tickets < p->tickets){max = *p;p++;}}printf("%s当选,票数:%d,弃票:%d",max.name,max.tickets,abandtick);return 0;
}
输出为:
请输入候选人的名字:
aa
请输入候选人的名字:
bb
请输入候选人的名字:
cc
请输入所要投的候选人的名字:
aa
请输入所要投的候选人的名字:
aa
请输入所要投的候选人的名字:
bb
请输入所要投的候选人的名字:
cc
请输入所要投的候选人的名字:
a
无所选候选人,弃票!
候选人:aa,票数:2
候选人:bb,票数:1
候选人:cc,票数:1
aa当选,票数:2,弃票:1
结构体在函数中的应用:
一个返回值为结构体变量的函数,一般使用结构体指针进行定义:
struct XuanMin{char name[32];int tickets;
};struct XuanMin* initcandidate(struct XuanMin *p)
{return p;
}
使用函数对选票系统进行封装如下:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>struct XuanMin{char name[32];int tickets;
};struct XuanMin* initcandidate(struct XuanMin *p,int *total) //候选人初始化
{int i;if(p == NULL){printf("请输入候选总人数:\n");scanf("%d",total);p = (struct XuanMin*)malloc(*total*sizeof(struct XuanMin));}for(i=0;i<*total;i++){p->tickets = 0;printf("请输入第%d个候选人的名字:\n",i+1);scanf("%s",p->name);p++;}return p-*total;
}void printicket(struct XuanMin *p,int len) //打印候选人信息
{int i;for(i=0;i<len;i++){printf("候选人:%s,票数:%d\n",p->name,p->tickets);p++;}
}int doVot(struct XuanMin *p,int len) //选民进行投票
{int i;int j;int mark;int abandtick = 0;char tempname[32];struct XuanMin *pbak = p;for(j=0;j<5;j++){p = pbak;mark = 0;printf("请输入所要投的候选人的名字:\n");scanf("%s",tempname);for(i=0;i<3;i++){if(strcmp(tempname,p->name) == 0){p->tickets++;mark = 1;}p++;}if(mark == 0){printf("无所选候选人,弃票!\n");abandtick++;}}return abandtick;
}struct XuanMin* getMax(struct XuanMin *p,int len) //找出票数最高的候选人
{struct XuanMin *max;int i;max = p;for(i=0;i<len;i++){if(max->tickets < p->tickets){max = p;}p++;}return max;
}int main()
{struct XuanMin *candidate = NULL;int *len;struct XuanMin *final;int abandon;candidate = initcandidate(candidate,len);printicket(candidate,*len);abandon = doVot(candidate,*len);printicket(candidate,*len);final = getMax(candidate,*len);printf("%s当选,票数:%d,弃票:%d",final->name,final->tickets,abandon);return 0;
}
注意:
使用结构体变量作为返回值的函数,一般使用的都是结构体指针,即返回的值是结构体指针。
结构体二级指针:
在上边的选票系统中使用initcandidate函数对候选人变量candidate进行初始化,包括候选人的姓名和票数,在initcandidate函数中我们将结构体指针变量candidate传递进去进行初始化,并返回给主函数中。
我们可以使用二级指针将结构体指针变量candidate的地址传递过去,进行操作,就可以将initcandidate初始化函数变为无返回值的函数。同理就像我们把表示候选人数量的变量len的地址传递过去,这样在初始化函数中获得候选人数量len的值以后,不需要使用返回值就能在主函数中获取len的值。
使用结构体二级指针代码如下:
void initcandidate(struct XuanMin **p,int *total)
{int i;if(*p == NULL){printf("请输入候选总人数:\n");scanf("%d",total);*p = (struct XuanMin*)malloc(*total * sizeof(struct XuanMin));}for(i=0;i<*total;i++){(*p)->tickets = 0;printf("请输入第%d个候选人的名字:\n",i+1);scanf("%s",(*p)->name);(*p)++;}*p = *p - *total;
}
注意:使用二级指针访问结构体变量时依旧使用“->”解引用操作符,而且要注意优先级使用“(*p)->tickets”、“(*p)++”这种格式来访问。
相关文章:
C语言——结构体数组、结构体指针、结构体函数与二级指针
C语言中的结构体(struct)是一种用户自定义的数据类型,它允许你将不同类型的数据项组合成一个单一的类型。结构体数组则是一种特殊的数组,其元素为结构体类型。这意味着你可以在一个数组中存储多个具有相同结构的记录。 定义结构体…...

【4】策略模式
如上图所示,如果要加入一个新的货币,那么就需要对类中的Calculate函数进行修改,这违背了封闭开放原则。 上图中的方式更加合适,搞一个抽象类(方法中可以用多态调用),然后每个货币自己是一个类&a…...

BGP 反射器联邦实验
要求: 1.如图连接网络,合理规划IP地址,AS 200内IGP协议为OSPF 2.R1属于AS 100;R2-R3-R4小AS 234 R5-R6-R7小AS 567,同时声明大AS 200,R8属于AS 300 3.R2-R5 R4-R7 之间为联邦EBGP邻居关系 4.R1-R8之…...

stm32入门学习13-时钟RTC
(一)时钟RTC stm32内部集成了一个秒计数器RTC,用于显示我们日常的时间,如日期年月日,时分秒等,RTC的主要原理就是进行每秒自增,如果我们知道开始记秒的开始时间,就可以计算现在的日…...

vuex properties of undefined (reading ‘getters‘)
前言: 最近打算用vue 写个音乐播放器,在搞 vuex 的时候遇到一个很神奇报错;vuex 姿势练了千百次了,刚开始的时候我一直以为是代码问题,反复检查了带了,依旧报错。 Error in mounted hook: "TypeError:…...

再谈表的约束
文章目录 自增长唯一键外键 自增长 auto_increment:当对应的字段,不给值,会自动的被系统触发,系统会从当前字段中已经有的最大值1操作,得到一个新的不同的值。通常和主键搭配使用,作为逻辑主键。 自增长的…...

认识一下测试策略与测试方案
目录 测试方案 测试策略 测试策略的内容主要包括 测试技术和工具 测试启动、停止和完成标准 风险分析和应对方案 测试范围 测试角色和职责 测试方法和类型 测试工具 测试层级 测试指标 测试可交付成果 测试方案的内容包括 测试目标 测试范围 测试环境 测试策略…...
Gradle 查看包的依赖关系
在 Terminal 中可以通过 gradle 的命令查看项目中使用的依赖库及其版本,并且可以更加直观的看到各个模块中库之间的依赖关系。同时也可以跟踪并解决与库版本冲突有关的问题。 工具查看 在 Android Studio 中选择 View > Tool Windoors > Gradle 或者直接选择…...

虚幻5|给攻击添加特效
一,打开武器蓝图 选择武器网格体,在细节处找到组件开始重叠,点击 写下以下蓝图,这是最终蓝图,后面会分讲要点 二,actor拥有标签,就是被击打的敌人,我们给actor添加标签 到主界面&am…...
Delphi包管理与依赖:掌握GetIt与DelphiPI的艺术
标题:Delphi包管理与依赖:掌握GetIt与DelphiPI的艺术 在Delphi的广袤生态中,包管理和依赖解决方案是构建大型项目不可或缺的工具。本文将深入探讨Delphi中的两种主要包管理工具:GetIt包管理器和DelphiPI,通过实际代码…...

如何使用unittest和pytest进行python脚本的单元测试
1. 关于unittest和pytest unittest是python内置的支持单元测试的模块,他提供了核心类,TestCase,让单元测试 代码的编写不再是从0开始,不再是作坊式,而是标准化,模板化,工厂化。 pytest是第三方…...
Java中的值传递与引用传递
Java中的值传递与引用传递 在Java编程中,理解值传递与引用传递的概念是编写无误代码的关键。这两个概念有时会让人感到困惑,特别是当它们与对象有关时。现在,我们将一步步地解释这两个概念,帮助你彻底理解它们。 1. 值传递与引用…...

Seaborn库
目录 主要功能和特点 使用方法 实例应用 Seaborn库的最新版本有哪些新功能和改进? 如何在Seaborn中实现复杂的数据预处理步骤,例如数据清洗和转换? Seaborn与其他数据可视化库(如Matplotlib、Plotly)相比有哪些优…...
openresty整合modsecurity
安装依赖包 安装依赖 yum -y install gcc-c flex bison yajl yajl-devel curl-devel curl GeoIP-devel doxygen zlib-devel libtool libxml2-devel libxslt-devel安装依赖包 ftp://ftp.icm.edu.pl/vol/rzm7/linux-centos-vault/7.8.2003/sclo/x86_64/rh/Packages/d/devtools…...

结构体structure、共用体union
目录 结构体 结构体类型的定义形式 结构体类型的大小 内存计算例子 共用体union 用共用体判断大小端 结构体和共用体对比 qsort() 结构体 结构体类型——用来描述复杂数据的一种数据类型 构造类型(用户自定义类型) struc…...

Spring自动注册-<bean>标签和属性解析
xml文件中最常见也最核心的就是<bean>,<Import>,<beans>,<alias>标签,关于它们的解析主要是BeanDefinitionParserDelegate类中.<bean>标签的解析最为复杂和重要. <bean>标签 processBeanDefinition(ele, delegate)方法中,主要是是对…...
【仿RabbitMQ消息队列】基于C++11中packaged_tack异步线程池
目录 什么是同步和异步? future 使用future和async配合管理异步任务 使用promise和future配合管理异步任务 使⽤std::packaged_task和std::future配合 C11异步线程池 什么是同步和异步? 同步(Synchronous) 同步编程是指程…...

免费下载专利
给大家提供一个可以免费下载专利的地方 链接:https://www.drugfuture.com/cnpat/cn_patent.asp...
CentOS7安装流程步骤详细教程
1. 简介 1.1. 概述 CentOS 7是一款基于Red Hat Enterprise Linux(RHEL)的开源Linux发行版,它提供了一个稳定、安全、高效的操作系统,适用于企业级应用、服务器、云计算等领域。CentOS 7以其高度的稳定性和安全性而闻名,它广泛应用于各种行业和领域,包括政府、金融、医疗、…...

【大模型从入门到精通17】openAI API 构建和评估大型语言模型(LLM)应用5
这里写目录标题 理论问题:实践问题:理论实践 理论问题: 1.描述评估LLM应用程序输出的重要性,并提及至少三个维度,这些输出应该在这几个维度上被评估。 2.解释在评估LLM应用程序时开发稳健的性能指标的作用,…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...

家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...

苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...

回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...

第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10+pip3.10)
第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10pip3.10) 一:前言二:安装编译依赖二:安装Python3.10三:安装PIP3.10四:安装Paddlepaddle基础框架4.1…...
32单片机——基本定时器
STM32F103有众多的定时器,其中包括2个基本定时器(TIM6和TIM7)、4个通用定时器(TIM2~TIM5)、2个高级控制定时器(TIM1和TIM8),这些定时器彼此完全独立,不共享任何资源 1、定…...
Python学习(8) ----- Python的类与对象
Python 中的类(Class)与对象(Object)是面向对象编程(OOP)的核心。我们可以通过“类是模板,对象是实例”来理解它们的关系。 🧱 一句话理解: 类就像“图纸”,对…...

高分辨率图像合成归一化流扩展
大家读完觉得有帮助记得关注和点赞!!! 1 摘要 我们提出了STARFlow,一种基于归一化流的可扩展生成模型,它在高分辨率图像合成方面取得了强大的性能。STARFlow的主要构建块是Transformer自回归流(TARFlow&am…...