C语言 结构体
结构体的自引用:
自引用的目的:
结构体的自引用就是指在结构体内部,包含指向自身类型结构体的指针。
像链表就会用到结构体的自引用。假如我们要创建链表
链表的没个节点都是一个结构体,它里面存放着它的数据和下个节点的地址。
假如我们用结构体创建了一个节点:
但是如果运行就会报错 :
这是因为根本无法确定结构体的大小,结构体的大小要看其成员变量的大小和
int data;
data的大小为整形的大小:4字节
struct node next;
struct Node next的大小其实就是struct Node的大小,我们根本算不出来,所以我们不能在结构体里面包含这个结构体本身类型,而应该用它的指针
struct Node {int data; //4字节struct node* next; //指针就是地址,地址就是4字节 };
这样这个结构体的大小就是8字节了
typedef的用法:
typedef是类型定义的意思。typedef struct 是为了使用这个结构体方便。
具体区别在于:
若struct node {}这样来定义结构体的话。在申请node 的变量时,需要这样写,struct node n;
若用typedef,可以这样写,typedef struct node{}NODE; 。在申请变量时就可以这样写,NODE n;
区别就在于使用时,是否可以省去struct这个关键字。
分三块来讲述:
1 首先:
在C中定义一个结构体类型要用typedef:
typedef struct Student
{
int a;
}Stu;
于是在声明变量的时候就可:Stu stu1;
如果没有typedef就必须用struct Student stu1;来声明
这里的Stu实际上就是struct Student的别名。
结构体的初始化:
首先创建一个结构体变量,然后对结构体到成员列表进行初始化
struct Node
{int data; //4字节char name[20];
};
int main()
{struct Node s1 = { 1, 'sun'};return 0;
}
这个s1是局部结构体变量
全局变量:s2和s3是全局结构体变量,s1是局部结构体变量,放在外面的全局结构体变量,里面的是局部结构体变量
结构体里面包含结构体的怎么初始化:
struct Node
{int data; //4字节char name[20];
}s2;struct ss
{int age;struct Node sss;
};
struct Node s3;
int main()
{return 0;
}
方法: 第一个结构体初始化用{ },里面再包含个{ }用来初始化第二个结构体
struct Node
{int data; //4字节char name[20];
}s2;struct ss
{int age;struct Node sss;
};
struct Node s3;
int main()
{struct ss que = { 10,{14,'wd'}};return 0;
}
还可以用.成员。列表的方式来初始化:
struct Node
{int data; //4字节char name[20];
}s2;struct ss
{int age;struct Node sss;
};
struct Node s3;
int main()
{struct ss que = { 10,{.data=2,.name='sad'}};return 0;
}
结构体成员对齐:
如下:求下面两个结构体的大小
struct S2
{char c1;char c2;int i;
};struct S3
{double d;char c;int i;
};int main()
{
printf("%d\n", sizeof(struct S2));
printf("%d\n", sizeof(struct S3));return 0;
}
按照正常来说:第一个结构体大小应该为:6
第二个结构体大小应该为13
但实际的运行结果为:
8
16
这就涉及到了结构体的对齐: