C语言进阶之旅 (13)自定义类型

Posted 一个正直的男孩

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言进阶之旅 (13)自定义类型相关的知识,希望对你有一定的参考价值。

思维导图

在这里插入图片描述

结构体

  • 概念,初始化,访问请看初识结构体
  • 结构体可以不写标签,就是匿名结构体,他只能用一次

自引用

  • 类似函数递归自己调用自己
struct Node {
int data;
    struct Node* next;
};

前面存数据,后面存下个位置的指针,没有指向就吧指针域改为空指针
在这里插入图片描述

内存对齐

  • 结构体是怎么存到内存中的呢?
#include <stdio.h>
struct S1 {
	char c1;
	int i;
	char c2;
};
int main()
{
 struct S1 s;
	printf("%d\\n", sizeof( s));

}

在这里插入图片描述



为啥是12?不应改是6吗,一个int,俩char,这里就有一个对齐的概念

  • 对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。
  • 默认对齐数vs 8,别的不知道。。。
  • 结构体大小,是结构体中最大元素的倍数

  • 为啥有内存对齐
  • 方便读取
  • 效率高
  • 修改默认对齐数,大致就是节省空间避免不必要的空间损失
    在这里插入图片描述

优化,其实上面那种是造成浪费的,所以只需要更改一下代码就会节省好多内存
在这里插入图片描述

  • 只需要把小的元素写在上面,下面写大的元素即可
#include <stdio.h>
struct S1 {
	char c1;
	char c2;
	int i;
	
};
int main()
{
 struct S1 s;
	printf("%d\\n", sizeof( s));

}

在这里插入图片描述
在这里插入图片描述
修改默认对齐数

  • 这里他就会特默认对齐数对齐,应为对齐是根据最小的那个判断
  • 假设默认对齐数是2,char对齐还是1,int哪些就需要改变,对齐就是2

在这里插入图片描述

位段

  • 用于节省空间
  • 一个int类型4个字节32个bit,位拿来存1他二进制就占一个bit
  • 岂不是大材小用了
  • 给的申请空间是bit
struct A
{
    int -a:2;
    int -a:5;
    int -a:10;
    int -a:30;
}
printf("%d",sizeof(struct a));

结果👏
在这里插入图片描述

  • 蓝色为a
  • 绿色为b
  • 黄色为c
  • 紫色为d
    在这里插入图片描述

枚举

  • 就是一一列举出来
  • 且他是一个带名字的数字
    在这里插入图片描述

  • 用于:switch等
void menu ()
{
printf("######################");
printf("exit ,add ,sub eid div");
printf("######################");
}
enum calc 
{
	exit,
	add,
	sub,
    rid,
	div,
};
int mian()
{
	int n = 0;
	scanf("%d", &n);
	switch (n)
	{
	case exit:
		printf("退出\\n");
		break;
	case add:
		printf("+");
		break;
	case sub:
		printf("-");
		break;
	case rid:
		printf("*");
		break;
	case div:
			printf("/");
			break;
	default:
		break;
	}
}

这里枚举中的值都是常数,第一个元素是0,后面一一递增,也可以给他初始化,如果你初始化了一个元素,后面就会在你这个基础上+1

在这里插入图片描述

联合体,共用体

  • 共用一块空间
  • 联合体的大小是这个集合中最大元素的字节个数
  • 使用联合体时不能同时使用
  • 访问类似指针类型来访问数组
union he
{ 
char en;
int an;
};

内存情况
在这里插入图片描述

优化笔试题

  • 判断编译器的大小端

老方法

int main(int argc, char* argv[])
{
	union s b;
	int i = 1;
	int* p = &i;
	if ((*(char*)p)==1)
	{
		printf("小端");
	}
	else {
		printf("大");
	}
}

新:

union u
{
char d;
int c;
}
int main()
{
	u.c = 1;
	if (u.d==1)
	{
		printf("小端存储");
	}
	else
	{
		printf("大端存储");
	}

	return 0;

解析🤯
在这里插入图片描述

祝大家端午节快乐

在这里插入图片描述

如果有错误请直接提出,评论区,私信,qq(1696912943),误人子弟可不好🤯

博主用的画图软件下载链接
持续更新中………………

以上是关于C语言进阶之旅 (13)自定义类型的主要内容,如果未能解决你的问题,请参考以下文章

C语言进阶之旅(留下的足迹)

我的C语言学习进阶之旅解决 Visual Studio 2019 报错:错误 C4996 ‘fscanf‘: This function or variable may be unsafe.(代码片段

我的C语言学习进阶之旅解决 Visual Studio 2019 报错:错误 C4996 ‘fscanf‘: This function or variable may be unsafe.(代码片段

C语言进阶之旅新老朋友结构体

C语言进阶之旅新老朋友结构体

我的C/C++语言学习进阶之旅C/C++编程笔记:C语言使用宏定义#define来处理通用的可抽取的代码块