C语言_结构体

1、结构体是什么?

   结构体是由一批数据组合而成的一种新的自定义类型。

2、为什么需要有结构体的类型?

   内置类型不能表示所有的场景,比如:学生群体;描述学生:name、age、gender、height。

struct Student{
	char name[20];
	int age;
	char gender[3];
	double height;
};

3、结构体内存对齐

(1)为什么需要内存对齐?
   1、平台原因(移植原因):
不是所有的硬件平台都能访问任意地址上的任意数据;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
   2、性能原因:
数据结构(尤其是栈)应该尽可能地在自然边界上对齐;
原因在于,为了访问未对齐的内存,处理器需要作两次内存访问,而对齐的内存访问仅需要一次。

(2)如何进行内存对齐?
这里分为两大步骤:
1、使结构体中每个成员变量都处在对齐的地址上:
   a、结构体中的第一个成员变量在偏移量为0的地址上;
   b、剩余的变量,对齐规则:min(该变量类型,默认对齐数),然后检测该变量相对于结构体起始位置的偏移量是不是该min的整数倍。不是的话,需要在该变量之前补齐字节数。
2、让结构体整体对齐:
   使得结构体大小为 min(结构体成员变量类型最大者,默认对齐数)的最小整数倍。

(3)求结构体中某个成员变量相对于结构体起始位置的偏移量?
   offsetof(结构体类型, 成员名字)
   模拟实现该宏:

#define offsetof(s, m) (size_t)&(((s*)0)->m)
//让编译器将0号地址单元开始的一块内存作为S的结构体进行解析。

4、位段

   位段为一种数据结构,可以把数据以位的形式紧凑的存储,并允许程序员对此结构的位进行操作。

位段的好处:
   跟结构体相比,位段可以达到同样的效果,但是可以很好的节省空间。
位段的缺点:
   位段的内存分配与对齐的实现方式依赖于具体的机器和系统,在不同的平台可能有不同的结果,这导致了位段在本质上是不可移植的。

位段内存对齐:
   a、前后类型相同,比特位能共用则共用,否则重新开辟对应类型的空间;
   b、前后类型不一致,重新开辟空间。

5、联合体

   联合体也是一种特殊的自定义类型,这种类型定义的变量也包含一系列的成员,特征是这些成员共用同一块内存空间。

联合的特点:
   联合的成员共用同一块空间,这样一个联合变量的大小,至少是最大成员的大小。

联合大小的计算:

  • 联合的大小至少是最大成员的大小;
  • 当最大成员大小不是最大对齐数的整数倍的时候,就到对齐到最大对齐数的整数倍。

6、什么是大小端?

   大端模式:指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中。
   小端模式:指数据的低位保存在内存的低地址中,而数据的低位,保存在内存的高地址中。

为什么有大小端?
   因为在计算机系统中,我们是以字节为单位的,每个地质单元都对应着一个字节,一个字节位8bit,但是在C语言中除了8bit的char之外,还有16bit的short、32bit的long(具体看编译器),对于位数大于8位的处理器,由于寄存器大于一个字节,那么必然存在一个如何将多个字节安排的问题,因此就导致了大端存储模式和小端存储模式。

大小端跟操作系统是否有关系?
  跟操作系统没有关系,CPU是大小端存储的决定因素。

如何测试一个机器为大端还是小端?

//利用联合体判断
int check_sys()
{
	union
	{
		int i;
		char c;
	}un;
	un.i = 1;
	return un.c;
}

int main()
{
	int ret = check_sys();
	if (ret == 1)
	{
		printf("小端\n");
	}
	else
	{
		printf("大端\n");
	}
	system("pause\n");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值