结构体解析--用法及大小

结构体解析–用法及大小

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;
}

由于小编学术不精,先总结到这,如有疑问,欢迎读者留言!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值