【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

        相关文章
        |
        15天前
        |
        C语言
        【数据结构】栈和队列(c语言实现)(附源码)
        本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
        90 9
        |
        29天前
        |
        存储 算法 C语言
        通义灵码在考研C语言和数据结构中的应用实践 1-5
        通义灵码在考研C语言和数据结构中的应用实践,体验通义灵码的强大思路。《趣学C语言和数据结构100例》精选了五个经典问题及其解决方案,包括求最大公约数和最小公倍数、统计字符类型、求特殊数列和、计算阶乘和双阶乘、以及求斐波那契数列的前20项和。通过这些实例,帮助读者掌握C语言的基本语法和常用算法,提升编程能力。
        60 4
        |
        14天前
        |
        存储 搜索推荐 算法
        【数据结构】树型结构详解 + 堆的实现(c语言)(附源码)
        本文介绍了树和二叉树的基本概念及结构,重点讲解了堆这一重要的数据结构。堆是一种特殊的完全二叉树,常用于实现优先队列和高效的排序算法(如堆排序)。文章详细描述了堆的性质、存储方式及其实现方法,包括插入、删除和取堆顶数据等操作的具体实现。通过这些内容,读者可以全面了解堆的原理和应用。
        57 16
        |
        14天前
        |
        C语言
        【数据结构】二叉树(c语言)(附源码)
        本文介绍了如何使用链式结构实现二叉树的基本功能,包括前序、中序、后序和层序遍历,统计节点个数和树的高度,查找节点,判断是否为完全二叉树,以及销毁二叉树。通过手动创建一棵二叉树,详细讲解了每个功能的实现方法和代码示例,帮助读者深入理解递归和数据结构的应用。
        63 8
        |
        17天前
        |
        存储 C语言
        【数据结构】手把手教你单链表(c语言)(附源码)
        本文介绍了单链表的基本概念、结构定义及其实现方法。单链表是一种内存地址不连续但逻辑顺序连续的数据结构,每个节点包含数据域和指针域。文章详细讲解了单链表的常见操作,如头插、尾插、头删、尾删、查找、指定位置插入和删除等,并提供了完整的C语言代码示例。通过学习单链表,可以更好地理解数据结构的底层逻辑,提高编程能力。
        44 4
        |
        23天前
        |
        存储 C语言
        如何在 C 语言中实现结构体的深拷贝
        在C语言中实现结构体的深拷贝,需要手动分配内存并逐个复制成员变量,确保新结构体与原结构体完全独立,避免浅拷贝导致的数据共享问题。具体方法包括使用 `malloc` 分配内存和 `memcpy` 或手动赋值。
        30 10
        |
        18天前
        |
        存储 C语言
        【数据结构】顺序表(c语言实现)(附源码)
        本文介绍了线性表和顺序表的基本概念及其实现。线性表是一种有限序列,常见的线性表有顺序表、链表、栈、队列等。顺序表是一种基于连续内存地址存储数据的数据结构,其底层逻辑是数组。文章详细讲解了静态顺序表和动态顺序表的区别,并重点介绍了动态顺序表的实现,包括初始化、销毁、打印、增删查改等操作。最后,文章总结了顺序表的时间复杂度和局限性,并预告了后续关于链表的内容。
        49 3
        |
        18天前
        |
        存储 算法 C语言
        C语言数据结构(2)
        【10月更文挑战第21天】
        |
        22天前
        |
        存储 大数据 编译器
        C语言:结构体对齐规则
        C语言中,结构体对齐规则是指编译器为了提高数据访问效率,会根据成员变量的类型对结构体中的成员进行内存对齐。通常遵循编译器默认的对齐方式或使用特定的对齐指令来优化结构体布局,以减少内存浪费并提升性能。
        |
        27天前
        |
        编译器 C语言
        共用体和结构体在 C 语言中的优先级是怎样的
        在C语言中,共用体(union)和结构体(struct)的优先级相同,它们都是用户自定义的数据类型,用于组合不同类型的数据。但是,共用体中的所有成员共享同一段内存,而结构体中的成员各自占用独立的内存空间。