自定义类型:结构体(1)
1.结构体回顾
结构是一些值的集合,这些值被称为成员变量。结构的每个成员可以是不同类型的变量。
1.1结构的声明
struct tag
{
member-list;
}variable-list;
例如描述一个学生:
struct Stu
{
char name[20];
int age;
char sex[5];
};
1.2结构体变量的创建和初始化
#include <stdio.h>
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;
定义结构体尽量不要使用匿名结构体。