【C语言】自定义类型:结构体

发布于:2025-04-13 ⋅ 阅读:(23) ⋅ 点赞:(0)

前言:

在上章节讲解了浮点数在内存的储存,在本章节为大家讲解结构体。

一·结构体的概念

结构"是一种构造类型,它是由若干"成员"组成的,每一个成员可以是一个基本数据类型或者又是一个构造类型.

   结构既是一种"构造"而成的数据类型,那么在说明和使用之前必须先定义它,也就是构造它,如同在说明和调用函数之前要先定义函数一样

结构体的定义使用struct关键字,其基本语法如下:

struct 结构体名称 {
    数据类型 成员1;
    数据类型 成员2;
    ...
};

类比现实:想象学生档案,包含姓名(字符串)、学号(整数)、成绩(浮点数)。结构体能将这三个字段“打包”成Student类型。

例如:

struct Student {
    int id;
    char name[50];
    float score;
};

结构体的成员可以是基本数据类型,也可以是其他复杂数据类型,如数组、指针等。

结构体的定义及初始化.ppt zhuangpeitu.com

二·结构体的声明与初始化

在C语言中,结构体可以通过以下方式声明和初始化:

  1. 仅声明结构体变量,但不初始化。

   struct Student ;
  1. 初始化:在声明时直接赋值。

   struct Student s = {1234, "张三", 100.0};

逐个成员赋值

  • ​
    struct Student s2;
    s2.id = 1002;
    strcpy(s2.name, "Bob");
    s2.score = 88.5;
    
    ​

    三·结构体成员的访问  

  • 使用.操作符

  • struct Student *ptr = &s1;
    printf("Score: %.1f\n", ptr->score); // 输出92.5

    使用.操作符后会出现这样的界面,供你选择,选择你想要输出的内容。

#include <stdio.h>
struct student
{
	int id;
	char name[40];
	float score;

};

struct student s1 = { 1001, "Alice", 92.5 };
int main()
{
	printf("%d %s %f", s1.id, s1.name, s1.score);
	return 0;
}

指针使用->操作符: 

struct Student *ptr = &s1;
printf("Score: %.1f\n", ptr->score); // 输出92.5

四·结构的特殊声明

匿名结构体类型

  • 不完全声明

在声明结构体时,可以省略结构体标签,但必须在后面的大括号中给出成员定义。

例如: 

struct //匿名结构体类型
{
	int a;
	char b;
	float c;
}s1,s2,s3;
  • 匿名结构体的限制

匿名结构体只能在声明时直接使用,不能在其他地方引用或重复使用。

例如,以下代码是非法的: 

 struct {
      int a;
      char b;
  } x;
  struct {
      int a;
      char b;
  } y = x; // 错误,x和y是不同的类型

编译器会将两个匿名结构体视为不同的类型,从而导致语法错误

五·结构体的自引用

自引用的定义

自引用结构体的定义需要先声明一个结构体标签,然后在该结构体中定义一个指向该结构体的指针。

例如: 

  struct Node {
      int data;
      struct Node *next; // 自引用指针
  };

  这种方式合法,因为编译器在解析struct Node时,已经知道Node的完整结构,因此可以正确计算next的长度。(PS:如何计算大小在下面会讲解的,稍安勿躁)

 

  • 错误的自引用方式
    如果在结构体中直接包含一个未定义的结构体实例,会导致编译器无法确定其长度,从而引发错误。例如:
  struct Node {
      int data;
      struct Node next; // 错误,未定义的结构体实例
  };

这种写法会导致编译器无法计算出Node的长度,因此是非法的。

 自引用的注意事项

  • 避免同时使用匿名声明和自引用:匿名结构体的最大特点是只能在声明时使用,而自引用需要在结构体定义完成后才能使用。因此,两者同时使用会导致矛盾,例如:
  struct {
      int a;
      struct {
          int b;
      } *ptr;
  } x; // 错误,ptr未定义

由于匿名结构体的限制,ptr无法在声明时正确解析。

  • typedef的使用:为了简化代码,可以使用typedef定义一个结构体别名,并在定义中包含自引用。例如:
  typedef struct {
      int data;
      struct Node *next;
  } Node;

总结:

本章讲解了结构体的运用和使用操作符,如何正确的初始化。

如果本章对大家有一点点的帮助,可以关注一下博主!!!