一、结构体定义与声明
结构体:是一组数据的集合,这些数据称为成员变量,成员变量可以是不用类型的数据
1.结构体声明格式:
struct Stu
{
int id;
char* name;
int sex;
};
2.结构体变量声明:
//全局结构体变量
struct Stu stu;
//局部结构体变量
void main()
{
//结构体变量
struct Stu stu = { 10,"王老二","male" };
}
struct Stu
{
int id;
char name[10];
char sex[10];
}s1,s2,s3; //全局的结构体变量
3.特殊声明形式——匿名结构体
//匿名结构体
struct
{
int id;
char name[10];
char sex[10];
}stu1;
注意:
- 匿名结构体一定要在声明后直接加上结构体变量,且该结构体只能使用一次
- 两个匿名结构体具有相同成员变量,但编译器是认为两个结构体是不一样
4.结构体自引用
typedef struct Node
{
int date;
char name[30];
Node *next;
}Node;
void main()
{
Node n={0};
}
结构体自引用必须使用结构体指针 :Node *next
typedef将 struct Node这个结构体类型重新定义为Node,后续结构体变量的声明中可以直接用Node声明
二、结构体变量的初始化
struct Stu
{
int id;
char name[10];
char sex[10];
};
void main()
{
//1.创建变量时按顺序赋值
struct Stu stu1 = { 10021,"Oliver","male" };
//2.创建变量时,乱序赋值(嵌入式C中常用风格)
struct Stu stu2 = {
.id = 10022,
.name = "Selina",
.sex = "female"
};
//3..创建变量后,逐个赋值
struct Stu stu3 = {0};
stu3.id = 10023;
strcpy(stu3.name,"Maria");
strcpy(stu3.sex,"male") ;
printf("%s\n%s", stu3.name, stu3.sex);
}
注意: 用逐个赋值方法将字符串赋值给字符数组时不能用
stu3.name="Maria";这种方法赋值
因为字符串赋值时实际上代表的是这个字符串首字符的地址,而stu3.name是一个地址常量(数组首元素地址),不能被赋值
成员变量是字符指针可以用这种方式赋值,如:
struct Stu
{
int id;
char name[10];
char sex[10];
char* address;
};
stu3.address = "FZU";
三、结构体成员变量调用
1.结构体变量.成员名
struct Stu
{
int id;
int height;
char* name;
};
void main()
{
struct Stu s = { 20,177,"Green" };
printf("%d\n",s.id);
printf("%d\n", s.height);
}
2.结构体指针->成员名
void main()
{
struct Stu* ps;
ps = &s;
printf("%d\n", ps->id);
printf("%d\n", ps->height);
}
四、结构体内存对齐
1.结构体内存对齐规则
首先要明白什么是对齐数
对齐数:编译器的默认对齐数和该成员大小中的最小值
例如vs编译器的默认对齐数是8,char类型成员的大小是1,所以这个成员的对齐数是1
明白什么是对齐数后再来看结构体内存的对齐规则
1.第一个成员放在与结构体变量地址偏移量为0的地方,即结构体变量的地址处
2.第二个成员对齐到这个成员对齐数整数倍的偏移量处
3.整个结构体大小等于所有成员对齐数中的最大值的整数倍
4.如果有嵌套结构体,则嵌套的结构体对齐到它最大对齐数整数倍偏移量的地址处。外部的结构体大小是所有成员(包括嵌套在内的结构体)最大对齐数的整数倍
设计结构体时尽量让占用空间小的成员变量放在一起
2.修改默认对齐数
#pragma pack(4)
括号内即修改的对齐数的值
五、结构体传参
结构体作为函数参数进行传递时,最好是传结构体指针
struct Stu
{
int id;
int height;
char* name;
};
void print_struct(struct Stu *s)
{
printf("id:%d\n",s->id);
printf("height:%d\n", s->height);
printf("name:%s\n", s->name);
}
void main()
{
struct Stu s = { 20,177,"Green" };
struct Stu* ps = &s;
print_struct(ps);
}
六、位段
位段中规定了每个成员比特位数
struct T
{
int a : 2;
int b : 3;
int c : 30;
int d : 20;
};
void main()
{
struct T t = { 2,6,1200,1500 };
t.a = 11;
t.b = 11111;
t.c = 11111111;
t.d = 1111111111;
}