当前位置: 首页 > news >正文

【C语言】结构类型的定义和使用

目录

1.结构体(struct)类型 

2.结构标记 

3.typedef

4.定义结构数组的方法 

5.调用结构数组的方法 

6.将结构体传入函数

7.结构体使用实例


1.结构体(struct)类型 

在C语言中,结构体(struct)类型是一种用户自定义的复合数据类型,用于组合不同类型的数据成员在一个单独的对象中。结构体类型的定义可以包含多个数据成员,每个数据成员可以是不同的数据类型。结构体类型的语法如下:

struct 结构体名 {数据类型 成员名1;数据类型 成员名2;// ...
};

以下是一个示例:

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

上述代码定义了一个名为student的结构体类型,包含了四个数据成员:idnameagescore,分别为整型、字符数组型、整型和浮点型。该结构体类型可以用于定义表示学生的对象,每个对象包括了学生的ID、姓名、年龄和分数。结构体类型创建后,需要通过声明一个结构体变量来实际分配内存,例如:

struct student s; // 声明一个名为s的结构体变量,表示一个学生
s.id = 1001; // 设置学生的ID为1001
strncpy(s.name, "Tom", sizeof(s.name)); // 设置学生的姓名为Tom
s.age = 20; // 设置学生的年纪为20
s.score = 90.5; // 设置学生的分数为90.5

2.结构标记 

C语言中,结构标记指的是定义一个结构体类型的名称,而不是直接定义结构体变量。结构标记的声明格式如下:

struct 结构体名称;

例如,以下是一个结构标记的声明:

struct student;

这个声明定义了一个名为"student"的结构体类型,但没有定义具体的结构体成员。这是因为结构标记只是为结构体类型分配了一个名称,而没有为它分配内存空间。

结构标记的主要作用是方便在后面的代码中使用结构体类型。可以使用结构标记名称来声明结构体变量、作为函数参数类型以及作为函数返回类型等。

3.typedef

C语言中,typedef是一种定义类型别名的关键字。它的用法如下:

  • 声明简单类型别名
typedef 原类型别名 新类型别名;

例如:

typedef int INT;
INT a = 1;

这样将int类型的a定义为INT类型的变量。

  • 声明结构体类型别名
typedef struct 原类型别名 新类型别名;

例如:

typedef struct date {int year;int month;int day;
} DATE;
DATE d = {2021, 10, 1};

这样将struct date类型的d定义为DATE类型的变量。

  • 声明指针类型别名
typedef 原类型别名 * 新类型别名;

例如:

typedef int * PTR_INT;
int i = 1;
PTR_INT ptr_i;
ptr_i = &i;

这样将int类型的指针定义为PTR_INT类型的指针变量。

使用typedef可以使代码更加简洁易懂,提高代码的可读性。

4.定义结构数组的方法 

定义结构数组的方法如下:

struct student {char name[20];int age;char gender;
};struct student stu[3]; // 定义一个包含3个元素的结构数组

这里定义了一个结构体 student,包含了学生的姓名、年龄和性别,然后通过结构体定义一个包含3个元素的结构数组 stu

5.调用结构数组的方法 

调用结构数组的方法如下:

#include <stdio.h>int main() {struct student stu[3] = {{"Tom", 18, 'M'},{"Lucy", 19, 'F'},{"John", 20, 'M'}};for(int i = 0; i < 3; i++) {printf("Name: %s\n", stu[i].name);printf("Age: %d\n", stu[i].age);printf("Gender: %c\n", stu[i].gender);}return 0;
}

这里通过初始化方式给结构数组赋值,然后使用 for 循环输出每个学生的信息。在输出时使用了结构体成员连接运算符 .(点号) 来访问每个学生的姓名、年龄和性别。

C语言中的结构体是一种自定义的数据类型,可以包含多个不同类型的数据成员。结构体的定义可以在函数内部或外部,格式为:

struct 结构体名 {数据类型 成员名1;数据类型 成员名2;...
};

其中,结构体名是自己定义的,可以起任何名字。成员名也可以任意取名,但要符合C语言的命名规则。

结构体变量定义格式为:

struct 结构体名 变量名;

访问结构体成员时使用“.”操作符,格式为:

变量名.成员名

例如:

struct student {char name[20];int age;float score;
};int main() {struct student s1;strcpy(s1.name, "Tom");s1.age = 18;s1.score = 88.5;printf("%s's age is %d, score is %.1f\n", s1.name, s1.age, s1.score);return 0;
}

输出结果为:

Tom's age is 18, score is 88.5

 

6.将结构体传入函数

