【C语言】自定义类型:结构体深入解析(一)

  🌈write in front :

🔍个人主页 : @啊森要自信的主页

✏️真正相信奇迹的家伙,本身和奇迹一样了不起啊!

欢迎大家关注🔍点赞👍收藏⭐️留言📝>希望看完我的文章对你有小小的帮助,如有错误,可以指出,让我们一起探讨学习交流,一起加油鸭。 请添加图片描述

文章目录

  • 📝前言
  • 🌠 什么是结构体?
  • 🌅 结构体类型的声明和创建
  • 🌠 结构体变量的初始化
  • 🌅 结构成员访问操作符
  • 🌠 匿名结构体类型
  • 🌅 结构的⾃引⽤
  • 🚩总结


📝前言

本小节,阿森继续和你一起学习什么是结构体?结构体类型的声明和创建,然后就是结构体的初始化,随即学习结构成员的访问操作符来更好的打印结构体的数据,当然还有匿名结构体类型,和结构的自引用。文章干货满满,接下来我们就学习一下结构体吧 😃!


🌠 什么是结构体?

结构体是一种用户定义的数据类型,它允许用户根据需要组合不同类型的变量。

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

结构体通过struct关键字来定义,它允许将多个不同类型的数据元素组合在一起,这些数据元素称为结构体的成员。

🌅 结构体类型的声明和创建

  1. 结构体类型的声明
struct 结构体类型标签名 
{成员声明1;成员声明2;...
};//分号不能丢

例如:

struct Student//此时只是声明了 Student 类型,
{				//但还没有创建任何 Student 类型的变量。int id;char name[20];float score;
};//分号不能丢
  1. 创建结构体类型的变量的语法如下:
struct 结构体类型名 变量名;

例如:

创建一个名为student1的学生结构体变量:
struct Student student1;
也可以在声明结构体类型的同时创建变量:
struct Stu
{char name[20];//名字int age;//年龄char sex[5];//性别char id[20];//学号
};
struct Stu s1;
struct Stu s2;

3.typedef关键字来为结构体类型定义别名,然后创建结构体变量:

// 首先定义一个结构体类型
struct Student 
{int id;char name[20];
};int main() 
{// 使用typedef为Student结构体类型定义一个别名StudentTypetypedef struct Student StudentType;  // 使用原结构体类型定义变量struct Student st1;// 使用新的类型别名定义变量 StudentType st2;// 访问结构体成员st1.id = 1001;st2.id = 1002;return 0;
}

typedef struct Student StudentType可以理解使用typedefstruct Student重新取了一个名字 StudentType ,此时这个 StudentTye 就是一个类型,比如:int a;这个StudentTye就相当于intStudentType st2 ;当然,这个 struct Student 也可以理解为 int ,所以也可以这么用 struct Student st1 ;

在这里插入图片描述

🌠 结构体变量的初始化

结构体变量的初始化主要有两种方式:

  1. 按照默认顺序初始化:

默认情况下,结构体成员的初始化顺序与它们在结构体定义中的顺序相同。

例如:

struct Stu
{char name[20];//名字int age;//年龄char sex[5];//性别char id[20];//学号
}p1;
struct Stu s1 = { "asenyaozixin",11,"男","2023012018" };
//定义结构体变量s2
  1. 指定顺序初始化:

可以通过在列表中指定成员名来指定成员的初始化顺序:
在这里插入图片描述

例如:

struct Stu
{char name[20];//名字int age;//年龄char sex[5];//性别char id[20];//学号
};
struct Stu s2 = { .age = 66,.id = "2023001001",.name = "ahuibuyiban",.sex = "nv" };

完整示例且打印:

struct Stu
{char name[20];//名字int age;//年龄char sex[5];//性别char id[20];//学号
};
int main()
{struct Stu s1 = { "asenyaozixin",11,"nan","2023012018" };//按照默认顺序初始化struct Stu s2 = { .age = 66,.id = "2024001001",.name = "ahuibuyiban",.sex = "nv" };//指定顺序初始化printf("%s %d %s %s\n", s1.name, s1.age, s1.sex, s1.id);printf("%s %d %s %s\n", s2.name, s2.age, s2.sex, s2.id);return 0;
}

打印结果:
在这里插入图片描述

🌅 结构成员访问操作符

结构成员访问操作符用于访问结构体中的成员变量。

