结构体类型的声明
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;
}