一、结构体
类型——>变量——>初始
1、声明:
struct
{
char name[20];
int age;
};//仅声明
struct Student
{
char name[20];
int age;
}Stu; //声明同时,仅定义Stu为结构体变量(相当于int a;)
2、初始化:
结构体和数组区别,数组不能先定义再进行一次性初始化;
结构体要明确的告诉系统{}中是一个结构体
//1.定义的同时初始化
struct Student = {"zhangsan",20};
//2.先定义再逐个初始化
struct Student Stu;
Stu.name = "Lisi";
Stu.age = 18;
//3.先定义再一次性初始化
struct Student Stu;
Stu= (struct Student ){"lisi",18};
//4.指定将数据赋值给指定的属性
struct Student Stu= {Stu.name="wang", Stu.age=20};
3、与typedef
任一变量加上typedef后,均提升为数据类型
int (*p)[10];
typedef int (*P)[10];//数组指针类型
P p1 = arr;//定义一个数组指针类型的p1,指向数组arr
int (*P)(int, int);
//回调函数
typedef int (*P)(int, int);//函数指针类型
P p2 = Max2;//定义一个函数指针p2,指向函数Max2
//此时 p2(2,10) = Max2(2,10)
typedef 与 # define
(1)typedef :自定义类型,即起别名
(2)#define:字符替换
typedef int* Pint;
Pint a, b;//a, b均为int*类型
#define Dint int*
Dint a, b;//a为int*类型, b为int类型
二、结构体与数组
数组不能先定义再进行一次性初始化,而结构体可以;
数组中的元素必须为统一类型,而结构体可以自定义多种类型;
结构体要明确的告诉系统{}中是一个结构体;
对于结构体字符类型成员的修改,用strcpy()
数组结构体:
struct Student Stu[10];
Stu[0].name;//调用数组内成员
int len = sizeof(Stu)/sizeof(Stu[0]);//数组长度
三、结构体的打印(区别“.”与”->”)
(1)传入结构体变量:
Stu.name;//调用
(2)传入结构体指针:”->”同”[]”、”*”表示解引用
(*Stu).name;
Stu->name;//
优先提倡运用(2),尤其结构体所占字节过多时
struct A
{
int a;
int *b;
}A;
struct B
{
int a1;
int *b1;
struct A *p;
}B;
int main()
{
B b;
//调用B中成员
b.a1;
b.b1;
b.p;
//调用A中成员
b.p->a;
b.p->b;
}
四、结构体的引用
(1)结构体的自引用(self reference):在结构体内部,包含指向自身类型结构体的指针
struct A
{
int a;
int *b;
struct A p;//错误,类似递归,在分配内存的时候,由于无限嵌套,无法确定这个结构体的长度
struct A *p;//合法,4字节(32位),指向相同类型的下一个;多用于链表
}A;
(2)结构体的相互引用(mutual reference):在多个结构体中,都包含指向其他结构体的指针
struct B
{
int a1;
int *b1;
struct A *p;//在B中引用指向A的指针
}B;
五、结构体的大小
结构体特点:空间换取时间
1、存入地址号必须能整除其字节大小;
2、char(1字节)随遇而安,任何地址号均能整除;
3、相同类型数据不同排序,其占用空间大小不同;
4、最大字节数(整体所占字节数必须能整除以它);
5、向上对齐;
struct A{
int a;//4
char b;//1+3
}A;//8
6、向下对齐;
struct B{
char a;//1+3
int b;//4
}B;//8
7、结构体指针:4字节;
8、结构体的嵌套,依然遵循以上原则;
9、空结构体/空类:0字节。