c语言中的结构体

本文详细介绍了C语言中的结构体,包括普通声明和特殊声明方式,结构体变量的创建,以及结构体的自引用问题。特别讨论了结构体内存大小的计算,涉及到内存对齐的规则,并通过实例分析了不同结构体大小差异的原因。此外,还提到了如何设置默认对齐数以影响结构体的内存布局。
摘要由CSDN通过智能技术生成

在这里插入图片描述

积土成山

1.结构体的声明

1)普通声明

声明一个学生类型,结构体是不同类型变量的集合。

struct student
{
	char name[20];
	int age;
};//分号不能丢
结构体变量的创建

在这里插入图片描述

2)特殊声明

去掉student这样的标识

struct 
{
	char name[20];
	int age;
};
1.结构体变量的创建
struct
{
	int a;
	char b;
	float c;
}x;
int main()
{
	struct m;
	x.a=5;
	m.a = 5;//这里会报错(m无法未定义的标识符)
	printf("%d", m.a);
	printf("%d", x.a);
	return 0;
}

我们发现在这种情况下不能创建局部变量,只可以创建全局变量。

2. 多个特殊声明时

我们尝试把两个struct下的一个变量x的地址赋给,另一个struct下的p。

struct
{
	int a;
	char b;
	int c;
}a[20], * p;
struct
{
	int a;
	char b;
	float c;
}x;
int main()
{
	p = &x;//这里会报错“从“*”到“*”的类型不兼容。”
	return 0;
}

这样表示编译器会把他们当成是两个不同的结构体;

2.结构体的自引用

1. 错误的形式

我们尝试在结构体中创建结构体,下面这样可行吗?

struct Node
{
	int data;
	struct Node next;//这里会报错(未定义的struct “Node”)
};
int main()
{
    int sum = sizeof(struct Node);
    printf("%d", sum);
	return 0;
}

无法打印sum,那我们自己思考一下结构体的内存大小是多少。
假设struct Node的大小为x
在这里插入图片描述

2.正确的形式
struct Node
{
	int data;
	struct Node *next;//通过指针的形式找到下一个结构体
};
int main()
{
	struct Node p;
	struct Node m;
	p.next = &m;
	p.next->data = 10;
	printf("%d", m.data);
	int sum = sizeof(struct Node);
	printf("%d", sum);
	return 0;
}

这里的结构体大小sum明显是个定值,一个int类型加上一个指针变量。

3.结构体的内存大小

1.结构体内存大小的计算
struct s1
{
	char c1;
	int i;
	char c2;
};
struct s2
{
	char c1;
	char c2;
	int i;
};
int main()
{
	printf("%d\n", sizeof(struct s1));
	printf("%d\n", sizeof(struct s2));
	return 0;
}

在这里插入图片描述
结构体储存的变量相同,但是内存大小却不一样,这是为什么呢?

结构体的内存对齐规则
1. 第一个成员在与结构体变量偏移量为0的地址处。
  1. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
    对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。
    VS中默认的值为8

  2. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。

  3. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整
    体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

画图演示一下

在这里插入图片描述

这里我们再讲一个特例:一个结构体内储存结构体变量的情况
struct S3
{
	double d;
	char c;
	int i;
};
struct S4
{
	char c1;
	struct S3 s3;
	double d;
};
int main()
{
	printf("%d", sizeof(struct S4));
	return 0;
}

那么我们来思考一下s4的内存大小是多少?
打印的结果是32。这是怎么计算的?
在这里插入图片描述

2. 设置默认对齐数

在c语言中我们是可以自己设置默认对齐数的

#pragma pack(8)//设置默认对齐数为8
struct S1
{
	char c1;
	int i;
	char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认
#pragma pack(1)//设置默认对齐数为1

修改默认对齐数后计算结构体的内存大小的规则不变。

谢谢大家的阅读与支持!在这里插入图片描述

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值