【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.mzph.cn/news/232365.shtml

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

相关文章

微博被封禁如何解决

1.电脑搜索互联网信息投诉平台,点击我要投诉 2.找到互联网企业,选择新浪微博 3.然后填写个人信息,这里正常填写就行 4.填写信息 5.截图 6.成功

响应式布局2:手写响应式导航栏(BootStrap实现以及原生实现)

1.响应式导航栏介绍 响应式导航栏是一种在不同设备和屏幕尺寸下自适应布局和显示的导航栏。它可以根据用户所使用的设备(如桌面电脑、平板电脑或手机)自动调整其外观和交互方式,以提供更好的用户体验。 pc端: 手机端&#xff1a…

嵌入式开发行业会不会也变成java行业?

今日话题,嵌入式开发行业会不会也变成java行业?关于嵌入式行业的未来,与一些人的担忧不同,它并不会内卷化,而是具有相对稳定性的领域。嵌入式开发在制造业等重要第二产业中扮演着关键角色,这些领域的稳定性…

ubuntu部署llama2-chinese

ubuntu上安装cuda见之前的blog,已安装cuda12,使用nvcc-V 下载llama2-chinese:GitHub - FlagAlpha/Llama2-Chinese: Llama中文社区,最好的中文Llama大模型,完全开源可商用 conda create -n llamachinese python3.10 pi…

C#二甲医院实验室信息系统源码

医院实验室信息系统简称(Hospitallaboratoryinformationsystem),也可以称作实验室(检验科)信息系统或者LIS系统。 LIS定义 其主要功能是将检验的实验仪器传出的检验数据经分析后,自动生成打印报告,通过网络存储在数据…

当我分别问8款GPT一个问题。。。

前两天下班在地铁上无聊寻思问一下不同的GPT一个相同的问题,哪个会给出我比较满意的答案,然后我就提问:我老妹有点憨怎么办?(ps:开玩笑的,嘻嘻。。。) 很明显其他GPT都给出了大差不差…

Java的数据类型

文章目录 整形浮点型字符型布尔型基本数据类型转换自动类型转换自动类型转换注意和细节强制类型转换强制类型转换细节说明 整形 浮点型 字符型 字符型使用细节 布尔型 基本数据类型转换 自动类型转换 自动类型转换注意和细节 强制类型转换 自动类型转换的逆过程&#x…

金三银四精选面试题系列

Java中有哪几种方式来创建线程执行任务? 1. 继承Thread类 public class ZhouyuThread extends Thread{public static void main(String[] args) {ZhouyuThread thread new ZhouyuThread();thread.start();}Overridepublic void run() {System.out.println("h…

Mistral AI CEO宣布于2024年开源GPT-4级别模型

法国初创公司Mistral AI的首席执行官Arthur Mensch在法国国家广播电台宣布,公司计划于2024年开源GPT-4级模型,引发了业界的关注。 最近,Mistral AI推出了基于MoE架构的8X7B模型,与GPT3.5和Llama270B等其他流行模型相媲美&#xf…

leetcode --- 30. 串联所有单词的子串[C++ 滑动窗口/双指针]

原题:30. 串联所有单词的子串 - 力扣(LeetCode) 题目解析: 本题在这道题的算法原理基础上进行思考会简单许多 leetcode --- 438. 找到字符串中所有字母异位词[C/滑动窗口哈希表]-CSDN博客 关键信息---words中的字符串长度都相等 …

二叉树【数据结构】

目录 二叉树1. 二叉树定义二叉树的存储定义 2. 遍历二叉树(1) 前序遍历(2) 中序遍历(3) 后序遍历(4) 层序遍历 3. 二叉树的相关操作(1) 二叉树的初始化(2) 二叉树的结点的手动创建(3) 二叉树结点的个数(4) 二叉树叶子结点的个数(5) 二叉树的高度(6) 第k层结点个数(7) 通过前序遍…

科技巨头三巨头:百度、阿里巴巴、腾讯的崛起与角力

导言 百度、阿里巴巴、腾讯被誉为中国科技领域的“三巨头”,在搜索、电商、社交等多个领域取得了巨大成功。本文将深入探讨这三家公司的崛起原因、核心业务、战略布局以及彼此之间的竞争和合作关系。 1. 百度的搜索帝国 搜索引擎: 百度以其搜索…

Java 序列化机制详解

Java 序列化机制是一种将对象转换为字节流的过程,以便在网络上传输或保存到文件中,并能在需要时将字节流还原为对象。这一机制通过实现 java.io.Serializable 接口来实现,同时涉及到一些关键概念和注意事项。 Serializable 接口 Serializabl…

开发知识点-09Rust

Rust Rust 语言通常用于编写系统级软件、网络服务器和高性能应用程序,它具有以下特点:1. 高性能和内存安全:Rust 在保证高性能的同时,利用其所有权模型和借用检查器等特性确保内存安全,避免了 C/C 等语言的内存错误和崩…

瑞友天翼应用虚拟化系统 多处SQL 注入漏洞复现(可RCE)

0x01 产品简介 瑞友天翼应用虚拟化系统是西安瑞友信息技术资讯有限公司研发的具有自主知识产权,基于服务器计算架构的应用虚拟化平台。它将用户各种应用软件集中部署在瑞友天翼服务器(群)上,客户端通过WEB即可快速安全的访问经服务器上授权的应用软件,实现集中应用、远程接…

Pytorch nn.Linear()的基本用法与原理详解及全连接层简介

主要引用参考: https://blog.csdn.net/zhaohongfei_358/article/details/122797190 https://blog.csdn.net/weixin_43135178/article/details/118735850 nn.Linear的基本定义 nn.Linear定义一个神经网络的线性层,方法签名如下: torch.nn.Li…

生日蜡烛C语言

分析&#xff1a;假设这个人只能活到100岁&#xff0c;如果不这样规定的话&#xff0c;那么这个人就可以假设活到老236岁&#xff0c;直接一次吹236个蜡烛&#xff0c;我们就枚举出所以情况&#xff0c;从一岁开始。 #include <stdio.h> int f(int a,int b){//计算从a到…

视频素材网站全新上线,海量高清视频等你来探索~

亲爱的视频制作爱好者们&#xff0c;好消息来啦&#xff01;我们的视频素材网站全新上线啦&#xff01;这次我们为大家带来了海量的高清视频素材&#xff0c;无论是风景、城市、人物、动物还是各种特效、背景等&#xff0c;应有尽有&#xff0c;满足您在视频制作过程中的各种需…

【神器】wakatime代码时间追踪工具

文章目录 wakatime简介支持的IDE安装步骤API文档插件费用写在最后 wakatime简介 wakatime就是一个IDE插件&#xff0c;一个代码时间追踪工具。可自动获取码编码时长和度量指标&#xff0c;以产生很多的coding图形报表。这些指标图形可以为开发者统计coding信息&#xff0c;比如…

【MySQL】:复合查询

复合查询 一.多表查询二.自连接三.子查询1.单行子查询2.多行子查询3.多列子查询4.在from语句里使用子查询5.合并查询 准备三张表 emp表 dept表 salgrade表 一.多表查询 实际开发中往往数据来自不同的表&#xff0c;所以需要多表查询。我们用一个简单的公司管理系统&#xff0c…