自定义类型:结构体,枚举,联合

1,结构体
      

结构体变量的定义和初始化
#include<stdio.h>
#include<windows.h>
struct S                         //类型声明
{
	char  name[20];          //名字
	int age;                 //年龄
};
struct S1
{
	char  name[20];
	int age;
}s1 = { "李四", 25 };            //声明类型的同事定义变量s1
struct S2
{
	char  name[20];
	int age;
	struct S *node;
}s2 = {"王五",30,NULL};        //结构体嵌套的初始化
int main()
{
	struct S s = { "张三", 18 };            //初始化
	struct S2 s3 = { "周六", 40 };
	printf("%s %d\n", s.name, s.age);
	printf("%s %d\n", s1.name, s1.age);
	printf("%s %d\n", s2.name, s2.age);
	printf("%s %d\n", s3.name, s3.age);
	system("pause");
	return 0;
}

结果:
结构体内存对齐

结构体内存对齐是非常热门的考点。
那么为什么存在内存对齐?

1.平台原因
不是所有的硬件平台都能访问任意地址上的任意数据的。

2.性能原因
数据结构应该尽可能地在地在自然边界上对齐。

原因在于,为了访问未对齐的内存,处理器需要进行两次内存访问;而对其的内存访问仅需要一次访问。

内存对齐如何计算?
我们必须掌握结构体的对齐规则:

1.第一个成员在与结构体变量偏移量为0的地址处。
2.其他成员变量要对其到对齐数的整数倍的地址处。(对齐数=编译器默认的一个对齐数与该成员大小的较小值。vs中默认的值为8  Linux中的默认值为4)
3.结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
4.如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

举例子:
看代码:
#include<stdio.h>
#include<windows.h>
struct s1
{
	char a;
	int b;
	char c;
};
struct s2
{
	char a;
	char b;
	int c;
};
struct s3
{
	double a;
	char c;
	int i;
};
struct s4
{
	char a;
	struct s3 b;
	double c;
};
int main()
{
	printf("%d\n", sizeof(struct s1));
	printf("%d\n", sizeof(struct s2));
	printf("%d\n", sizeof(struct s3));
	printf("%d\n", sizeof(struct s4));
	system("pause");
	return 0;
}

结果:

解释:







2.位段
先来看一个位段类型代码:

#include<stdio.h>
#include<windows.h>
struct A
{
    int _a : 2;
    int _b : 5;
    int _c : 10;
    int _d : 30;
};
int main()
{
    printf("%d\n", sizeof(struct A));
    system("pause");
    return 0;
}

输出的结果为8;

位段有属于自己的特点:
(1)位段的成员必须是int ,unsigned int,signed int。

(2)位段的成员名后边有一个冒号和一个数字。

那么位段的大小是如何计算的?

由于是int类型,所以给位段的内存分配时,先分配四个字节的大小,如果够用,就不会继续分配;如果不够用,比如struct A ,先分配的四个字节不够用,然后在分配四个字节,总共就8个字节的大小。

3.联合
联合也是一种特殊的自定义类型,这中类型定义的变量也包含一系列的成员,但是这些成员公用一块空间(联合体也叫共用体)。

看代码:
#include<stdio.h>
#include<windows.h>
union Un
{
	char b;
	int  c;
};
int main()
{
	union Un a;
	printf("%d\n", sizeof(a));
	system("pause");
	return 0;
}

输出的结果为4;

联合的成员是公用同一块内存空间,这样一个联合变量的大小,至少是最大成员的大小。

联合可用于求此计算机的大小端存储。
看代码:

#include<stdio.h>
#include<windows.h>
int daxiaoduan()
{
	union 
	{
		int b;
		int c;
	}un;
	un.b = 1;
	return un.c;
}
int main()
{
	
	int ret = daxiaoduan();;
	if (ret = 1)
		printf("大端\n");
	if (ret = 0)
		printf("小端\n");
	system("pause");
	return 0;
}


联合大小的计算

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

比如:

#include<stdio.h>
#include<windows.h>
union  un1
{
	char a[5];
	int b;
};
union  un2
{
	short c[7];
	int b;
};
int main()
{

	printf("%d\n", sizeof(union un1));
	printf("%d\n", sizeof(union un2));
	system("pause");
	return 0;
}

结果:
在un1中,最大成员大小(5)不是最大对齐数(4)的整数倍,所以对齐到第八个字节处。

在un2中,最大成员大小(14)不是最大对齐数(4)的整数倍,所以对齐到第十六字节处。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值