【C语言进阶篇】看完这篇结构体文章,我向数据结构又进了一大步!(结构体进阶详解)(上)

简介: 【C语言进阶篇】看完这篇结构体文章,我向数据结构又进了一大步!(结构体进阶详解)

📋 前言

  🌈hello! 各位宝子们大家好啊,结构体的基本使用和常见错误在上一篇详细讲解过了,不知道大家都学会了没有。

  ⛳️今天给大家来个硬菜,教点高级点的结构体结构,给我们的数据结构开个好头!废话不多说直接进入正题

  📚本期文章收录在《C语言进阶篇》,大家有兴趣可以看看呐

  ⛺️ 欢迎铁汁们 ✔️ 点赞 👍 收藏 ⭐留言 📝!

1 结构体的声明

1.1 结构的基础知识

这个部分博主在前一篇博客已经详细讲解过了,一俩句话也解释不清楚,结构体这方面基础不是很好的铁铁们可以去阅读一下这篇文章哦!万字详解包看包会!

🔥 注:上一篇结构体万字解析的链接《结构体的基础讲解》

1.2 结构的声明

1.2.1 . 匿名结构体类型声明

在声明结构的时候,也可以不完全的声明。面的两个结构在声明的时候省略掉了结构体标签(tag),看下有什么后果。

  • 而这就叫匿名结构体类型

📚 代码演示:

//匿名结构体类型
struct
{
  int a;
  char b;
  float c;
}x;
struct
{
  int a;
  char b;
  float c;
}a[20], * p;q

1.2.2 匿名结构体类型的的缺陷

那么匿名结构体有什么缺陷呢?其实有俩个缺陷匿名结构体第一没有 标签名,连名字都没有所以只能在创建结构体时定义。

  • 只能在创建结构体时定义结构体变量
  • 相同类型的结构体,我们编译器认为是不一样的

假如我们有俩个相同类型的 匿名结构体 ,一个用来创建。一个创建 匿名结构体指针 用来存放相同类型的结构体变量地址!

📚 代码演示:

//匿名结构体类型
struct
{
  int a;
  char b;
  float c;
}x;
struct
{
  int a;
  char b;
  float c;
}* p;
int main()
{
  p = &x;
  return 0;
}

📑 代码结果:

这里我们就可以看出虽然都是相同类型的匿名结构体,但是在编译期间我们的编译器认为他们俩类型是不一样的。

  • 相同类型的 匿名 结构体指针,接收不了相同类型匿名结构体的地址

总结:

  • 匿名结构体只能在创建是定义
  • 相同类型的匿名结构体,编译器会这两个声明当成完全不同的两个类型。
  • 所以匿名结构体只适合,那种只用一次的结构体上用法很少。

2. 结构的自引用

那么结构体如果想包含一个该结构本身的成员是否可以呢?答案是可以的,这种用法我们在数据结构这门课 链表时会经常使用!

  • 那么我们看下面这段代码,自引用结构体是否可以这样定义呢?

📚 代码演示:

//代码1
struct Node
{
 int data;
 struct Node next;
};
//可行否?

如果可以,那 sizeof(struct Node)是多少?诶这里我们就会发现我们根本计算不了这个结构体的大小是多少!

  • 这里就和套娃一样,int data 我们知道是四个字节
  • struct Node 里面又包含了 struct Node 这个根本就算不了嘛!逻辑上就错误了!

2.1 结构体自引用的作用

在我们数据结构体中有一个叫做链表的数据结构,这里就不给大家详细解释了,只给大家见见猪跑!免得搞混了。链表是我们数据结构中用来指向相同类型的元素但是在不同空间里的连续存储方式。

  • 使他们向像一个链子一样可以相互链接访问

大家看着张图是不是就明白很多呢? 我们想在节点一找到相同类型的下一个节点:

  • 诶!那这样我们只需要把相同类型节点的地址存放到上一个节点处是不是就可以了?
  • 而不是去存放下一个节点的内容。那么我们就定义一个结构体
  • 他的成员一个负责存放数组,一个负责存放下一个地点的地址

📚 代码演示:

//代码2
struct Node
{
 int data;
 struct Node* next;
};

这样我们就可以访问一块不连续空间但是,是相同类型的结构体变量了。也可以对比数组

  • 数组是一块连续的空间里存放相同类型的数据
  • 链表是一块不连续的空间里存放不相同类型的数据
  • 而这就是结构体自引用的妙用了

2.2 结构体自引用的注意事项

但是在使用的时候,有些人会犯这样的错误一定要注意。

  • 我们知道结构体可以重命名而很多人就会把重名的结构体当成结构体成员。
  • 但这是非常错误的
//代码3
typedef struct
{
 int data;
 Node* next;
}Node;
//这样写代码,可行否?

📑 代码结果:

这时在编译期间就会发生错误,我们typedef 重定义还没生效呢!你就开始使用重定义之后的类型名了。

原因:

结构体重定义在结构体结束时最后一行才生效,但是我们在重定义生效之前就想使用这肯定回发生错误呢!

  • 正确的做法是在结构体里面我们还是使用未重命名之前的标签名。
//解决方案:
typedef struct Node
{
 int data;//数据域
 struct Node* next;//指针域
}Node;


目录
打赏
0
0
0
0
17
分享
相关文章
c语言及数据结构实现简单贪吃蛇小游戏
c语言及数据结构实现简单贪吃蛇小游戏
数据结构(C语言)之对归并排序的介绍与理解
归并排序是一种基于分治策略的排序算法,通过递归将数组不断分割为子数组,直到每个子数组仅剩一个元素,再逐步合并这些有序的子数组以得到最终的有序数组。递归版本中,每次分割区间为[left, mid]和[mid+1, right],确保每两个区间内数据有序后进行合并。非递归版本则通过逐步增加gap值(初始为1),先对单个元素排序,再逐步扩大到更大的区间进行合并,直至整个数组有序。归并排序的时间复杂度为O(n*logn),空间复杂度为O(n),且具有稳定性,适用于普通排序及大文件排序场景。
【C语言】深入解析C语言结构体:定义、声明与高级应用实践
通过根据需求合理选择结构体定义和声明的放置位置,并灵活结合动态内存分配、内存优化和数据结构设计,可以显著提高代码的可维护性和运行效率。在实际开发中,建议遵循以下原则: - **模块化设计**:尽可能封装实现细节,减少模块间的耦合。 - **内存管理**:明确动态分配与释放的责任,防止资源泄漏。 - **优化顺序**:合理排列结构体成员以减少内存占用。
219 14
【C语言】结构体详解 -《探索C语言的 “小宇宙” 》
结构体通过`struct`关键字定义。定义结构体时,需要指定结构体的名称以及结构体内部的成员变量。
223 10
C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合
本文深入解析了C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合,旨在帮助读者掌握这一高效的数据处理方法。
114 1
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
103 1
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
104 5
C 语言结构体 —— 数据封装的利器
C语言结构体是一种用户自定义的数据类型,用于将不同类型的数据组合在一起,形成一个整体。它支持数据封装,便于管理和传递复杂数据,是程序设计中的重要工具。
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
331 13
C 语言结构体与位域:高效数据组织与内存优化
C语言中的结构体与位域是实现高效数据组织和内存优化的重要工具。结构体允许将不同类型的数据组合成一个整体,而位域则进一步允许对结构体成员的位进行精细控制,以节省内存空间。两者结合使用,可在嵌入式系统等资源受限环境中发挥巨大作用。
123 12
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等