自定义类型:结构体(1)

1.结构体回顾

结构是一些值的集合,这些值被称为成员变量。结构的每个成员可以是不同类型的变量。

1.1结构的声明

struct tag
{
    member-list;
}variable-list;

例如描述一个学生:

struct Stu
{
   char name[20];
   int age;
   char sex[5];
};

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

#include 
struct Stu
{
   char name[20];
   int age;
   char sex[5];
   char id[20];
};
int main()
{
  //按照结构体成员的顺序初始化
    struct Stu s = { "张三", 20, "男", "2024123456" };
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 = "lisa", .id = "2024345678", .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);

2 .结构的特殊声明

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

比如:

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

上面的两个结构体在声明的时候省略掉了结构体标签。

那么,在上面代码的基础上,下面的代码合法吗?

p = &x;

警告:

编译器会把上面的两个声明当成完全不同的两个类型,所以是非法的。

匿名的结构体类型,如果没有对结构体类型重命名的话,基本上只能使用一次。

3.结构的自引用

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

比如,定义一个链表的节点:

struct Node
{
    int data;
    struct Node next;
};
上述代码正确吗?如果正确,那 sizeof(struct Node) 是多少?
仔细分析,其实是不行的,因为⼀个结构体中再包含⼀个同类型的结构体变量,这样结构体变量的大小就会无穷的大,是不合理的。
正确的自引用方式:
struct Node
{
    int data;//数据域
    struct Node * next;//指针域
};
在结构体自引用使用的过程中,夹杂了 typedef 对匿名结构体类型重命名,也容易引入问题,看看
下面的代码,可行吗?
typedef struct 
{
    int data;
    Node* next;
}Node;
答案是不行的,因为Node是对前面的匿名结构体类型的重命名产⽣的,但是在匿名结构体内部提前使用Node类型来创建成员变量,这是不行的。
解决方案如下:
typedef struct Node
{
    int data;
    struct Node* next;
}Node;

定义结构体尽量不要使用匿名结构体。

你可能感兴趣的:(c语言)