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

C语言——结构体

一、结构体的创建

1、定义

在 C 语言中,结构体是一种自定义的数据类型,它允许将不同类型的数据项组合成一个单一实体。这在组织复杂数据时非常有用,因为它可以将有逻辑关系的数据组合在一起。结构体是一些值的集合,这些值是结构成员变量。

2、结构体的声明格式

结构体定义由关键字 struct 和结构体名组成,结构体名可以根据需要自行定义。

struct tag {member-listmember-listmember-list  ...
} variable-list ;struct 结构体标签
{变量定义;变量定义;变量定义;...
} 结构变量;

tag 是结构体标签。

member-list 是标准的变量定义,比如 int i; 或者 float f;,或者其他有效的变量定义。

variable-list 结构变量,定义在结构的末尾,最后一个分号之前,您可以指定一个或多个结构变量。

在一般情况下,tag、member-list、variable-list 这 3 部分至少要出现 2 个。

3、结构体的声明实例

(1)没有具体标签(匿名)

    //此声明声明了拥有3个成员的结构体,分别为int类型的a,char类型的的b和double类型的c//同时又声明了结构体变量s1//这个结构体并没有标明其标签struct{int a;char b;double c;} s1;

(2)有具体标签

    //此声明声明了拥有3个成员的结构体//结构体的标签被命名为Student,没有声明变量struct Student{int age;char name[20];int height;};

(3)同时声明变量

    //此声明声明了拥有3个成员的结构体//结构体的标签被命名为Person,同时声明变量struct Person{int age;char name[20];int height;};

在上面的声明中,第二个和第三个声明被编译器当作两个完全不同的类型,即使他们的成员列表是一样的。因为它们的标签名不一样,即使两个结构体的成员列表完全相同,如果它们被声明为不同的类型(即使是匿名的),那么它们仍然是不同的类型。

4、结构体变量的初始化

在C语言中,当您定义一个结构体时,可以为其成员变量提供初始值。这种操作称为结构体的初始化。初始化时,您可以使用大括号{}来包含一系列初始化器,这些初始化器的顺序应当与结构体定义中的成员声明顺序一致。每个初始化器由逗号分隔。

(1)基本的结构体定义和初始化:

struct Person {int age;char name[20];int height;
};struct Person z = { 18, "zhangsan", 180 };

(2)匿名结构体的定义和初始化

为了声明一个匿名结构体的实例,需要先给结构体定义一个别名,或者直接在声明时提供一个变量名。如果想要声明一个匿名结构体并立即创建一个该类型的实例,可以用下列方法:

(i)直接在声明时初始化结构体变量:

struct {int age;char name[20];int height;
} z = { 18, 'zhangsan', 180 };

(ii)给匿名结构体定义一个别名:

typedef struct
{int age;char name[20];int height;
} Person;Person z = { 18, "zhangsan", 180 };
Person w = { 19, "wanger", 190 };

这里初始化变量时不能用:

struct Person z = { 18, "zhangsan", 180 };

这是错误的。

因为使用了typedef,所以在定义变量时应该直接使用别名Person,而不是struct Person。正确的声明应该是:

Person z = { 18, "zhangsan", 180 };

如果使用struct Person,编译器会认为你正在尝试声明一个新的、不同的结构体类型,它没有找到这个新类型的定义,因此会报告“不完整的类型”的错误。

这与有标签的结构体不同。

5、结构体的成员

(1)成员种类

在C语言中,结构体的成员可以是几乎任何类型,包括:

  1. 基本数据类型:如 int, float, double, char 等。

  2. 数组类型:可以是基本数据类型的数组,例如 int numbers[10];,也可以是结构体类型的数组。

  3. 指针类型:包括指向基本数据类型、数组、其他结构体或者函数的指针。

  4. 结构体类型

    • 同类型的结构体指针(因为直接包含同类型的结构体会造成无限大小的定义)。
    • 其他类型的结构体或结构体数组,常用于嵌套结构体。
  5. 联合体(union)类型:可以包含联合体,它是一种特殊的数据结构,允许在相同的内存位置存储不同的数据类型。

  6. 枚举类型(enum):可以包含枚举类型成员,用于表示成员变量只能取有限个命名的整数值。

  7. 函数指针类型:可以包含指向函数的指针,这允许结构体“拥有”可以调用的函数。

下面是一个包含不同类型成员的结构体示例:

#include <stdio.h>// 声明一个枚举类型
enum Color
{ RED, GREEN, BLUE 
};// 定义一个结构体类型
struct Example
{int integer;                   // 基本数据类型double floating_point;         // 基本数据类型char character;                // 基本数据类型char string[100];              // 数组类型int *pointer;                  // 指针类型struct Nested{float nested_floating_point;} nested_struct;               // 嵌套结构体类型union{int union_int;float union_float;} union_member;                // 联合体类型enum Color color;               // 枚举类型void (*function_pointer)(void); // 函数指针类型
};// 一个简单的函数,之后会被赋给结构体中的函数指针
void simpleFunction()
{printf("Hello from simpleFunction!\n");
}int main()
{struct Example example;example.integer = 10;example.floating_point = 3.14;example.character = 'A';example.string[0] = '\0'; // 初始化字符串为空字符串int value = 20;example.pointer = &value; // 指向value的指针example.nested_struct.nested_floating_point = 2.71;example.union_member.union_float = 5.55f; // 使用联合体的float成员example.color = RED; // 枚举类型成员赋值example.function_pointer = simpleFunction; // 函数指针赋值// 使用函数指针调用函数example.function_pointer();return 0;
}

(2)结构体内包含其他结构体或包含指向自己结构体类型的指针

结构体的成员可以包含其他结构体,也可以包含指向自己结构体类型的指针,而通常这种指针的应用是为了实现一些更高级的数据结构如链表和树等。

以下是一个使用自引用指针的结构体定义,这个结构体可以用来实现一个简单的单向链表节点:

#include <stdio.h>struct ListNode
{int value;           // 这个节点存储的数据struct ListNode* next;  // 指向下一个节点的指针
};int main()
{// 创建链表节点struct ListNode node1;node1.value = 1;node1.next = NULL; // 目前链表只有一个节点,所以next指向NULL// 添加第二个节点struct ListNode node2;node2.value = 2;node2.next = NULL;// 将第一个节点的next指针指向第二个节点node1.next = &node2;// 现在,node1.next指向node2,形成了一个包含两个节点的链表return 0;
}

如果两个结构体互相包含,则需要对其中一个结构体进行不完整声明,如下所示:

	struct B;//对结构体B进行不完整声明	     struct A//结构体A中包含指向结构体B的指针{struct B* partner;//other members;};//结构体B中包含指向结构体A的指针,在A声明完后,B也随之进行声明struct B{struct A* partner;//other members;};

二、结构体的使用

1、. 点操作符(成员访问操作符)

格式:

结构体变量.成员

实例:

#include <stdio.h>struct Student
{char name[20];double height;int age;
};int main()
{struct Student a = {"xiaoa",1.80,19};printf("%s %lf %d",a.name,a.height,a.age);return 0;
}

运行结果:

也可以使用指针,但 . 操作符的优先级大于 * 操作符,要加()

#include <stdio.h>struct Student
{char name[20];double height;int age;
};int main()
{struct Student a = {"xiaoa",1.80,19};struct Student* pa = &a;printf("%s %lf %d",(*pa).name,(*pa).height,(*pa).age);return 0;
}

运行结果:

2、->箭头操作符(成员访问操作符)

格式:

结构体变量的指针->成员

实例:

#include <stdio.h>struct Student
{char name[20];double height;int age;
};int main()
{struct Student a = {"xiaoa",1.80,19};struct Student* pa = &a;printf("%s %lf %d\n",pa->name,pa->height,pa->age);return 0;
}

运行结果:

三、结构体做函数参数

1、直接传结构体变量

这种方法占用内存和时间较多,因为要将实参拷贝成形参需要时间,形参存储需要内存空间。

#include <stdio.h>struct Student//定义结构体
{char name[20];double height;int age;
};void print(struct Student student)//定义函数
{printf("名字 %s\n",student.name);printf("身高 %lf\n", student.height);printf("年龄 %d\n", student.age);
}int main()
{struct Student a = {"xiaoa",1.80,19};//定义和初始化结构变量astruct Student b = {"xiaob",1.85,18};//定义和初始化结构变量bprint(a);//利用print函数输出结构变量aprint(b);//利用print函数输出结构变量breturn 0;
}

运行结果:

2、传结构体变量的指针

这种方法更节省空间,不用创建形参。