结构体可以像其他数据类型一样传递给函数。下面是一些示例代码:

假设有以下结构体:

typedef struct Person {char name[30];int age;
} Person;
  • 将结构体作为函数参数

将结构体作为函数的参数,可以通过值传递或指针传递。

void print_person(Person p) {printf("姓名:%s,年龄:%d\n", p.name, p.age);
}void update_person(Person *p) {p->age += 1;
}

在这个示例代码中,我们定义了两个函数。print_person函数用于打印结构体Person中的信息,update_person函数用于修改结构体Person中的信息。print_person函数使用的是值传递,即将结构体Person的值作为参数传递给函数。update_person函数使用的是指针传递,即将结构体Person的指针作为参数传递给函数。

  • 将结构体指针作为函数参数

如果要在函数中修改结构体的值,可以将结构体的指针作为参数传递给函数。这样可以避免在函数内部创建新的结构体副本。

void update_person(Person *p) {p->age += 1;
}

在此示例代码中,我们定义了一个update_person函数,它使用了指针传递。函数使用->运算符来访问结构体中的成员。

调用上述函数的方法如下:

Person person = {"Tom", 20};
print_person(person); // 输出 "姓名:Tom,年龄:20"
update_person(&person);
print_person(person); // 输出 "姓名:Tom,年龄:21"

7.结构体使用实例

利用结构体求投票数

#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define MAX_CANDIDATES 10// 候选人结构体
typedef struct Candidate {char name[50]; // 候选人名字int vote_count; // 票数
} Candidate;int main() {int num_candidates;Candidate candidates[MAX_CANDIDATES];// 获取候选人数量printf("请输入候选人数量(最多%d个):", MAX_CANDIDATES);scanf("%d", &num_candidates);getchar(); // 消耗输入缓冲区中的换行符// 获取候选人信息for (int i = 0; i < num_candidates; i++) {printf("请输入候选人%d的名字:", i+1);fgets(candidates[i].name, 50, stdin);candidates[i].name[strcspn(candidates[i].name, "\n")] = '\0'; // 去除输入缓冲区中的换行符candidates[i].vote_count = 0; // 初始化票数为0}// 投票while (1) {char candidate_name[50];printf("请输入你要投票的候选人名字(输入exit结束投票):");fgets(candidate_name, 50, stdin);candidate_name[strcspn(candidate_name, "\n")] = '\0';if (strcmp(candidate_name, "exit") == 0) {break;}int found = 0;for (int i = 0; i < num_candidates; i++) {if (strcmp(candidate_name, candidates[i].name) == 0) {candidates[i].vote_count++;found = 1;break;}}if (!found) {printf("没有找到名为%s的候选人,请重新输入。\n", candidate_name);}}// 输出投票结果printf("投票结果:\n");for (int i = 0; i < num_candidates; i++) {printf("%s: %d 票\n", candidates[i].name, candidates[i].vote_count);}return 0;
}

在这个例子中,我们定义了一个候选人结构体,包含了候选人的名字和票数。在程序运行时,首先获取候选人数量和候选人信息,并初始化各个候选人的票数为0。然后,利用一个循环获取用户输入的投票信息,直到用户输入exit为止。每次获取到用户输入的候选人名字后,我们遍历候选人数组,查找是否有对应的候选人。如果找到了,则给该候选人的票数加1;否则输出错误提示信息。最后,我们输出投票结果,显示每个候选人的名字和票数。

 

相关文章:

【C语言】结构类型的定义和使用

目录 1.结构体&#xff08;struct&#xff09;类型 2.结构标记 3.typedef 4.定义结构数组的方法 5.调用结构数组的方法 6.将结构体传入函数 7.结构体使用实例 1.结构体&#xff08;struct&#xff09;类型 在C语言中&#xff0c;结构体&#xff08;struct&#xf…...

C++内存管理:其二、数组内存管理

一、new一个对象数组 如果我们想在堆内存上创建一个对象数组&#xff0c;可以这么写&#xff1a; Complex * pca new Complex[3]; 主要做三件事&#xff1a; &#xff08;1&#xff09;申请一块内存&#xff0c;足够放置三个Complex对象。 &#xff08;2&#xff09;执行三次…...

No169.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…...

Hadoop设置hdfs全局指令

在终端进入用户个人环境变量配置文件 vim ~/.bashrc 然后添加如下内容 export PATH$PATH:/usr/local/hadoop/bin 添加到你的hadoop下载目录的bin目录为止就可以了 重新激活一下配置文件 source ~/.bashrc hdfs有专属于自己的文件存储目录,加上特殊的指令就可以箱终端一…...

