学嵌入式和C语言编程|学习日记Day17:吃透内存管理与位运算
前言自学嵌入式 C 来到第 17天终于接触到贴近硬件底层的核心内容堆区动态内存管理、基础位运算。这两块是写单片机、嵌入式工程绕不开的知识点内存管理决定程序稳不稳定位运算决定代码效率高不高今天就把笔记里的干货完整整理出来。一、C 语言堆区动态内存管理1. 核心 4 个基础函数1malloc 内存申请cvoid *malloc(size_t size);功能向堆内存申请指定字节大小的连续空间参数size 需要申请的内存字节数返回值申请成功返回内存首地址申请失败返回NULL2free 内存释放cvoid free(void *ptr);功能释放之前 malloc/calloc 在堆上申请的内存参数ptr必须是堆内存空间的首地址3calloc 数组式内存申请cvoid *calloc(size_t nmemb,size_t size);功能专门申请数组形式的堆空间会自动把申请的内存全部初始化为 0参数nmemb数组元素总个数size单个元素占用字节大小返回值成功返回首地址失败返回NULL2. 最容易踩坑内存泄露程序运行时堆里申请的内存使用完毕后没有调用 free 释放这块内存会一直被占用系统无法回收就形成内存泄露。✅ 最简单规避方案malloc/calloc 开辟的内存使用结束必须配对 free 释放。3. 什么时候必须用堆空间函数内部开辟的内存想要函数执行结束后数据依然保留只能开辟在堆上需要使用的内存体量很大栈默认空间仅 8M 不够存放优先堆区分配。4. 栈区 VS 堆区核心区别对比表格对比维度栈区堆区管理方式操作系统自动申请、自动回收程序员手动 malloc 申请、free 释放存储内容局部变量、函数形参、返回值、函数调用现场自定义的大块动态数据、跨函数留存数据默认空间大小默认 8M远大于栈空间访问效率读写速度更快读写效率略低于栈内存风险不会内存泄露忘记 free 就会内存泄露二、内存空间分布三、C 语言位运算嵌入式底层的高效写法位运算直接操作二进制比特位运算速度是算术运算里最快的寄存器配置、IO 口控制全靠它。1. 6 种基础位运算符规则运算符运算规则口诀通俗解释按位与全 1 为 1有 0 则 0两个二进制位都为 1结果才是 1|按位或有 1 则 1全 0 才 0任意一位是 1结果就是 1^按位异或相同为 0不同为 1两位数值不一样结果为 1~按位取反0 变 11 变 0所有二进制位全部反转左移高位直接舍弃低位补 0等价num*2ⁿ数字左移 n 位 乘以 2 的 n 次方右移有符号数高位补符号位无符号数高位补 0等价num/2ⁿ数字右移 n 位 整除 2 的 n 次方2. 位运算经典实用场景场景 1指定某一位置 1公式num num | (1 n);示例把第 3 位设置为 1Plain Text1010 0001 | (13) 1010 0001 | 0000 1000 1010 1001场景 2指定某一位清 0公式num num ~(1 n);示例把第 3 位清零Plain Text1010 1010 ~(13) 1010 1010 1111 0111 1010 0010场景 3不借助第三方变量交换两个数字异或特性ca a ^ b;b a ^ b;a a ^ b;推导原理a^a0、a^0a第一步a a^b第二步b (a^b)^b a^(b^b)a^0a第三步a (a^b)^a b^(a^a)b^0b补充两种交换写法临时变量法tmpa;ab;btmp;求和法aab;ba-b;aa-b;3. 位运算符优先级排序优先级从高到低~、^|三、今日自学总结动态内存只存在堆区malloc 和 free 必须成对使用内存泄露是嵌入式长期运行程序的致命 bug栈自动管理无需手动释放但空间小、生命周期仅限当前函数位运算直接操作二进制效率拉满嵌入式配置寄存器、引脚电平、硬件校验都会高频使用置 1、清 0、变量交换是最常用的三个技巧写代码一定要留意运算符优先级复杂位运算建议主动加括号避免优先级出错导致逻辑异常。