【C语言】学数据结构前必学的结构体struct详细

简介: 本文讲解:学数据结构前必学的结构体struct详细。

 

佛祖说,他可以满足程序猿一个愿望。程序猿许愿有生之年写出一个没有bug的程序,然后他得到了永生。


目录

1、结构体的声明与定义

1.1结构体是什么?

1.2为什么要有结构?

1.3结构体的声明

1.4结构体成员类型

1.5结构体变量定义和初始化

2、结构体成员的访问

3、结构体传参


前言:

大家好,我是拳击哥,今天我给大家带来的学数据结构前必学的结构体。本期讲解初始化结构体,如何访问结构体成员以及结构体的传值调用和传址调用。下面我就来讲解它们的用法。


1、结构体的声明与定义

1.1结构体是什么?

什么是结构,我们在学习数组的时候知道了数组是一组相同类型元素的集合,那么数组就是一个结构。而结构体的结构是一些不同类型数据的集合,这些数据称为成员变量。结构的每个成员可以不同类型的变量。


1.2为什么要有结构?

我们生活有很多复杂对象,比如一个人、一本书。一个人他由有姓名,性别,年龄,工资,籍贯来描述。一本书它由书名、作者、出版社、价格来描述。因此这些描述组成复杂对象就是结构。好了说了那么多,如何用代码的形式描述这些复杂对象?请往下看。


1.3结构体的声明

struct stu
{
  type member1;
  type member2;
  type member3;
  ...;
}variavle-list;

image.gif

上述代码中struct是结构体的类型,stu是标签名根据需求起的一个名称。type是结构体类型member是结构体成员我们可以看到可以有N个成员根据你需求来决定有多少个成员变量。

那么{}里面的所有的成员我们成为member-list也就是成员列表,variable-list是变量列表。有了以上概念的理解,1.2中说到了一个人有姓名,性别,年龄,工资,籍贯。假设要描述一个学生如何做呢,我们来看代码:

#include<stdio.h>
struct Person
{
  //以下五个是结体成员
  char name[10];
  int age;
  char sex[5];
  float salary;
  char place[10];
}s4,s5;//声明的同时定义s4,s5
int main()
{
  struct Person s1, s2, s3;//s1-s3是结构体变量(局部的)
  return 0;
}

image.gif

main函数上方的struct Person以及{}里面的内容都是结构体的声明,声明了结构体成员的类型以及大小。{}后面定义的s3,s4是全局的结构体变量。main函数里面定义的s1,s2,s3这三个是局部结构体变量。只有创建了这五个变量,才会在内存中开辟五块块空间。这五个结构体变量里面存的就是刚刚结构体声明里面的五个结构体成员。

image.gif编辑


1.4结构体成员类型

那么结构体的是一组不同类型的数组的集合,结构体的成员可以是变量、数组、指针、甚至是棋类结构体。下面我们用代码来讲解。


1.5结构体变量定义和初始化

