结构体解析–用法及大小
1.什么是结构体
结构体:一种数据类型,类似于int,char,long等。当一种对象不止一种数据类型时,可以使用结构体来包含不同变量。例如:建立学生信息系统,一个学生的信息包含姓名,年龄,学号,家庭住址等等姓名,家庭住址为char型;年龄,学号为int型,这时可以使用结构体类型
定义学生变量,就可以了。
结构体关键字为struct,结构体建立如下:
struct Student
{
char name[20];//姓名,20个字节
int num;//学号
int age;//年龄
};
struct Student stu1;//定义一个变量stu1,
这是一个结构体类型,定义变量时要加上struct,这样就很麻烦,所以引用
typedef重命名,即重新起名字,用新名字替换旧(繁琐的)名字。
格式:typedef 旧名字 新名字
typedef struct Student
{
char name[20];
int num;
int age;
}student;//,以后定义变量时可以不再加入struct
student stu2;//定义变量stu2
比较二者(stu1,stu2)是不是加上typedef方便很多,也容易理解呢。
2.结构体初始化:
1不可以在结构体内初始化
2聚合类型(数组,结构体)只初始化一部分,其余值为0。
```cpp
typedef struct Date
{
int Year;
int Month;
int Day;
}date;
int main()
{
date d = {2000};
printf("%d,%d,%d",d.Year,d.Month,d.Day);
return 0;
}
```cpp
struct Student
{
char *name;//姓名为字符串,定义为指针,也可以定义为数组[外链图
int num;//学号
int age;//年龄
};
int main()
{
struct Student stu1 = {"小王",1,23};
struct Student stu2;
stu2.name = "乐乐";//如果定义为数组,则不能赋值,字符串
stu2.num = 2;
stu2.age = 24;
printf("%s,%d,%d\n",stu1.name,stu1.num,stu1.age);
printf("%s,%d,%d\n",stu2.name,stu2.num,stu2.age);
return 0;
}
结构体包含的数据较多,因此数据较大,再传参数时就不适用,因次定义结构体指针,传指针。
3.结构体指针传参,修改值
typedef struct Student
{
char *name;//指针指向姓名
int num;//学号
int age;//年龄
}student;
void Show(student *p)
{
printf("%s,%d,%d",p->name,p->num,p->age);
}
int main()
{
student arr[] = {"乐乐",2,24,"豆豆",3,19,"阳阳",4,18};
student *p = &arr[1];//指针p指向豆豆
p->name = "月月";//修改姓名,如果说name定义为数组则不能修改,name为字符串常量
//p->num = 6;//修改豆豆学号
//p->age = 20;//修改豆豆年龄
//printf("%s,%d,%d",p->name,p->num,p->age);
for(int i = 0;i < sizeof(arr)/sizeof(arr[0]);i++)
{
printf("%s,%d,%d\n",arr[i].name,arr[i].num,arr[i].age);
}
/*printf("%s,%d,%d",stu2.name,stu2.num,stu2.age);*/
return 0;
}
4 .访问:
访问成员,2种方式:
1.结构体普通变量通过".“访问其成员
2.结构体指针通过”->"访问其成员
使用->,如p1->age
使用(p1).age,注意必须用圆括号,因为.运算符比的优先级更高
typedef struct Student
{
char *name;//姓名为字符串,定义为指针,也可以定义为数组char[20]
int num;//学号
int age;//年龄
}student;
int main()
{
student stu1 = { "hh",10,5};
student stu2;
student *p2 = &stu2;
p2->name = "荣荣";
p2->num = 12;
p2->age = 10;
student stu3 = {"真真",11,20};
student *p3 = &stu3;
printf("%s,%d,%d\n",stu1.name,stu1.num,stu1.age);
printf("%s,%d,%d\n",p2->name,p2->num,p2->age);
printf("%s,%d,%d\n",(*p3).name,(*p3).num,(*p3).age);
return 0;
}
5 .结构体内再嵌套结构体
结构体嵌套注意:
嵌套的结构体一定要在之前声明
struct Date
{
int Year;
int Month;
int Day;
};
typedef struct Student
{
char *name;//姓名
int num;//学号
int age;//年龄
struct Date birthday;//引用结构体Date
}student;
int main()
{
student stu3 = {"猪猪",1,12};
student *p = &stu3;
p->birthday.Year = 2000;
p->birthday.Month = 10;
p->birthday.Day= 10;
printf("%s,%d,%d,%d,%d,%d\n",stu3.name,stu3.num,stu3.age,stu3.birthday.Year,
stu3.birthday.Month,stu3.birthday.Day);
printf("%d\n",sizeof(stu3));//计算stu3字节大小
return 0;
}
6.计算结构体大小
内存对齐的使用规则:
1.前面的地址必须是后面的地址的整数倍,不是补齐
2.整个struct的长度必须是最长字节的整数倍!
struct A
{
};//结构体没定义变量
struct B
{
char a;//1+3,前面的地址必须是后面的地址的整数倍,所以加3
int b;//4
};//8个字节
struct B1
{
char a;
int b;
};//8
struct C
{
int b;
char a;
};//8
struct D
{
char a;//1+1
short b;//2+2
int c;//4
};//8
struct D1
{
short b;//2+2
int c;//4
char a;//1+3
};//12
struct E
{
int a;//4
char c;//1
short b;//2
};//8
struct F
{
int a;
char b;
double c;//8
};//16
struct G
{
double a;
char b;
int c;
float d;
};//24
struct H
{
unsigned int a;
short b;
char c;
};
struct HH//
{
char a;
struct H
{
unsigned int a;
short b;
char c;
};
};//1
struct HHH
{
char a;
struct H
{
unsigned int a;
short b;
char c;
}h;
};//12
struct HHHH
{
char d;
struct
{
unsigned int a;
short b;
char c;
};
};//12
int main()
{
printf("%d\n",sizeof(A));//c++会预存位置,值是1,c语言是0
printf("%d\n",sizeof(B));//8
printf("%d\n",sizeof(C));//8
printf("%d\n",sizeof(D));//8
printf("%d\n",sizeof(D1));//12
printf("%d\n",sizeof(E));//8
printf("%d\n",sizeof(F));//16
printf("%d\n",sizeof(G));//24
printf("%d\n",sizeof(H));//8
printf("%d\n",sizeof(HH));//1,结构体H是数据类型,并没有定义变量
printf("%d\n",sizeof(HHH));//定义了变量
printf("%d\n",sizeof(HHHH));//12
//printf("%d\n",sizeof(C));
return 0;
}
7.#pragma pack(n)预编译指令
则所有成员对齐以n字节为准(即偏移量是n的整数倍),不再考虑当前类型以及结构体内最大类型
注意:
n必须是已有的大小。如:1,2,4,8
无论n值或者最大的结构体内数据类型,哪个大就照哪个值算
//#pragma pack(1)//字节对齐
struct A
{
char a;
int b;
};//5
int main()
{
printf("%d\n",sizeof(A));//5
return 0;
}