C语言进阶学习日志:自定义类型 (细中细)(下)

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: C语言进阶学习日志:自定义类型 (细中细)(下)

位段:

位段的声明和结构是类似的 但还是有不同的

位段的成员必须是int,unsigned int,signed int 但这只是规定 char也没什么事

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


位段的内存分配:

  1. 位段的空间是按照需要以4个字节或者1个字节的方式来开辟的
  2. 位段涉及很多不确定的因素,位段是不跨平台的,注重可执行程序应该避免使用位段

046f9a51489d472a9f00f9be3ea3c38f.png位段很大的作用就是可以帮助我们优化 节省空间  有些变量只要那么多的bit位 我们就给他那么多 这样就可以很好的节省空间

#include <stdio.h>
struct stu
{
  char a:3;
  char b:4;
  char c:5;
  char d:4;
}s;
int main()
{
  s.a=10;
}

这种给有位段的结构体成员变量赋值时  也要注意位段的限制  

好像这里给a赋值10 他的二进制码 1010 但是在赋值时 我们分配给a的是三个bit位 那么存放时就只能放三个bit位的值  也就是是说只能放  010  进去

对于连续存放时 从地位往高位 放入


位段的跨平台问题:

① int 位段被当成有符号数还是无符号数是不确定的

②位段中的最大数目不能确定(早期有些机器是是16位机器 最大数目是16 32位机器的最大数目是32)所以如果一个机器是16位的位段设置为 大于它的 就会出问题

③ 位段中的成员在内存中是从左向右分配 还是从右向左分配 这个也是没有定义的

④ 当一个结构体包括两个位段,如果第二个位段成员比较大,无法容纳于第一个位段剩余的位时,是舍弃还是利用,这是不确定 (这就跟我们说的一样)

总的来讲 位段是不支持跨平台的


枚举类型:

枚举顾名思义 就是 列举  把一些数据列举出来

enum u
{
  //枚举的可能取值
  EXIT,0 这只是初始的
  MON, 1
  THE, 2
  WED  3
};
enum s
{
 DAY=7,
 ONE=6,  这时候FOR为7
 FOR
};
int main()
{
  enum u d = EXIT;
  enum u d = 0;//这样赋值是不建议的 在c语言里面它可能没有报错 但在c++里面检查更严格后就会报错了
               //因为c++会认为 d是枚举类型 0是int类型 不会让他们这样赋值
}

注意 枚举成员都是常量

枚举看起来虽然功能单一 但它也是有优点的

  1. 增加代码的可读性和可维护性
  2. 和#define定义的标识符比较枚举有类型 也就是说枚举有类型检查,更加严谨
  3. 防止了命名污染(封装)
  4. 便于调试
  5. 使用方便,一次可定义多个常量


联合体:

union u
{
  char c;
  double i;
};
int main()
{
  printf("%d\n",sizeof(u));  8  最大成员的大小
  printf("%p\n",&u);
  printf("%p\n",&(u.c));
  printf("%p\n",&(u.i));
  //后面的地址是一样的
}

可以发现 c 和 i 的其实地址是一样的 使用的第一个字节重复了 所以联合体还有个名字叫共用体  当然共用体也有个缺点 就是同一时间只能使用一个变量 每次使用一个变量 另一个变量也会跟着改变所以 每次只能使用一个变量

所以联合体就有了一个应用场景 就是当你每次使用时 都会用到不同的东西 但每次只使用一个的时候 就可以用了

知道了这种特性后 我们就可以用这个特性来判断我们的机器是大端还是小端

    int Checksys()
   {
     union u
     {
        char i;
        int c;
     }s;
     s.c=1;
     return s.i;
   }

b3a48e574ee34cc1a30e0ff27fa0e88f.gif

联合体大小的计算:

联合的大小至少是最大成员的大小。

当最大成员的大小不是最大对齐数的整数倍时,就要对齐最大对齐数的整数倍

大家来计算一下这个联合体的大小是多少
union un
{
  short  c[7];
  int  i;
};
union un
{
  short  c[7]; 2-8-2 
  int  i;      4-8-4
};
  最终最大对齐数是4 也就是要4的倍数 其中最大成员大小是14 那么最终的联合体大小是16

那么到这里 我们自定义类型的讲解就没有了 感谢大家能看到这里 希望大家都能收到自己心仪的offer!!!!

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
21天前
|
安全 编译器 Linux
【c语言】轻松拿捏自定义类型
本文介绍了C语言中的三种自定义类型:结构体、联合体和枚举类型。结构体可以包含多个不同类型的成员,支持自引用和内存对齐。联合体的所有成员共享同一块内存,适用于判断机器的大小端。枚举类型用于列举固定值,增加代码的可读性和安全性。文中详细讲解了每种类型的声明、特点和使用方法,并提供了示例代码。
19 3
|
1月前
|
Arthas 监控 Java
JVM知识体系学习七:了解JVM常用命令行参数、GC日志详解、调优三大方面(JVM规划和预调优、优化JVM环境、JVM运行出现的各种问题)、Arthas
这篇文章全面介绍了JVM的命令行参数、GC日志分析以及性能调优的各个方面,包括监控工具使用和实际案例分析。
43 3
|
1月前
|
存储 Prometheus NoSQL
大数据-44 Redis 慢查询日志 监视器 慢查询测试学习
大数据-44 Redis 慢查询日志 监视器 慢查询测试学习
24 3
|
1月前
|
存储 编译器 Linux
C语言——自定义类型
C语言——自定义类型
|
1月前
|
数据采集 监控 Java
SpringBoot日志全方位超详细手把手教程,零基础可学习 日志如何配置及SLF4J的使用......
本文是关于SpringBoot日志的详细教程,涵盖日志的定义、用途、SLF4J框架的使用、日志级别、持久化、文件分割及格式配置等内容。
128 0
SpringBoot日志全方位超详细手把手教程,零基础可学习 日志如何配置及SLF4J的使用......
|
2月前
|
Kubernetes API Docker
跟着iLogtail学习容器运行时与K8s下日志采集方案
iLogtail 作为开源可观测数据采集器,对 Kubernetes 环境下日志采集有着非常好的支持,本文跟随 iLogtail 的脚步,了解容器运行时与 K8s 下日志数据采集原理。
|
1月前
|
Python
log日志学习
【10月更文挑战第9天】 python处理log打印模块log的使用和介绍
30 0
|
1月前
|
C语言
教你快速理解学习C语言的循环与分支
教你快速理解学习C语言的循环与分支
15 0
|
1月前
|
存储 编译器 C语言
【C语言】自定义类型:联合与枚举的简明概述
【C语言】自定义类型:联合与枚举的简明概述
|
3月前
|
JSON 中间件 Go
go语言后端开发学习(四) —— 在go项目中使用Zap日志库
本文详细介绍了如何在Go项目中集成并配置Zap日志库。首先通过`go get -u go.uber.org/zap`命令安装Zap,接着展示了`Logger`与`Sugared Logger`两种日志记录器的基本用法。随后深入探讨了Zap的高级配置,包括如何将日志输出至文件、调整时间格式、记录调用者信息以及日志分割等。最后,文章演示了如何在gin框架中集成Zap,通过自定义中间件实现了日志记录和异常恢复功能。通过这些步骤,读者可以掌握Zap在实际项目中的应用与定制方法
130 1
go语言后端开发学习(四) —— 在go项目中使用Zap日志库