IDEA 2023.1.3图文安装教程及下载

IDEA 2023.1 最新变化是在 IDEA 2023.1 中&#xff0c;对新 UI 做出了大量改进。实现了性能增强&#xff0c;从而更快导入 Maven&#xff0c;以及在打开项目时更早提供 IDE 功能。 新版本通过后台提交检查提供了简化的提交流程。 IntelliJ IDEA Ultimate 现在支持 Spring Secur…...

【JVM】运行时数据区(内存区域划分)详解

文章目录 前言一、JVM 运行时数据区1, 堆2, Java 虚拟机栈3, 本地方法栈4, 程序计数器5, 元数据区 / 方法区 二、内存异常问题1, 栈溢出2, 内存溢出3, 内存泄露 总结 前言 &#x1f4d5;各位读者好, 我是小陈, 这是我的个人主页 &#x1f4d7;小陈还在持续努力学习编程, 努力通…...

Python-Scrapy框架(框架学习)

一、概述 Scrapy是一个用于爬取网站数据的Python框架&#xff0c;可以用来抓取web站点并从页面中提取结构化的数据。 基本组件&#xff1a; 引擎(Engine)&#xff1a;负责控制整个爬虫的流程&#xff0c;包括调度请求、处理请求和响应等。 调度器(Scheduler)&#xff1a;负责…...

flink生成水位线记录方式--基于特殊记录的水位线生成器

背景 在flink基于事件的时间处理中&#xff0c;水位线记录的生成是一个很重要的环节&#xff0c;本文就来记录下几种水位线记录的生成方式的其中一种&#xff1a;基于特殊记录的水位线生成器 基于特殊记录的水位线生成器 我们发送的事件中&#xff0c;如果带有某条特殊记录的…...

Arcgis日常天坑问题(1)——将Revit模型转为slpk数据卡住不前

这段时间碰到这么一个问题&#xff0c;revit模型在arcgis pro里导出slpk的时候&#xff0c;卡在98%一直不动&#xff0c;大约有两个小时。 首先想到的是revit模型过大&#xff0c;接近300M。然后各种减小模型测试&#xff0c;还是一样的问题&#xff0c;大概花了两天的时间&am…...

JavaWeb:上传文件

1.建普通maven项目&#xff0c;或者maven项目&#xff0c;这里以普通maven为例&#xff0c;区别的jar包的导入方式啦 到中央仓库下载哦 2.结构 3.写fileservlet public class FileServlet extends HttpServlet {Overrideprotected void doPost(HttpServletRequest req, HttpSe…...

STM32 大小端与字节对齐使用记录

大小端 串口数据包解析 MDK stm32 小段模式 接收到的数据包&#xff1a; DD 03 00 1B 11 59 00 00 00 00 17 70 00 00 2F 39 00 00 00 00 00 03 23 64 00 0E 02 0B 6E 0B 84 FC EA 77 其中数据内容为&#xff1a; DD 03 00 1B 11 59 //电压mV 00 00 00 00 17 70 …...

RabbitMQ中basic**方法汇总与参数解释

当使用RabbitMQ进行消息传递时&#xff0c;Channel对象提供了一组称为"basic方法"的方法&#xff0c;用于执行最基本的消息传递操作。在本篇博客中&#xff0c;我们将详细介绍这些方法&#xff0c;包括示例和参数解释。 1. basicPublish 方法 basicPublish 方法用于…...

linux之/etc/default/useradd文件

/etc/default/useradd文件是在使用useradd添加用户时&#xff0c;一个需要调用的默认的配置文件之一&#xff0c;可以使用命令"useradd -D"进行修改。 useradd用法&#xff1a; [rootcentos79-3 mail]# useradd --help Usage: useradd [options] LOGINuseradd -Dus…...

3.primitive主数据类型和引用 认识变量

3.1 声明变量 Java注重类型。它不会让你做出把长颈鹿类型变量装进兔子类型变量中这种诡异又危险的举动——如果有人对长颈鹿调用“跳跃”这个方法会发生什么样的悲剧&#xff1f;并且它也不会让你将浮点数类型变量放进整数类型的变量中&#xff0c;除非你先跟编译器确认过数字…...

【群智能算法改进】一种改进的光学显微镜算法 IOMA算法[1]【Matlab代码#60】

文章目录 【获取资源请见文章第5节&#xff1a;资源获取】1. 光学显微镜算法&#xff08;OMA&#xff09;1.1 物镜放大倍数1.2 目镜放大倍数 2. 改进后的IOMA算法2.1 透镜成像折射方向学习 3. 部分代码展示4. 仿真结果展示5. 资源获取说明 【获取资源请见文章第5节&#xff1a;…...

第三课-软件升级-Stable Diffusion教程

前言: 虽然第二课已经安装好了 SD,但你可能在其它地方课程中,会发现很多人用的和你的界面差距很大。这篇文章会讲一些容易忽略或者常常需要做的操作,不一定要完全照做,以后再回过头看看也可以。 1.控制类型 问题:为什么别人有“控制类型”部分,而我没有?如下红色方框…...

【C++】设计模式之——建造者

建造者模式概念模拟实现建造者模式代码实现 建造者模式 首先先大体了解一下&#xff0c;建造者模式是什么意思&#xff0c;它是怎么实现的&#xff1f; 首先&#xff0c;建造者模式是一种创建型设计模式再一个它是使用多个简单的对象一步一步的搭建出一个复杂的对象它可以将一个…...

【C++】基础语句(学习笔记)

一、分支 1、三种基本结构 顺序结构分支结构循环结构 2、if与switch对比 1&#xff09;使用场景 switch只支持常量值固定相等的分支判断if可以判断区间范围用switch能做的&#xff0c;用if都能做 2&#xff09;性能比较 分支少时&#xff0c;差别不是很大。分支多时&…...

大厂秋招真题【DP】米哈游20230924秋招T2-米小游与魔法少女-奇运

米哈游20230924秋招T2-米小游与魔法少女-奇运 题目描述与示例 题目描述 米小游都快保底了还没抽到希儿&#xff0c;好生气哦&#xff01;只能打会活动再拿点水晶。 米小游和世界第一可爱的魔法少女 TeRiRi 正在打 BOSS&#xff0c;BOSS 的血量为h&#xff0c;当 BOSS 血量小…...

LVS+Keepalived 高可用集群负载均衡

一.keepalived介绍 1.1.Keepalived实现原理 由多台路由器组成一个热备组&#xff0c;通过共用的虚拟IP地址对外提供服务。 每个热备组内同时只有一台主路由器提供服务&#xff0c;其他路由器处于冗余状态。 若当前在线的路由器失效&#xff0c;则其他路由器会根据设置…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

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 开发者设计的强大库&#xff…...

Rust 开发环境搭建

环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行&#xff1a; rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu ​ 2、Hello World fn main() { println…...

macOS 终端智能代理检测

&#x1f9e0; 终端智能代理检测&#xff1a;自动判断是否需要设置代理访问 GitHub 在开发中&#xff0c;使用 GitHub 是非常常见的需求。但有时候我们会发现某些命令失败、插件无法更新&#xff0c;例如&#xff1a; fatal: unable to access https://github.com/ohmyzsh/oh…...

二维FDTD算法仿真

二维FDTD算法仿真&#xff0c;并带完全匹配层&#xff0c;输入波形为高斯波、平面波 FDTD_二维/FDTD.zip , 6075 FDTD_二维/FDTD_31.m , 1029 FDTD_二维/FDTD_32.m , 2806 FDTD_二维/FDTD_33.m , 3782 FDTD_二维/FDTD_34.m , 4182 FDTD_二维/FDTD_35.m , 4793...

STM32标准库-ADC数模转换器

文章目录 一、ADC1.1简介1. 2逐次逼近型ADC1.3ADC框图1.4ADC基本结构1.4.1 信号 “上车点”&#xff1a;输入模块&#xff08;GPIO、温度、V_REFINT&#xff09;1.4.2 信号 “调度站”&#xff1a;多路开关1.4.3 信号 “加工厂”&#xff1a;ADC 转换器&#xff08;规则组 注入…...

深入解析 ReentrantLock:原理、公平锁与非公平锁的较量

ReentrantLock 是 Java 中 java.util.concurrent.locks 包下的一个重要类,用于实现线程同步,支持可重入性,并且可以选择公平锁或非公平锁的实现方式。下面将详细介绍 ReentrantLock 的实现原理以及公平锁和非公平锁的区别。 ReentrantLock 实现原理 基本架构 ReentrantLo…...

在Spring Boot中集成RabbitMQ的完整指南

前言 在现代微服务架构中&#xff0c;消息队列&#xff08;Message Queue&#xff09;是实现异步通信、解耦系统组件的重要工具。RabbitMQ 是一个流行的消息中间件&#xff0c;支持多种消息协议&#xff0c;具有高可靠性和可扩展性。 本博客将详细介绍如何在 Spring Boot 项目…...