1.3中我们定了5个结构体变量,我们看到有三种定义方式。这些定义都是有了结构体类型,才能进行定义的。实际上有三种定义方式:

    • 声明类型的同时,在;前面定义全局的结构体变量
    • 单独定义结构体变量
    • main函数里面定义局部的结构体变量

    我们来看一组代码:

    #include<stdio.h>
    struct Person
    {
      //以下五个是结体成员
      char name[10];
      int age;
      char sex[5];
      float salary;
      char place[10];
    }s4,s5;//声明的同时定义s4,s5
    struct Person s6;
    int main()
    {
      struct Person s1, s2, s3;//s1-s3是结构体变量(局部的)
      return 0;
    }

    image.gif

    以上代码中,s4,s5属于声明结构体类型的同时在;前面定义全局的结构体变量

    s6属于单独定义的结构体变量;s1-s2属于在main函数里面定义局部的结构体变量。

    相信大家都已经理解了结构体变量的定义,下面我们来看结构体变量的初始化。


    初始化结构体变量。跟数组初始化类似,只不过。结构体变量里面的值可以为不同类型,如以下程序:

    #include<stdio.h>
    struct Person
    {
      char name[10];
      int age;
      char sex[5];
      float salary;
      char place[10];
    };
    int main()
    {
      struct Person s1 = { "张三",22,"男",12.3f,"美国" };
      struct Person s2 = { "李四",23,"女",66.2f,"荷兰" };
      struct Person s3 = { "王五",66,"保密",0.2f,"布吉岛" };
      printf("%s %d %s %.1f %s\n", s1.name, s1.age, s1.sex, s1.salary, s1.place);
      printf("%s %d %s %.1f %s\n", s2.name, s2.age, s2.sex, s2.salary, s2.place);
      printf("%s %d %s %.1f %s\n", s3.name, s3.age, s3.sex, s3.salary, s3.place);
      return 0;
    }

    image.gif

    输出结果

    张三 22 男 12.3 美国

    李四 23 女 66.2 荷兰

    王五 66 保密 0.2 布吉岛

    当我们想访问结构体成员时,我们用结构体变量 . 号结构体成员来获取。注意,你初始化什么类型格式符就写什么类型比如"张三"对应的格式符为%s,相信大家已经知道怎样初始化结构体变量了。

    总结:

      • 结构体成员类型可以是不同的类型,普通数据类型,数组,指针,甚至是结构体
      • 结构体体变量初始化时,对应着结构体成员类型来初始化
      • 结构体变量访问结构体成员时用.操作符来访问
      • 输出每个结构体成员时应该对应该类型的格式符

      最后我们来看一下当结构体成员是结构体时是什么样子:

      #include<stdio.h>
      struct S1
      {
        int a;
        char b;
      };
      struct S2
      {
        float c;
        struct S1 f;
        double d;
      };
      int main()
      {
        struct S2 s = { 2.1f,{10,'A'},3.4 };
        printf("%.1f %d %c %.1lf\n", s.c, s.f.a, s.f.b, s.d);
        return 0;
      }

      image.gif

      输出结果:2.1 10 A 3.4

      structS2中定义了结构体类型为结构体,有些像套娃。下面我来讲解它们的用法:

      结构体类型为结构体的结构体成员时初始化只需要在{}里面再加一个{}就好了,{}里面就可以初始化该成员为结构体里面的结构体成员。

      结构体变量访问为结构体成员为结构体的结构体成员里面的结构体成员需要用到两个.号 。如上方程序,两个点号来获取。结构体类型为结构体里面的成员。


      2、结构体成员的访问

      结构体成员的访问相信大家在上面的讲解中已经了解到了一个方法那就通过.号来访问,还有一个方法是通过->来访问。这两个访问方法为:

        • .操作符
        • ->符号
        #include<stdio.h>
        struct Person
        {
          char name[10];
          int age;
          char sex[5];
        };
        void Print1(struct Person* p)
        {
          printf("%s %d %s\n", (*p).name, (*p).age, (*p).sex);
          printf("%s %d %s\n", p->name, p->age, p->sex);
        }
        int main()
        {
          struct Person s = { "张三",60,"男" };
          Print1(&s);
          return 0;
        }

        image.gif

        输出结果

        张三 60 男

        张三 60 男

        以上代码是把结构体变量s的地址传给了指针结构体变量p。那么我们就可以通过解引用p再访问结构体成员,访问方式就是.号。->号权限比较大可以不用解引用直接访问成员。

        image.gif编辑


        3、结构体传参

        在我们学习数组的时候,数组的参数有传值和传参两中传参方式。结构体也是一样,既能传参又能传址。有以下代码:

        #include<stdio.h>
        struct Person
        {
          char name[10];
          int age;
          char sex[5];
        };
        void Print1(struct Person p1)
        {
          printf("%s %d %s\n", p1.name, p1.age, p1.sex);
        }
        void Print2(struct Person* p2)
        { 
            printf("%s %d %s\n", (*p2).name, (*p2).age, (*p2).sex);
          printf("%s %d %s\n", p2->name, p2->age, p2->sex);
        }
        int main()
        {
          struct Person s = { "张三",60,"男" };
          Print1(s);
          Print2(&s);
          return 0;
        }

        image.gif

        输出结果

        张三 60 男

        张三 60 男

        张三 60 男

        Print1形参里面传过去的就是值,此时p1等同于s。依次通过.号来访问成员变量就好了。

        Print2形参里面传过去的就是地址,此时p1的地址等同于s的地址,我们需要先对p1进行解引用才来依次访问成员变量。我们也可以用->直接访问成员变量。

        image.gif编辑


        本期博客到这里就结束了,相信大家对初识结构体有了新的认识,感谢您的观看。

        image.gif编辑

        Never Give Up

        相关文章
        |
        2月前
        |
        算法 数据处理 C语言
        C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合
        本文深入解析了C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合,旨在帮助读者掌握这一高效的数据处理方法。
        51 1
        |
        2月前
        |
        存储 算法 搜索推荐
        【趣学C语言和数据结构100例】91-95
        本文涵盖多个经典算法问题的C语言实现,包括堆排序、归并排序、从长整型变量中提取偶数位数、工人信息排序及无向图是否为树的判断。通过这些问题,读者可以深入了解排序算法、数据处理方法和图论基础知识,提升编程能力和算法理解。
        56 4
        |
        2月前
        |
        存储 机器学习/深度学习 搜索推荐
        【趣学C语言和数据结构100例】86-90
        本文介绍并用C语言实现了五种经典排序算法:直接插入排序、折半插入排序、冒泡排序、快速排序和简单选择排序。每种算法都有其特点和适用场景,如直接插入排序适合小规模或基本有序的数据,快速排序则适用于大规模数据集,具有较高的效率。通过学习这些算法,读者可以加深对数据结构和算法设计的理解,提升解决实际问题的能力。
        49 4
        |
        2月前
        |
        存储 算法 数据处理
        【趣学C语言和数据结构100例】81-85
        本文介绍了五个经典算法问题及其C语言实现,涵盖图论与树结构的基础知识。包括使用BFS求解单源最短路径、统计有向图中入度或出度为0的点数、统计无向无权图各顶点的度、折半查找及二叉排序树的查找。这些算法不仅理论意义重大,且在实际应用中极为广泛,有助于提升编程能力和数据结构理解。
        53 4
        |
        2月前
        |
        算法 数据可视化 数据建模
        【趣学C语言和数据结构100例】76-80
        本文介绍了五种图论算法的C语言实现,涵盖二叉树的层次遍历及广度优先搜索(BFS)和深度优先搜索(DFS)的邻接表与邻接矩阵实现。层次遍历使用队列按层访问二叉树节点;BFS利用队列从源节点逐层遍历图节点,适用于最短路径等问题;DFS通过递归或栈深入图的分支,适合拓扑排序等场景。这些算法是数据结构和算法学习的基础,对提升编程能力和解决实际问题至关重要。
        54 4
        |
        2月前
        |
        存储 算法 vr&ar
        【趣学C语言和数据结构100例】71-75
        本文介绍了五个C语言数据结构问题及其实现,涵盖链表与二叉树操作,包括按奇偶分解链表、交换二叉树左右子树、查找节点的双亲节点、计算二叉树深度及求最大关键值。通过递归和遍历等方法,解决了理论与实际应用中的常见问题,有助于提升编程能力和数据结构理解。
        45 4
        |
        2月前
        |
        存储 算法 C语言
        【趣学C语言和数据结构100例】66-70
        本书《趣学C语言和数据结构100例》精选了5个典型的数据结构问题及C语言实现,涵盖链表与数组操作,如有序集合的集合运算、有序序列表的合并、数组中两顺序表位置互换、三递增序列公共元素查找及奇偶数重排。通过详细解析与代码示例,帮助读者深入理解数据结构与算法设计的核心思想,提升编程技能。
        37 4
        |
        29天前
        |
        存储 网络协议 编译器
        【C语言】深入解析C语言结构体:定义、声明与高级应用实践
        通过根据需求合理选择结构体定义和声明的放置位置,并灵活结合动态内存分配、内存优化和数据结构设计,可以显著提高代码的可维护性和运行效率。在实际开发中,建议遵循以下原则: - **模块化设计**:尽可能封装实现细节,减少模块间的耦合。 - **内存管理**:明确动态分配与释放的责任,防止资源泄漏。 - **优化顺序**:合理排列结构体成员以减少内存占用。
        133 14
        |
        1月前
        |
        存储 编译器 C语言
        【C语言】结构体详解 -《探索C语言的 “小宇宙” 》
        结构体通过`struct`关键字定义。定义结构体时,需要指定结构体的名称以及结构体内部的成员变量。
        159 10
        |
        2月前
        |
        存储 缓存 算法
        在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
        在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
        70 5