自定义类型:结构体

兄弟盟这篇文章我们来讲一下结构体。

首先呢我们还是要先讲一下什么是结构体:

1.1结构体类型的声明

1.1.1什么是结构体:

结构体(Struct)是一种自定义的数据类型,它允许将多个不同类型的变量组合在一起形成一个单一的类型。在编程中,结构体通常用于将相关的数据项组织在一起,以便于管理和操作。

结构体的定义通常包括以下几个部分:

1. 结构体名称:这是结构体的标识符,用于在代码中引用该结构体。
2. 成员变量:这些是结构体内部的变量,每个成员变量都有自己的类型和名称。

例如,在C语言中,一个简单的结构体定义可能如下所示:

struct Person {
    char name[50];
    int age;
    float height;
};//分号不能丢

在这个例子中,`Person` 是结构体的名称,它包含三个成员变量:`name`(一个字符数组),`age`(一个整数),和 `height`(一个浮点数)。

使用结构体的好处包括:

- **数据封装**:将相关数据封装在一起,便于管理和维护。
- **代码清晰**:通过使用结构体,代码的逻辑更加清晰,易于理解。
- **类型安全**:结构体可以定义为特定的数据类型,编译器可以检查类型错误。

在实际编程中,结构体可以用于多种场景,如定义一个日期结构体来存储年、月、日信息,或者定义一个坐标结构体来存储x和y坐标等。结构体是编程中组织数据的重要工具之一。

1.1.2结构体变量的创建和初始化

关于结构体变量的创建这里有几种情况:

struct Book
{
   char name[20];
   char author[20];
   float price;
   char id[13];
}b3,b4;//全局变量
struct Book b2;//局部变量

int main()
{
   struct Book b1;//局部变量
   struct Book arr[5];//数组
}

那怎么么进行初始化呢?看下面: 

#include <stdio.h>
struct Stu
{
 char name[20];//名字
 int age;//年龄
 char sex[5];//性别
 char id[20];//学号
};
int main()
{
 //按照结构体成员的顺序初始化
 struct Stu s = { "张三 ", 20, "男", "20230818001" };
 printf("name: %s\n", s.name);
 printf("age : %d\n", s.age);
 printf("sex : %s\n", s.sex);
 printf("id : %s\n", s.id);
 
 //按照指定的顺序初始化
 struct Stu s2 = { .age = 18, .name = "lisi", .id = "20230818002", .sex = 
"女" };
 printf("name: %s\n", s2.name);
 printf("age : %d\n", s2.age);
 printf("sex : %s\n", s2.sex);
 printf("id : %s\n", s2.id);
 return 0;
}

1.2结构的特殊说明

在声明结构的时候,可以不完全的声明。

比如:

//正常来说结构体是要有名字的,就想这样
struct S//这个S就是这个结构体的名字
{
  char c;
  int i;
  double d;
};

int main()
{
  struct S s;//这里可以进行创建变量。
  return 0 ;
}




//但是对于匿名结构体呢?
//匿名结构体就是没有这个名字,当你把下面创建变量的的名字也去掉的话,那么下面也就不能直接创建变量了。
struct 
  char c;
  int i;
  double d;
}s = {'x',100,3.14};这时变量的名字就是在这里直接创建的,并且也可以初始化,下面也是可以正常打印的

int main()
{
 printf("%c %d %lf\n",s.c,s.i,s.d)
  return 0 ;
}
//这就是匿名结构体类型,匿名结构体类型只能用一次。

匿名结构体类型还有一个问题

struct 
  char c;
  int i;
  double d;
}s//你命结构体变量
struct 
  char c;
  int i;
  double d;
}*ps//匿名结构体指针。这两个结构体成员一模一样,但是ps不等于&s,就因为是匿名的

//这两个是不相等的

其实匿名结构体类型也是可以重新产生一个名字的:

//就想这样
typedef struct
{
  char c;
  int i;
  double d;
}S;//这个S就是这个结构体的名字

int main()
{
  S s;
return 0;
}//但是给一个匿名结构体起一个名字多多少少有点不伦不类了。

 1.3结构的自引用

在结构中包含一个类型为该结构体本身的成员是否可以呢?

就像这样,定义一个链表的节点:

这里我们来说一下,什么是链表?什么是节点?

如图所示:像链条一样把每个数串起来就是链表,他是一种线性数据结构,而这每一个数就是一个节点,而这个节点不仅仅能携带一个数值,还要找到下一个节点,那我们把链表节点定义写成这样可以吗?

struct Node
{
 int data;//这个节点携带的数据
 struct Node next;//而且还携带者下一个数据
};

上述代码其实是不正确的,仔细分析,我们可以这样理解,sizeof(struct Node)是多大?因为一个结构体中包含一个同类型的结构体变量,这样结构体变量的大小就会是无穷大,是不合理的。

我仅仅是想找到下一个节点,那怎么弄?我们可以这样理解,在节点中存放一个整型并且也存放下一个节点的地址,让一个节点存放两个东西。那么最后一个节点地址处存放空指针就可以了,这样就ok了。就想这样:

 

struct Node
{
 int data;//数据
 struct Node* next;//指针
};
int main()
{
  
return 0;
}

正确的就是这样啦, 这才是自引用。

typedef struct Node
{
 int data;
 struct Node* next;
}Node;//重命名

int main()
{
  Node n2;这样写更简单一点,如够你不这样写,按原先的写法就是下面的会挺麻烦的。
return 0;
}




 struct Node
{
 int data;
 struct Node* next;
};

int main()
{
 struct Node n2;//这样写你每一次进行定义一个变量的时候都要把struct Node写一边,会很麻烦。
return 0;
}




//最上面的那串代码还可以写成这样。
 struct Node
{
 int data;
 struct Node* next;
};

typedef struct Node Node;//这样进行重命名也是可以的。
int main()
{
  Node n2;
return 0;
}

这里补充一点:匿名的结构体是不能实现结构体的自引用的效果。 

OK了兄弟们,这就是今天的内容。

  • 23
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值