结构体成员的直接访问

  1. 结构体成员的直接访问----点操作符(.)
    使⽤⽅式:结构体变量.成员名

使用点操作符可以访问结构的普通成员,例如:

struct Stu
{char name[20];int age;float score;
} s3 = { "熊大", 33, 66.0f }, s4 = {"熊二", 18, 100.0f};//全局变量int main()
{struct Stu s1 = {"zhangsan", 20, 95.5f};//局部变量struct Stu s2 = {"lisi", 18, 87.5f};struct Stu s5 = {.score= 98.5f, .name="hehe", .age = 18};//. 结构成员访问操作符//结构体变量.成员名//printf("%s %d %f\n", s1.name, s1.age, s1.score);printf("%s %d %f\n", s2.name, s2.age, s2.score);printf("%s %d %f\n", s3.name, s3.age, s3.score);printf("%s %d %f\n", s4.name, s4.age, s4.score);
}

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

  1. 结构体成员的间接访问----箭头操作符(->)
    使⽤⽅式:结构体指针->成员名

结构体变量声明为结构体指针时,使用箭头操作符访问其成员:

struct Stu
{char name[20];int age;float score;
} s3 = { "熊大", 33, 66.0f }, s4 = {"熊二", 18, 100.0f};//全局变量int main()
{struct Stu s1 = {"zhangsan", 20, 95.5f};//局部变量struct Stu s2 = {"lisi", 18, 87.5f};struct Stu s5 = {.score= 98.5f, .name="hehe", .age = 18};//结构体指针struct Stu* p1 = &s1;//取出s1的地址struct Stu* p2 = &s2;//取出s2的地址struct Stu* p3 = &s3;//取出s3的地址struct Stu* p4 = &s4;//取出s4的地址struct Stu* p5 = &s5;//取出s5的地址printf("%s %d %f\n", p1->name, p1->age, p1->score);printf("%s %d %f\n", p2->name, p2->age, p2->score);printf("%s %d %f\n", p3->name, p3->age, p3->score);printf("%s %d %f\n", p4->name, p4->age, p4->score);printf("%s %d %f\n", p5->name, p5->age, p5->score);//结构体指针->成员名return 0;
}

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


🌠 匿名结构体类型

匿名结构体类型就是没有给结构体类型起名字的结构体类型。

匿名结构体的定义方式:

struct 
{成员1 数据类型;成员2 数据类型;...
} 变量名1, 变量名2, ...; 

例如:

struct
{int a;char b;float c;
} x;

匿名结构体的特点是:

  • 不需要给结构体起名字,定义时不指定结构体名称。

  • 只能在定义它的代码块内使用,不能在其他地方再次使用这个匿名结构体类型。

思考:下⾯的两个结构在声明的时候省略掉了结构体标签(tag),然后主函数里的p = &x的代码合法吗?

struct
{int a;char b;float c;
} x;struct
{int a;char b;float c;
} *p;int main()
{p = &x;//?代码合法吗?return 0;
}

输出没问题但有警告:
在这里插入图片描述

警告:
编译器会把上⾯的两个声明当成完全不同的两个类型,所以是⾮法的。
匿名的结构体类型,如果没有对结构体类型重命名的话,基本上只能使⽤⼀次。
在这里插入图片描述


🌅 结构的⾃引⽤

结构的自引用指的是结构体内部包含自己类型的指针成员,通过这个指针可以实现结构体之间的引用关系。

⾃引⽤⽅式:

struct Node{int data;struct Node *next; 
};// Node结构体包含一个指向Node结构体的指针next
// 通过next可以实现链表节点之间的引用关系

在这里插入图片描述

  • 思考1:
    在结构中包含⼀个类型为该结构本⾝的成员是否可以呢?
    ⽐如,定义⼀个链表的节点:
struct Node
{int data;struct Node next;
};

上述代码正确吗?如果正确,那 sizeof(struct Node) 是多少?
仔细分析,其实是不⾏的,因为⼀个结构体中再包含⼀个同类型的结构体变量,这样结构体变量的⼤⼩就会⽆穷的⼤,是不合理的。

代码运行:
在这里插入图片描述
图解分析:
在这里插入图片描述

  • 思考2:
    在结构体⾃引⽤使⽤的过程中,夹杂了 typedef 匿名结构体类型重命名,也容易引⼊问题,看看下⾯的代码,可⾏吗?
