结构体...

结构体类型创建

1.有名结构体的定义方式

(1)声明结构体的同时,定义结构体

struct Stu              //Stu为结构体名
{
	char name[10];
	char sex[5];    //结构体成员
	short age;
}student1,student2;     //student1,student2为结构体变量

(2)先声明,后定义

struct Stu              //Stu为结构体名
{
	char name[10];
	char sex[5];    //结构体成员
	short age;
};
struct Stu student1;   //student1为结构体变量

2.无名结构体的定义方式

struct
{
	char name[10];
	char sex[5];    //结构体成员
	short age;
}student1;             //student1为结构体变量

3.别名结构体的定义方式

typedef struct Student  //Student为结构体名
{
	char name[10];
	char sex[5];    //结构体成员
	short age;
}Stu;              //Stu为结构体类型的别名

Stu student1;     //相当于struct Student student1

结构体初始化

1.定义的同时初始化

2.先定义再逐个初始化

struct Student//Student为结构体名
{
	char name[10];
	char sex[5];    //结构体成员
	short age;
};
int main()
{
	//1.定义的同时初始化
	struct Student stu1 = {"小明","男",17};


	//2.先定义再逐个初始化
	struct Student stu2;
	strcpy(stu2.name,"小红");
	strcpy(stu2.sex,"女");
	stu2.age = 16;


	return 0;
}

结构体内存对齐

一个结构体所占内存大小并不等于其所有元素内存大小之和

例:

struct S
{
	char a;
	int b;
	double c;
};
int main()
{
	struct S str;
	printf("sizeof(char) = %d\n",sizeof(char));
	printf("sizeof(int) = %d\n",sizeof(int));
	printf("sizeof(double) = %d\n",sizeof(double));
	printf("sizeof(str) = %d\n",sizeof(str));

	return 0;
}

运行结果:


经过测试,结构体str的大小并不等于sizeof(char)+sizeof(int)+sizeof(double)=13,而结果为16,那结构体的内存是怎样计算的?

结构体内存的计算是需要遵循结构体内存对齐规则的,那为什么结构体需要内存对齐?

结构体内存对齐目的:

1.平台原因:

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

(2)某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。

2.性能原因:

(1)为了访问未对齐的内存,处理器需要做做两次内存访问,而对齐的内存只需要一次访问。

内存对齐的本质是:牺牲空间换取时间;

了解了内存对齐的原因,接下来需要学习内存对齐的规则;

1.第一个成员在与结构体变量偏移量为0的地址处;

例:

struct S
{
	char a;
	int b;
};

内存示意图:


a为结构体第一个变量,存放在偏移量为0的地址处;

2.其他成员要对齐到对齐数的整数倍地址处;

对齐数=编译器默认对齐数与该成员大小的较小值;

Linux环境下对齐数为4,windows环境下对齐数为8;

例:

在Windows环境下:

struct S
{
	char a;
	int b;
	double c;
};

变量a(1字节)先存入偏移量为0(存放在第1字节处)的地址处,存放变量b时,变量b的大小为4字节,对齐数为4,则存放在第5~8字节处,同理变量c的大小为8字节,对齐数为8,则存放在第9~16字节处;

示意图:


3.结构体总大小为最大对齐数(每个成员变量除了第一个成员都有一个对齐数)的整数倍;

例:

struct S
{
	char a;
	double c;
	int b;
};

在windows环境下:

由规则1,2计算出结构体总大小为8+8+4=20,而结构体的最大对齐数为8,20不是8的整数倍,所以将它补到8的整数倍,也就是24,最终得出结构体总大小为24;

示意图:


4.如果结构体1嵌套了结构体2,结构体2对齐到自己的对齐数的整数倍处,结构体1的大小就是其成员最大对齐数的整数倍;

规则4其实就将被嵌套的结构体看做普通变量,按规则1,2,3对齐即可;

位段,位段计算机大小

c语言允许在一个结构体中以位段为单位来指定其成员所占内存大小,这种以位为单位的成员称为位段,利用位段能够利用较少的位数存储数据;

位段的定义方式:

例:

int a:2;
int :0;

int b:1;//另一个存储单元

位段的规则:

在某些机器上, 位段总是作为 unsigned 处理, 而不管它们是否被说明成 unsigned 的;

大多数C 编译器都不支持超过一个字长的位段;

位段不可标明维数, 不能说明位段数组, 例如 flag:l[2];

位段不可以取地址;

枚举,联合

枚举

枚举是一个被命名的整型常数的集合,内部成员第一个默认值是0,后边依次+1;

例如
enum A{
a,//默认值是0
b,//1
c,//2
d,//3

}

联合体

在联合体中,各成员共享一段内存空间, 一个联合变量的长度等于各成员中最长的长度。共享指该联合变量可被赋予任一成员值,但每次只能赋一种值, 赋入新值则改变旧值;

union str
{
	int a;
	char b;
	double c;
};
联合体str中成员a,b,c共用一块内存;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值