当前位置: 首页 > article >正文

学习C语言(21)

整理今天的学习内容

1.结构体实现位段

(1)位段的声明

位段的成员必须是 int、unsigned int 或signed int ,在C99中位段成员的类型也可以选择其他类型

例:

(2)位段的内存分配

位段的空间上是按照需要以4个字节( int )或者1个字节( char )的方式开辟的

解释下面程序的运行结果

首先开辟四个字节,32个比特位,_a,_b,_c,依次放入被开辟空间中

当_d申请30个比特位的空间时,原先开辟的空间不够,再次开辟4个字节的空间存放_d,其余空间被浪费掉

                                                                                                       注:一个空格代表1个比特位

所以struct A 变量的大小是8个字节

测试:

                        注:一个空格代表1个比特位   

(3)位段的跨平台问题

·int 位段被当成有符号数还是无符号数是不确定的
·位段中最大位的数目不能确定。(16位机器最大16,32位机器最大32,写成27,在16位机器会出问题
·位段中的成员在内存中从左向右分配,还是从右向左分配,标准尚未定义
·当⼀个结构包含两个位段,第二个位段成员比较大,无法容纳于第⼀个位段剩余的位时,是舍弃剩余的位还是利用,这是不确定的
·跟结构相比,位段可以达到同样的效果,并且可以很好的节省空间,但是有跨平台的问题存在

(4)位段的使用

位段的几个成员共用同⼀个字节,所以不能对位段的成员使用&操作符,这样就不能使用scanf直接给位段的成员输入值,只能是先输入放在一个变量中,然后赋值给位段的成员

例:

自定义类型:联合和枚举

1.联合体

(1)联合体类型的声明

(2)联合体在内存中的储存

编译器只为联合体最大的成员分配足够的内存空间,联合体的特点是所有成员共用同⼀块内存空间。所以联合体也叫:共用体
给联合体其中一个成员赋值,其他成员的值也跟着变化

      

(3)联合体大小的计算

1.联合的大小至少是最大成员的大小
2. 当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍

(4)结构体和联合体的对比

例:图书、杯子、衬衫这三种商品每⼀种都有:库存量、价格、商品类型的信息,除此之外,图书还包括书名、作者、页数,杯子还包括设计,衬衫还包括设计、可选颜色、可选尺寸

以结构体的的形式设计变量:

以联合体的的形式设计变量:

与结构体相比,联合体的使用可以节省内存

(5)用联合体判断当前机器的大小端

2.枚举

(1)枚举的声明

{}中的内容是枚举类型的可能取值,也叫枚举常量 。
这些可能取值都是有值的,默认从0开始,依次递增1,当然在声明枚举类型的时候也可以赋初值

(2)枚举类型的优点

·增加代码的可读性和可维护性
· 和#define定义的标识符比较枚举有类型检查,更加严谨
·便于调试,预处理阶段会删除 #define 定义的符号
· 使用方便,一次可以定义多个常量
·枚举常量是遵循作用域规则的,枚举声明在函数内,只能在函数内使用

(3)枚举类型的使用

使用枚举常量给枚举变量赋值

C语言中可以拿整数直接给枚举变量赋值,但在C++中不行,因为C++的类型检查比较严格

动态内存管理

C语言中的动态内存开辟使程序员可以自己申请和释放空间

1.malloc和free

(1)malloc

void*  malloc  (size_t  size);

                                      ↑

                      需要开辟空间的字节数
这个函数向内存申请⼀块连续可用的空间,并返回指向这块空间的指针
• 如果开辟成功,则返回⼀个指向开辟好空间的指针
• 如果开辟失败,则返回⼀个 NULL 指针,因此malloc的返回值⼀定要做检查
• 返回值的类型是 void* ,所以malloc函数并不知道开辟空间的类型,具体在使用的时候由使用者自己决定
• 如果参数 size 为0,malloc的行为是标准是未定义的,取决于编译器

(2)free

void free (void* ptr);

                          ↑

                    需要释放的动态内存的地址

free函数用来释放动态开辟的内存

• 如果参数 ptr 指向的空间不是动态开辟的,那free函数的行为是未定义的

• 如果参数 ptr 是NULL指针,则函数不进行任何处理

malloc和free都声明在 stdlib.h 头文件中

使用free函数处理过的指针是野指针,需要置NULL

2.calloc和realloc

(1)calloc

void* calloc (size_t num, size_t size);

• 函数的功能是为 num 个大小为 size 的元素开辟⼀块空间,并且把空间的每个字节初始化为0

• 与函数 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全 0

calloc函数的使用:

  

(2)realloc

void* realloc (void* ptr, size_t size);

realloc 函数可以对动态开辟内存大小进行调整

• ptr 是要调整的内存地址

• size为调整之后新大小

• 返回值为调整之后的内存起始位置

 • 这个函数调整原内存空间大小的基础上,还可能会将原来内存中的数据移动到新的空间

realloc在调整内存空间时存在两种情况:

情况1:原有空间之后有足够大的空间

直接原有内存之后直接追加空间,原来空间的数据不发生变化

情况2:原有空间之后没有足够大的空间

在堆空间上另找⼀个合适大小 的连续空间来使用,这样函数返回的是⼀个新的内存地址

realloc函数的使用:

realloc(NULL,20)==malloc(20) 


http://www.kler.cn/news/324155.html

相关文章:

  • videojs 播放mp4视频只有声音没有画面问题
  • k8s搭建一主三从的mysql8集群---无坑
  • 【深度学习】注意力机制与自注意力机制详解
  • Docker学习路线
  • 将 Java 对象自动转换为 XML 字符串
  • 电子数据交换EDI 835 的处理
  • Spring Boot 进阶- Spring Boot 自定义拦截器详解
  • 中药材识别
  • 前置机、跳板机、堡垒机:安全运维领域的“黄金三角”
  • stm32 FLASH闪存(读写内部FLASH读取芯片ID)
  • Mac下利用vscode配置latex
  • 记一次因视频编码无法在浏览器播放、编码视频报错问题
  • 软件测试学习路线图
  • 【有啥问啥】深度解析迁移学习(Transfer Learning)
  • C#算法(16)—获取上升沿和下降沿信号
  • windows10使用bat脚本安装前后端环境之redis注册服务
  • 微服务--初识MQ
  • 【InsCode AI】Tableau可视化—AI生成
  • 鸿蒙HarmonyOS NEXT系统揭秘:跨端迁移与多端协同
  • 基于Spring框架的分层解耦详解
  • node后端react前端简单实例
  • react hooks--useImperativeHandle
  • 洛谷 P10456 The Pilots Brothers‘ refrigerator
  • 基于php的民宿预订管理系统
  • pkg升级导致xfce虚拟终端无法启动甚至xfce挂死无法登入@FreeBSD(未解决)
  • vue3更具文件目录动态添加路由配置
  • django drf 统一Response格式
  • ES6的简单介绍(第二部分)
  • Unity与AI对话系统互动生成表情示例
  • linux的中断管理机制