typedef struct 
{int data;//存放数据Node* next;//存放写一个节点的地址
}Node;
int main()
{return 0;
}

运行:
在这里插入图片描述
分析:
首先使用typedef给前面匿名结构体起了别名Node还不是类型,但是在typedef语句内,struct定义部分还没有结束,所以在struct内部使用Node声明next时,Node类型还未通typedef获得定义,仅仅是对匿名结构体的一个重命名,就提前使⽤Node类型来创建成员变量。

解决⽅案如下:定义结构体不要使⽤匿名结构体了
如下:
先定义结构体:

struct Node{int data;struct Node* next; 
}

再使用typedef给它起别名:

typedef struct Node Node;

或者一步完成:

typedef struct Node
{int data;struct Node* next;
} Node;

🚩总结

这次阿森和你一起学习结构体的结构体类型的声明和创建,初始化,访问操作符,这是结构体基础知识,但阿森会慢慢和你一起学习,从基础到进阶。感谢你的收看,如果文章有错误,可以指出,我不胜感激,让我们一起学习交流,如果文章可以给你一个小小帮助,可以给博主点一个小小的赞😘

请添加图片描述

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

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

相关文章

编辑器Sublime text 常用快捷命令 列模式 替换空行

平替notepad 下载可取官网 www.sublimetext.com 据说可以无限试用,没有功能限制 1、快速删除空行 ctrl h选择正则表达式 .*Find输入: ^(\t)*$\nReplace输入:点击Replace All 2、快速选择指定字符 用鼠标选中alt f3修改 3、列编辑模式 ct…

WEB渗透—PHP反序列化(五)

Web渗透—PHP反序列化 课程学习分享(课程非本人制作,仅提供学习分享) 靶场下载地址:GitHub - mcc0624/php_ser_Class: php反序列化靶场课程,基于课程制作的靶场 课程地址:PHP反序列化漏洞学习_哔哩…

win10环境下git安装和基础操作

简述 关于git的作用就不多赘述了,配合GitHub,达到方便人们日常项目维护和管理,每一次项目增删改查都可以看的清清楚楚,方便团队协作和个人项目日常维护。 下载git 首先我们自然是要到官网下载git,下载地址为https:/…

无框架Java转go语言写http与tcp请求

项目地址 https://github.com/cmdch2017/http_tcpServer 项目结构 如何快速上手 http篇 1、controller包就相当于RestController,这里返回了一个Person对象,当你需要新建一个接口时,再新写一个func仿照下面的方法就行了 package control…

创建型模式之抽象工厂模式

一、概述 1、抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。 2、抽象工厂模式:一个工厂可以生产一系列产品(一族产品),极大减少了工厂类的数量 3、抽象工厂模式&am…

SpringBoot配置mysql加密之Druid方式

一、导入Druid依赖 <dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.22</version> </dependency>二、生成密文 方式1. 找到存放druid jar包的目录 1-1、在目录…

局域网其他pc如何访问宿主机虚拟机IP?

文章目录 背景贝瑞蒲公英设置虚拟机网络连接测试 背景 使用贝瑞蒲公英异地组网&#xff0c;将家里的pc作为pgsql服务器在公司使用&#xff0c;但是虚拟机的ip和端口访问不了 贝瑞蒲公英 设置虚拟机网络 就是添加端口转发规则 连接测试 公网内其他pc连接测试 可以看到已经连接成…

教你玩转Shopify独立站!六招运营技巧不可错过

作为一个新手卖家&#xff0c;想要在 Shopify 上运营自己的独立站&#xff0c;可能会感到有些困惑。不过&#xff0c;只要掌握了一些技巧&#xff0c;就可以轻松上手。今天就为大家介绍六个运营 Shopify 独立站的技巧&#xff0c;帮助大家更好玩转 Shopify 独立站&#xff01; …

隐私计算介绍

这里只对隐私计算做一些概念性的浅显介绍&#xff0c;作为入门了解即可 目录 隐私计算概述隐私计算概念隐私计算背景国外各个国家和地区纷纷出台了围绕数据使用和保护的公共政策国内近年来也出台了数据安全、隐私和使用相关的政策法规 隐私计算技术发展 隐私计算技术安全多方计…

【vSphere | PowerCLI】使用 PowerCLI 连接 vCenter 查看 VM 故障排错

