自定义类型:结构体2.0(初阶+进阶)+位段+枚举+联合(上)

简介: 自定义类型:结构体2.0(初阶+进阶)+位段+枚举+联合(上)

一.结构体


🐓1.1什么是结构体🏀🐔

同一种类型的数据的集合是数组,和数组不同,结构体是多种类型的数据的集合。

现实生活中,我们要汇总学生的体检信息时,我们会为名字、身高、体重分别单独建表吗?显然不会。通常是给每人发一张"体检卡",在资料上面分别记录着名字、身高、体重等信息。如果一个班上有60个学生,那么50张"体检卡"即为一个集合。

下图即为"体检卡":

59baf9ea6cc449c595c55123f1ec20e9.png

1.2结构体的声明

998a0346420a4722b977981ca6fdb084.png

上图4个数据进行结构体的声明

  • char[64]型的姓名
  • int型的身高
  • float型的体重
  • long型的奖学金


其中,结构体的名字student称为结构名。{}中声明的name、height等称为结构体成员

注意结构体声明的末尾也要加上分号。


1.3结构体成员的类型与创建变量🚅

结构的成员可以是标量、数组、指针,甚至是其他结构体。

#include<stdio.h>
//定义学生类型
struct Stu
{
  //成员变量
  char name[20];
  int age;
  float weight;
} s4, s5, s6;//全局变量
int main()
{
  //int num = 0;
  //通过类型创建变量
  struct Stu s1;//局部变量
  struct Stu s2;
  struct Stu s3;
  return 0;
}


1.4结构体成员的访问🏠

  • 结构体变量访问成员
  • 结构变量的成员是通过点操作符(.)访问的。点操作符接受两个操作数

cb989275bb0c4b858d60e5c740794e6d.png

我们可以看到 s 有成员name和age

那我们如何访问s的成员?🍌

struct S s;
strcpy(s.name, "zhangsan");//使用.访问name成员
s.age = 20;//使用.访问age成员


结构体指针访问指向变量的成员

有时候我们得到的不是一个结构体变量,而是指向一个结构体的指针。

那该如何访问成员?

struct Stu
{
 char name[20];
 int age;
};
void print(struct Stu* ps)
{
 printf("name = %s   age = %d\n", (*ps).name, (*ps).age);
    //使用结构体指针访问指向对象的成员
 printf("name = %s   age = %d\n", ps->name, ps->age);
}
int main()
{
    struct Stu s = {"zhangsan", 20};
    print(&s);//结构体地址传参
    return 0;
}

b630a54726b6468c8b269a8b5f3d9187.png

两种写法同时展现:

struct Book
{
  char name[20];
  int price;
};
void print(struct Book* p)
{
  printf("%s %d\n", p->name, p->price);
}
int main()
{
  struct Book b1 = {"C语言", 66};
  struct Book b2 = { .price = 80, .name = "java"};
  //结构体变量.结构体成员
  printf("%s %d\n", b1.name, b1.price);
  printf("%s %d\n", b2.name, b2.price);
  //结构体指针->结构体成员
  //struct Book* p1 = &b1;
  print(&b1);
  return 0;
}


0cf194cda0c14f08b978952ff17a80b7.png

1.5结构体和typedef

typedef声明是创建数据类型的同义词的声明(而非创建新的数据类型)🐔

54ac9ed69516418d850c6c265bd96e61.png

错误使用☀️

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


应该先有一个完整的类型名才能使用Node,而成员变量里面已经使用了,存在先后顺序问题


正确使用☁️

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


为简化创建变量的过程,可以讲类型名重定义,就会使用到typedef

typedef struct Book
{
  char name[20];
  int price;
}Book;//不能再将全局变量加在这里后面
Book b3;//全局
Book b4;//全局
int main()
{
  struct Book b1;
  struct Book b2;
  Book b3;//struct Book的别名
  return 0;
}


类型名的重命名也可以用到

