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

简介: 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!!!!

相关实践学习
通过日志服务实现云资源OSS的安全审计
本实验介绍如何通过日志服务实现云资源OSS的安全审计。
目录
相关文章
|
10月前
|
调度
FreeRTOS学习日志 - 第一天
这就是我的FreeRTOS学习日志 - 第一天的内容,明天继续探索这片实时操作系统的广阔海洋。+
200 12
|
数据采集 监控 Java
SpringBoot日志全方位超详细手把手教程,零基础可学习 日志如何配置及SLF4J的使用......
本文是关于SpringBoot日志的详细教程,涵盖日志的定义、用途、SLF4J框架的使用、日志级别、持久化、文件分割及格式配置等内容。
1180 2
SpringBoot日志全方位超详细手把手教程,零基础可学习 日志如何配置及SLF4J的使用......
|
Arthas 监控 Java
JVM知识体系学习七:了解JVM常用命令行参数、GC日志详解、调优三大方面(JVM规划和预调优、优化JVM环境、JVM运行出现的各种问题)、Arthas
这篇文章全面介绍了JVM的命令行参数、GC日志分析以及性能调优的各个方面,包括监控工具使用和实际案例分析。
1583 3
|
存储 Prometheus NoSQL
大数据-44 Redis 慢查询日志 监视器 慢查询测试学习
大数据-44 Redis 慢查询日志 监视器 慢查询测试学习
235 3
|
Python
log日志学习
【10月更文挑战第9天】 python处理log打印模块log的使用和介绍
338 0
|
5月前
|
存储 C语言
`scanf`是C语言中用于按格式读取标准输入的函数
`scanf`是C语言中用于按格式读取标准输入的函数,通过格式字符串解析输入并存入指定变量。需注意输入格式严格匹配,并建议检查返回值以确保读取成功,提升程序健壮性。
1137 0
|
存储 算法 C语言
【C语言程序设计——函数】素数判定(头歌实践教学平台习题)【合集】
本内容介绍了编写一个判断素数的子函数的任务,涵盖循环控制与跳转语句、算术运算符(%)、以及素数的概念。任务要求在主函数中输入整数并输出是否为素数的信息。相关知识包括 `for` 和 `while` 循环、`break` 和 `continue` 语句、取余运算符 `%` 的使用及素数定义、分布规律和应用场景。编程要求根据提示补充代码,测试说明提供了输入输出示例,最后给出通关代码和测试结果。 任务核心:编写判断素数的子函数并在主函数中调用,涉及循环结构和条件判断。
774 23
|
7月前
|
安全 C语言
C语言中的字符、字符串及内存操作函数详细讲解
通过这些函数的正确使用,可以有效管理字符串和内存操作,它们是C语言编程中不可或缺的工具。
372 15
|
12月前
|
人工智能 Java 程序员
一文彻底搞清楚C语言的函数
本文介绍C语言函数:函数是程序模块化的工具,由函数头和函数体组成,涵盖定义、调用、参数传递及声明等内容。值传递确保实参不受影响,函数声明增强代码可读性。君志所向,一往无前!
512 1
一文彻底搞清楚C语言的函数
|
算法 C语言
【C语言程序设计——函数】利用函数求解最大公约数和最小公倍数(头歌实践教学平台习题)【合集】
本文档介绍了如何编写两个子函数,分别求任意两个整数的最大公约数和最小公倍数。内容涵盖循环控制与跳转语句的使用、最大公约数的求法(包括辗转相除法和更相减损术),以及基于最大公约数求最小公倍数的方法。通过示例代码和测试说明,帮助读者理解和实现相关算法。最终提供了完整的通关代码及测试结果,确保编程任务的成功完成。
716 15
【C语言程序设计——函数】利用函数求解最大公约数和最小公倍数(头歌实践教学平台习题)【合集】