这里写目录标题 1. 连接vCenter Server2. 客户机操作系统内提供网络配置信息3. 创建VM4. 迁移VM5.故障排错连接 VC 报错&#xff1a; Error: Invalid server certificate解决方法 参考资料 1. 连接vCenter Server PS C:\Users\Administrator> Connect-VIServer 192.168.1.1…

Kubernetes (k8s) 快速认知

应用部署方式 传统部署时代 早期的时候&#xff0c;各个组织是在物理服务器上运行应用程序。缺点 资源分配问题&#xff1a; 无法限制在物理服务器中运行的应用程序资源使用 维护成本问题&#xff1a; 部署多个物理机&#xff0c;维护许多物理服务器的成本很高 虚拟化部署时…

【Qt之Quick模块】1. 概述及Quick应用程序创建流程

概述 Qt的Quick模块是用于创建现代化、动态和响应式用户界面的工具集。它是基于QML&#xff08;Qt Meta-Object Language&#xff09;和JavaScript的。 QML是一种声明性的语言&#xff0c;用于描述用户界面的结构和行为。它使用层叠样式表&#xff08;CSS&#xff09;的语法来…

轻量化压缩之【剪枝】

在深度学习领域&#xff0c;剪枝是一种常用的模型轻量化技术&#xff0c;主要是通过移除神经网络中被认为不重要的连接&#xff08;即权重&#xff09;来减少模型的大小和计算量。移除的连接可以是单独的权重&#xff08;非结构化剪枝&#xff09;&#xff0c;也可以是整个神经…

RabbitMQ入门案例

RabbitMQ 是目前比较主流的MQ消息队列中间件&#xff0c;下面简单总结RabbitMQ入门时所做的一些笔记 1.RabbitMQ 入门案例 需求&#xff1a;用 Java 编写两个程序。发送单个消息的生产者和接收消息并打印出来的消费者 1.1 添加依赖 <!--rabbitmq 依赖客户端--> <de…

美颜SDK是什么?视频美颜SDK在直播平台中的集成与接入教程详解

当下&#xff0c;主播们追求更加自然、精致的外观&#xff0c;而观众也期待在屏幕前欣赏到更为清晰、美丽的画面。为了满足这一需求&#xff0c;美颜SDK应运而生&#xff0c;成为直播平台的重要利器之一。 一、什么是美颜SDK&#xff1f; 通过美颜SDK&#xff0c;开发者可以…

三菱PLC FX3U滑动平均值滤波

三菱PLC滑动平均值滤波其它相关写法,请参考下面文章链接: https://rxxw-control.blog.csdn.net/article/details/125044013https://rxxw-control.blog.csdn.net/article/details/125044013滑动平均值滤波程序总共分为三部分,第一步为:滑动采样。 第二步为:队列求和,第三…

最强笔记生成AI —— NotionAI

NotionAI是Notion推出的一款革命性AI工具&#xff0c;它正通过利用其先进的AI技术来扩大用户群。这款强大的生成式AI工具能够帮助用户完成笔记总结、识别会议中的行动项&#xff0c;并创建和修改文本。NotionAI通过自动化枯燥的任务、为用户提供建议和模板&#xff0c;极大地简…

深度学习模型轻量化方法介绍

深度学习模型轻量化是指通过一系列技术手段减少模型的大小和计算需求&#xff0c;使其能够在资源有限的环境中&#xff08;如移动设备、嵌入式系统&#xff09;运行。下面是一些常见的模型轻量化方法&#xff1a; 模型剪枝&#xff08;Pruning&#xff09;: 描述: 模型剪枝涉及…

【Java异常】idea 报错:无效的目标发行版:17 的解决办法

【Java异常】idea 报错&#xff1a;无效的目标发行版&#xff1a;17 的解决办法 一&#xff0c;问题来源 springcloud的第一个demo项目就给我干趴了 二、原因分析 java: 无效的目标发行版: 17 原因就是 JDK 版本不对。从 IDEA 编辑器中可以找到问题的原因所在&#xff0c;…

Axure之交互与情节与一些实例

目录 一.交互与情节简介 二.ERP登录页到主页的跳转 三.ERP的菜单跳转到各个页面的跳转 四.省市联动 五.手机下拉加载 今天就到这里了&#xff0c;希望帮到你哦&#xff01;&#xff01;&#xff01; 一.交互与情节简介 "交互"通常指的是人与人、人与计算机或物体…