对结构体的认识

一.结构体类型

结构体类型是一种自定义类型
C语言中自定义类型有:结构体,枚举,联合体
结构体中有成员变量,每个成员变量都有不同的类型
结构是许多变量的集合
一个学生有许多元素构成所以用结构体
struct是关键字,student是类型名,也是结构体标签

struct student
{
	char name[20];
	int age;
};

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

struct student
{
	char name[20];
	int age;
	char id[20];//学号
}m;//变量s

int main()
{
	//结构体变量的创建和初始化
	//按照顺序初始化
	struct student s = { "zhangsan",20,"20231212" };

	//不按顺序初始化
	struct student a = { .age = 20,.id = "20329393",.name = "wanger" };
    
	return 0;
}

1. typedef可以是类型名简化

//typedef 将struct student 这个类型重命名为p 
//就可以用p 去创建变量
typedef struct student
{
	char name[20];
	int age;
	char id[20];//学号
}p;//变量s

typedef struct student s;
//将struct student 这个类型重命名为s
//就可以用s 去创建变量
int main()
{
	//结构体变量的创建和初始化
	//按照顺序初始化
	 p i = { "zhangsan",20,"20231212" };
	 //
	 s e = { "lisi",19,"293942"};
	//不按顺序初始化
	p i = { .age = 20,.id = "20329393",.name = "wanger" };
    
	return 0;
}


2.匿名的结构体类型

匿名的结构体类型,如果没对结构体类型重命名的话,基本上只能使用一次

//省略了结构体标签
//匿名的结构体类型
struct
{
	int year;
	char arr[20];
}x;//变量
3.结构体的自引用

自引用:在结构体中包含自己本身的结构体类型的变量

struct ss
{
  int i;
  struct ss p;
}

这样写是错的,结构体的大小里面再包含一个结构体+一个整型的大小

正确的写法:

struct ss
{
  int i;//4大小
  struct ss * p;// 4/8
}

三.结构体的内存对齐

1.对齐规则

  • 结构体的第一个成员对齐到偏移量为0的地址处
  • 其他成员对齐到对齐数整数倍的地址
  • 对齐数 = 编译器默认的值(字节大小)和成员变量(字节大小)的较小值
  • 结构体的总大小是最大对齐数(就是该结构体中成员变量之间的最大值)
  • 如果嵌套了结构体,结构体的总大小是成员变量中最大值的整数倍(含嵌套的结构体)
  • 偏移量/字节大小 = 整数倍
  • VS中对齐数为8

1.1 例一:

struct S1
{
char c1;//1  8  1
int i;// 4   8  4
char c2;// 1 8  1
};
printf("%d\n", sizeof(struct S1));

大小为:12
在这里插入图片描述

1.2例二:结构体嵌套
struct s1
{
	double d;//8 8 8
	char c;//  8 1 1
	int i;//   8 4 4
};
struct s
{
	char c1;//8 1 1
	struct s1 a;
	double d;//8 8 8
};

大小为:32
在这里插入图片描述

四.结构体传参

要传结构体的地址,地址压栈比较小 而传结构体过去,结构体压栈的开销比较大,会导致性能的下降

五.结构体实现位段

5.1位段的声明

1.位段的成员名的类型必须是int,unsigned int,signed int 在C99位段的成员也可以选择其他类型
2.位段的成员后有冒号和一个数字(这个数字表示bit位大小)

//_结构体成员名也可以使用
struct S
{
int _a : 2;// 2 bit
int _b : 5; // 5 bit
};
位:指的是二进制位
位段是专门用来节省内存的

5.2位段的内存分配

struct A
{
char_a:3;
char _b:4;
char _c:5;
char _d:4;
};
s.a = 10;
s.b = 12;
s.c = 3;
s.d = 4;
int main()
{
 sizeof(struct A);

 return 0;
}

在这里插入图片描述

5.3位段使用要注意的地方

1.内存中每个字节分配地址,一个字节内的bit位是没有地址的。
2.位段的成员是不能是用&操作符的,所以不可以直接给位段成员scanf(输入值),只能先输入一个值放入一个变量中,然后这个变量再赋值给位段的成员。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值