#include <stdio.h>struct Student//定义结构体
{char name[20];double height;int age;
};void print(struct Student *student)
{printf("名字 %s\n", student->name);printf("身高 %lf\n", student->height);printf("年龄 %d\n", student->age);
}int main()
{struct Student a = { "xiaoa",1.80,19 };//定义和初始化结构变量astruct Student b = { "xiaob",1.85,18 };//定义和初始化结构变量bprint(&a);//传入结构体变量a的地址print(&b);//传入结构体变量b的地址return 0;
}

运行结果:

相关文章:

C语言——结构体

一、结构体的创建 1、定义 在 C 语言中&#xff0c;结构体是一种自定义的数据类型&#xff0c;它允许将不同类型的数据项组合成一个单一实体。这在组织复杂数据时非常有用&#xff0c;因为它可以将有逻辑关系的数据组合在一起。结构体是一些值的集合&#xff0c;这些值是结构…...

基于多反应堆的高并发服务器【C/C++/Reactor】(中)Buffer的创建和销毁、扩容、写入数据

TcpConnection:封装的就是建立连接之后得到的用于通信的文件描述符&#xff0c;然后基于这个文件描述符&#xff0c;在发送数据的时候&#xff0c;需要把数据先写入到一块内存里边&#xff0c;然后再把这块内存里边的数据发送给客户端&#xff0c;除了发送数据&#xff0c;剩下…...

【Linux】常用的基本命令指令①

前言&#xff1a;从今天开始&#xff0c;我们逐步的学习Linux中的内容&#xff0c;和一些网络的基本概念&#xff0c;各位一起努力呐&#xff01; &#x1f496; 博主CSDN主页:卫卫卫的个人主页 &#x1f49e; &#x1f449; 专栏分类:数据结构 &#x1f448; &#x1f4af;代码…...

活动运营常用的ChatGPT通用提示词模板

活动目标确定&#xff1a;如何明确活动的目标&#xff0c;确保活动策划与执行的方向性&#xff1f; 活动主题选择&#xff1a;如何选择吸引人的活动主题&#xff0c;提高用户的参与度和兴趣&#xff1f; 活动形式策划&#xff1a;如何根据活动目标和主题&#xff0c;选择适合…...

SpringBoot 中实现订单30分钟自动取消的策略

简介 在电商和其他涉及到在线支付的应用中&#xff0c;通常需要实现一个功能&#xff1a;如果用户在生成订单后的一定时间内未完成支付&#xff0c;系统将自动取消该订单。 本文将详细介绍基于Spring Boot框架实现订单30分钟内未支付自动取消的几种方案&#xff0c;并提供实例…...

像专家一样使用TypeScript映射类型

掌握TypeScript的映射类型&#xff0c;了解TypeScript内置的实用类型是如何工作的。 您是否使用过Partial、Required、Readonly和Pick实用程序类型? 你知道他们内部是怎么运作的吗? 如果您想彻底掌握它们并创建自己的实用程序类型&#xff0c;那么不要错过本文所涵盖的内容。…...

Golang 结构体

前言 在 Go 语言中&#xff0c;结构体&#xff08;struct&#xff09;是一种自定义的数据类型&#xff0c;将多个不同类型的字段&#xff08;fields&#xff09;组合在一起 结构体通常用于模拟真实世界对象的属性和行为 定义结构体 可以使用 type 关键字和 struct 关键字来定…...

服务器运行状况监控工具

服务器运行状况监视提供了每个服务器状态和性能的广泛概述&#xff0c;通过监控服务器指标&#xff0c;如 CPU 使用率、内存消耗、I/O、磁盘使用率、进程等&#xff0c;服务器运行状况监控可以避免服务器停机。 服务器性能监控指标 服务器是网络中最重要的组件之一&#xff0…...

2022年全国职业院校技能大赛软件测试赛题卷②—自动化测试解析报告(含术语)

2022年全国职业院校技能大赛软件测试任务四 自动化测试 目录 第一题:按照以下步骤在PyCharm中进行自动化测试脚本编写,并执行脚本。...

497 蓝桥杯 成绩分析 简单

497 蓝桥杯 成绩分析 简单 //C风格解法1&#xff0c;*max_element&#xff08;&#xff09;与*min_element&#xff08;&#xff09;求最值 //时间复杂度O(n)&#xff0c;通过率100% #include <bits/stdc.h> using namespace std;using ll long long; const int N 1e4 …...

一、HTML5简介

一、简介 超文本标记语言&#xff08;英语&#xff1a;HyperText Markup Language&#xff0c;简称&#xff1a;HTML&#xff09;是一种用于创建网页的标准标记语言。可以使用 HTML 来建立自己的 WEB 站点&#xff0c;HTML 运行在浏览器上&#xff0c;由浏览器来解析。 <!…...

