自定义类型—结构体

目录

文章目录

一、结构体类型的声明

结构的声明

结构体变量的创建和初始化

结构体的特殊声明

二、结构体内存对齐

1.对齐规则

2.修改默认对齐数

3.结构体传参

总结


一、结构体类型的声明

  • 结构的声明

注意:结构体类型的关键字是struct

struct Stu {
	int a;
	char b;
};


  • 结构体变量的创建和初始化

//在声明结构体时创建变量
struct Str{
int a;
char b;

}s,str;//两个变量之间用,隔开






//先声明后创建
struct Str{
int a;
char b;
};

int main()
{   
    //按照结构体成员的顺序初始化
    struct Str s={3,"c"};//初始化时用大括号括起来,各个变量之间用,隔开
    //按照指定的顺序初始化
   struct Str s={.b="c",.a=3};
    return 0;
}

  • 结构体的特殊声明

在声明结构的时候可以不完全声明

#include <stdio.h>
//匿名结构体类型
struct {
	int a;
	char b;
	float c;
}x;

struct {
	int a;
	char b;
	float c;

}str,*p;
int main()
{

	return 0;
}

由上代码可见,对于没有标签的结构声明,这两个变量是同一种类型吗我们可以做一下调试,发现编译器会把上面两个声明当作完全不同的两个类型,如果没有对结构体类型重命名,基本上只能使用一次


二、结构体内存对齐

1.对齐规则

  • 结构体的第一个成员对齐到结构体变量起始位置偏移量为0的地址处 
  • 其他成员要对齐对齐数的整数倍的地址处
  • 对齐数=编译器的默认对齐数与该成员变量大小的较小值

注意:vs中默认对齐数为8,linux和gcc中没有默认对齐数,对齐数就是成员自身大小

  • 结构体总大小为最大对齐数(所有结构体成员中的最大值)的整数倍
  • 如果出现结构体嵌套的现象,嵌套的结构体对齐到自己成员中最大对齐数的整数倍

下面我们用几个例题来讲解一下:


结构体嵌套情况:

此时struct S中嵌套了struct D


2.修改默认对齐数

#pragma这个预处理指令,可以改变编译器的默认对齐数

#include <stdio.h>

#pragma pack(1)//设置默认对齐数为1
struct S {
	int a;
	float b;
	char c;

}s;
#pragma pack()//预处理指令一般不建议写在函数内部,包括主函数,因为预处理指令是在编译阶段进行处理的,作用域常常是全局
int main()
{
	printf("%zd\n", sizeof(s));
//取消设置的对齐数,还原为默认
	printf("%zd\n", sizeof(s));
	return 0;
}

易错点:我们看到当恢复为默认对齐数时,结构体大小任然是9,这是因为在我重新恢复默认对齐数的时候,系统已经给这个结构体分配好了内存空间,后面再还原的时候也不会再重新分配了内存空间了,所以结构体的内存大小不变。


3.结构体传参

小tips:结构体传参的时候要传结构体的地址

我们知道函数中临时变量的创建需要压栈,会浪费时间和空间,特别是当一个结构体过大时,所以我们推荐传址。


总结

结构体的内存对齐是一个非常热门的问题,结构体的定义和使用也是C语言中的重要内容

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值