对结构体的认识

一.结构体类型

结构体类型是一种自定义类型
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(输入值),只能先输入一个值放入一个变量中,然后这个变量再赋值给位段的成员。

相关推荐

  1. golang 根据某个特定字段结构顺序进行排序

    2024-03-24 12:02:01       37 阅读
  2. Swift中结构

    2024-03-24 12:02:01       34 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-24 12:02:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-24 12:02:01       101 阅读
  3. 在Django里面运行非项目文件

    2024-03-24 12:02:01       82 阅读
  4. Python语言-面向对象

    2024-03-24 12:02:01       91 阅读

热门阅读

  1. Redis 教程系列之Redis 配置(三)

    2024-03-24 12:02:01       42 阅读
  2. ubuntu安装可调试的ffmpeg

    2024-03-24 12:02:01       38 阅读
  3. vue3项目的创建

    2024-03-24 12:02:01       38 阅读
  4. Dr4g0n

    Dr4g0n

    2024-03-24 12:02:01      43 阅读
  5. Codeup_5973:问题 B: 【递归入门】组合的输出

    2024-03-24 12:02:01       48 阅读
  6. Spark 安装(集群模式)

    2024-03-24 12:02:01       43 阅读
  7. 独立服务器和云计算各有什么优势?

    2024-03-24 12:02:01       37 阅读