struct Book
{
  char name[20];
  int price;
};
typedef struct Book Book;


不同点⚡

这里是两个不同的东西
struct 
{
  char c;
  int a;
  double d;
}s1;//匿名结构体变量
typedef struct
{
  int data;
  char c;
} S;//结构体类型,本来是没有名字的,现在重新起名字



1.6特殊的声明

匿名结构体定义变量🐶

struct  //省略了结构名 struct+结构名=类型名
{
  char c;
  int a;
  double d;
}s1;//匿名结构体只能这样定义变量
int main()
{
  struct s2;//错误,不能这样写
  return 0;
}


匿名结构体是一次性用品

匿名结构体成员相同但类型不同🐰

struct 
{
  char c;
  int a;
  double d;
}s1;
struct
{
  char c;
  int a;
  double d;
}* ps;
int main()
{
  ps = &s1;//err
  return 0;
}


0465ef326d4d4ef5b6ce73cba32619f5.png

  • 相同结构体类型:

通过同一个结构体 定义出来的变量 就相当于 int a; int b

a和b是两个不同的变量,但是它们的类型都是int类型

  • 结构体类型不同: (上图就是结构体类型不一样)

用一个结构体类型的指针 指向另一个结构体类型的指针时  编译器会报出警告,类型不兼容

虽然两个匿名结构体类型的成员都完全相同,但是他们的类型还是不同的


1.7结构的自引用📍

//这是一个错误的示范
struct Node
{
  int data;
  struct Node n;//自己类型的变量 
};


这里是结构体中的一个成员是它这个结构体本身。 那它无限套娃 永远也停止不了

92ebaa302aa940dfa8631f2e0fbcd1e2.png

这属于线性数据结构,一个结点包括数据域和指针域

正确写法:

//当一个结构体要找到另外一个同类型的结构体的时候
//应该在自己类型里面包含一个自己类型的指针,而不是自己类型的变量 
struct Node
{
  int data;//4
  struct Node* next;//4/8
};
int main()
{
  struct Node n1;
  struct Node n2;
  n1.next =  &n2;
  return 0;
}


相关文章
|
存储 编译器 Linux
详解结构体、位段、枚举、联合类型【C语言/进阶】
详解结构体、位段、枚举、联合类型【C语言/进阶】
78 0
|
6月前
|
存储 开发框架 编译器
C语言进阶—自定义类型:结构体,枚举,联合
C语言进阶—自定义类型:结构体,枚举,联合
|
6月前
|
存储 开发框架 .NET
【C语言进阶】自定义类型详解(结构体、枚举、联合)
【C语言进阶】自定义类型详解(结构体、枚举、联合)
|
存储 编译器 Linux
C语言进阶-自定义类型:结构体、枚举、联合(1)
C语言进阶-自定义类型:结构体、枚举、联合
74 0
|
存储 编译器 C语言
C语言进阶-自定义类型:结构体、枚举、联合(2)
C语言进阶-自定义类型:结构体、枚举、联合
62 0
|
编译器 C语言
C语言进阶,第4节-自定义类型详解(结构体+枚举+联合)
C语言进阶,第4节-自定义类型详解(结构体+枚举+联合)
|
存储
自定义类型:结构体2.0(初阶+进阶)+位段+枚举+联合(中)
自定义类型:结构体2.0(初阶+进阶)+位段+枚举+联合(中)
|
存储 编译器
自定义类型:结构体2.0(初阶+进阶)+位段+枚举+联合(下)
自定义类型:结构体2.0(初阶+进阶)+位段+枚举+联合(下)
|
C语言
C语言进阶-自定义类型:结构体、枚举、联合(下)
C语言进阶-自定义类型:结构体、枚举、联合(下)
86 0
|
编译器 Linux C语言
C语言进阶-自定义类型:结构体、枚举、联合(上)
C语言进阶-自定义类型:结构体、枚举、联合(上)
69 0