结构体类型的声明
struct tag
{
    //成员列表(可以包含各种变量成员)
    member-list;
}
//变量列表(声明全局的结构体变量)
variable-list; 
例如描述一个学生:
struct Stu
{
    char name[20];//名字
    int age;//年龄
    char sex[5];//性别
    char id[20];//学号
}; 
 
特殊的声明
在声明结构体时,可不完全声明。
//匿名结构体类型
struct
{
    int a;
    char b;
    float c;
}x;
struct
{
    int a;
    char b;
    float c;
}*p; 
 
我们可以看到两个结构体的成员都一样,那是否可以使用以下代码?
p = &x; 
 
结构的自引用
struct Node
{
    int data;
    struct Node next;
}; 
 
正确的自引用方式,应该类似于链表结构,如:
struct Node
{
    int data;
    struct Node* next;
}; 
注意不能使用一下代码
typedef struct
{
    int data;
    Node* next;
}Node; 
 
typedef struct Node
{
    int data;
    struct Node* next;
}Node; 
结构体变量的定义和初始化
struct Point
{
    int x;
    int y;
}p1;                //声明类型的同时定义变量p1
struct Point p2;    //定义结构体变量p2
//初始化:定义变量的同时赋值。
strruct Point p3 = {x, y};
struct Stu        //类型声明
{
    char name[15];//名字
    int age;      //年龄
};
struct Stu s = {"zhangsan", 29};//初始化
struct Node
{
    int data;
    struct Point p;
    struct Node* next;
}n1 = {10, {4,5}, NULL};            //结构体嵌套初始化
struct Node n2 = {20, {5, 6}, NULL};//结构体嵌套初始化 
结构体内存对齐
知道了结构体的基本使用方法后,我们来深入了解结构体,学会求结构体的大小。
结构体的对齐规则
为什么要内存对齐
平台原因(移植原因)
性能原因
综上所述
结论
//将S1改为S2
struct S1
{
    char c1;
    int i;
    char c2;
};
struct S2
{
    char c1;
    char c2;
    int i;
}; 
修改默认对齐数
#pragma 预处理指令可以改变默认对齐数。
#include <stdio.h>
#pragma pack(8)//设置默认对齐数为8
struct S1
{
    char c1;
    int i;
    char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认
#pragma pack(1)//设置默认对齐数为1
struct S2
{
    char c1;
    int i;
    char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认
int main()
{
    //输出的结果是什么?
    printf("%d\n", sizeof(struct S1));//16
    printf("%d\n", sizeof(struct S2));//6
    return 0;
} 
结构体传参
关于结构体传参这里有两种方式,看看哪一种更好。
struct S
{
    int data[1000];
    int num;
};
struct S s = {{1,2,3,4}, 1000};
//结构体传参
void print1(struct S s)
{
    printf("%d\n", s.num);
}
//结构体地址传参
void print2(struct S* ps)
{
    printf("%d\n", ps->num);
}
int main()
{
    print1(s); //传结构体
    print2(&s); //传地址
    return 0;
}