视频云存储/视频智能分析平台EasyCVR在麒麟系统中无法启动该如何解决?

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…...

前端性能优化之图像优化

图像优化问题主要可以分为两方面&#xff1a;图像的选取和使用&#xff0c;图像的加载和显示。 图像基础 HTTP Archive上的数据显示&#xff0c;网站传输的数据中&#xff0c;60%的资源都是由各种图像文件组成的&#xff0c;当然这些是将各类型网站平均的结果&#xff0c;单独…...

微信小程序封装vant 下拉框select 单选组件

先上效果图&#xff1a; 主要是用vant 小程序组件封装的&#xff1a;vant 小程序ui网址&#xff1a;vant-weapp 主要代码如下: 先封装子组件&#xff1a; select-popup 放在 components 文件夹里面 select-popup.wxml: <!--pages/select-popup/select-popup.wxml--> &…...

c语言试卷

江西财经大学IT帮 2020&#xff0d;2021第一学期期末C语言模拟考试试卷 课程名称&#xff1a;C语言程序设计(软件)&#xff08;主干课程&#xff09; 适用对象&#xff1a;21级本科 试卷命题人 钟芳盛 游天悦 李俊贤 万军豪 张位 试卷审核人 钟芳盛 一、单项…...

文献阅读:Sparse Low-rank Adaptation of Pre-trained Language Models

文献阅读&#xff1a;Sparse Low-rank Adaptation of Pre-trained Language Models 1. 文章简介2. 具体方法介绍 1. SoRA具体结构2. 阈值选取考察 3. 实验 & 结论 1. 基础实验 1. 实验设置2. 结果分析 2. 细节讨论 1. 稀疏度分析2. rank分析3. 参数位置分析4. 效率考察 4.…...

NCC基础开发技能培训

YonBuilder for NCC 是一个带插件的eclipse工具&#xff0c;跟eclipse没什么区别 NC Cloud2021.11版本开发环境搭建改动 https://nccdev.yonyou.com/article/detail/495 不管是NC Cloud 新手还是老NC开发&#xff0c;在开发NC Cloud时开发环境搭建必看&#xff01;&#xff…...

Flink中的状态管理

一.Flink中的状态 1.1 概述 在Flink中&#xff0c;算子任务可以分为有状态和无状态两种状态。 无状态的算子任务只需要观察每个独立事件&#xff0c;根据当前输入的数据直接转换输出结果。例如Map、Filter、FlatMap都是属于无状态算子。 而有状态的算子任务&#xff0c;就…...

【linux】线程互斥

线程互斥 1.线程互斥2.可重入VS线程安全3.常见锁的概念 喜欢的点赞&#xff0c;收藏&#xff0c;关注一下把&#xff01; 1.线程互斥 到目前为止我们学了线程概念&#xff0c;线程控制接下来我们进行下一个话题&#xff0c;线程互斥。 有没有考虑过这样的一个问题&#xff0c…...

机器学习原理到Python代码实现之LinearRegression

Linear Regression 线性回归模型 该文章作为机器学习的第一篇文章&#xff0c;主要介绍线性回归模型的原理和实现方法。 更多相关工作请参考&#xff1a;Github 算法介绍 线性回归模型是一种常见的机器学习模型&#xff0c;用于预测一个连续的目标变量&#xff08;也称为响应变…...

Java 8 Stream API 入门到实践详解

一、告别 for 循环&#xff01; 传统痛点&#xff1a; Java 8 之前&#xff0c;集合操作离不开冗长的 for 循环和匿名类。例如&#xff0c;过滤列表中的偶数&#xff1a; List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

2025盘古石杯决赛【手机取证】

前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来&#xff0c;实在找不到&#xff0c;希望有大佬教一下我。 还有就会议时间&#xff0c;我感觉不是图片时间&#xff0c;因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

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

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

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

使用LangGraph和LangSmith构建多智能体人工智能系统

现在&#xff0c;通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战&#xff0c;比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机&#xff08;无人驾驶飞行器&#xff0c;UAV&#xff09;技术的快速发展&#xff0c;其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统&#xff0c;无人机的“黑飞”&…...

接口自动化测试:HttpRunner基础

相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具&#xff0c;支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议&#xff0c;涵盖接口测试、性能测试、数字体验监测等测试类型…...