1.结构体的定义
结构体是一种特殊的数据类型,由程序员自己设计,分配的内存空间连续。
struct 结构体名
{
成员列表 //可以是基本数据类型也可以是,指针,数组,其他结构体,联合体等
};
结构体本身并不占用空间,结构体变量才占用空间。
结构体成员的顺序就是内存分配的顺序。
2.结构体的内存对齐
struct Student
{
char s_id[10];
char s_name[10];
char s_sex[4];
int age;
};
int main()
{
struct Student s1={.....};
内存分配遵循的原则:
1)首地址必须是结构体变量中的“最大基本数据类型成员所占字节数”的整数倍;
2)每个成员相对结构体首地址的偏移量,都是该成员基本数据类型所占字节数的整数倍;
3)结构体变量总大小,为结构体变量中“最大基本数据类型成员所占字节数”的整数倍。
注意:char b[10] 数组,按char来算,基本数据类型所占字节数为1,而不是10。
3.结构体的初始化
1)用“{}”初始化连续的空间
2)用已经定义的结构体整体赋值另一个结构体变量
3)用已定义的结构体部分赋值另一个结构体变量的部分(并不适用于所有情况,比如数组类型就不可以,数组类型需要用strcpy_s函数)
4)不可以强转类型来赋值
struct Elem
{
char s_name[20];
int age;
};
struct Student
{
char s_name[20];
int age;
};
int main()
{
struct Student s1={"aijiawei",23}; \\1)
struct Student s2=s1; \\2)
s2.age=s1.age; \\3)
s2.name=s1.name; \\3)错误,因为name代表数组首元素的地址,地址给地址赋值是错误的
strcpy_s(s2.name,20,s1.name); \\3)正确,使用拷贝函数
struct Elem e1=s1; \\4)错误,e1和s1是两种数据类型
return 0;
}
4.结构体的使用(使用指针更佳)
void Print(char *p,int n) \\sizeof(p)=4
{
.......
}
void Print(char br[],int n) \\sizeof(br)=24
{
.......
}
struct Student
{
char s_name[20];
int age;
};
int main()
{
struct Student s1={"aijiawei",23};
Print(s1,24)
return 0;
}
5.柔性数组(只有结构体才可以这样用)
柔性数组不占用内存,只是一个符号。必须在结构体成员中在最后声明。
struct student
{
int a;
char b[]; //或者 char b[0];
};
用途:长度为0的数组,为了满足长度可变的结构体,必须在最后声明。
5.1柔性数组和指针的对比
柔性数组:
struct student
{
int a;
char b[0];
};
int main()
{
struct student *s1=(sturct student*)malloc(sizeof(struct student)+50);
s1->a=10;
strcpy(s1->b,20,"aaaa");
printf("%d",sizeof(*s1); //4,永远都是4,和50无关
free(s1);
s1=nullptr;
return 0;
}
指针:
struct student
{
int a;
char *b;
};
int main()
{
struct student *s1=(sturct student*)malloc(sizeof(struct student));
struct student *b=(sturct student*)malloc(sizeof(char)*50);
s1->a=10;
strcpy(s1->b,20,"aaaa");
printf("%d",sizeof(*s1); //8,a占四个,b是个指针类型占4个
free(b); //必须先释放,后释放s1
b=nullptr;
free(s1);
s1=nullptr;
return 0;
}
注意:sizeof是在编译之前就已经计算了,而不是把数据链接进去才开始计算
5.2柔性数组的优点
struct 1
{
int a1;
int b1[2];
};
struct 2
{
int a2;
int b2[0];
};
int main()
{
struct 1 x={1,2,3}; //只可以放三个
struct 2 y={1,2,3,4,5,6,7,8}; //空间可变,可以放更多内容
sizeof(x); //12
sizeof(y); //4,柔性数组不占用空间
return 0;
}