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

嵌入式学习15

标题:C语言底层核心|位运算详解 + 程序五大内存分区全梳理)

前言

最近系统学习C语言底层知识点,今天啃完两大重难点:位运算程序内存分区管理。位运算是嵌入式、驱动开发必备技能,直接操作二进制比特位;内存分区是理解程序运行、排查内存泄漏、段错误的根本。本文整理完整知识点、实操模板、踩坑易错点,适合零基础巩固、面试复习。

一、位运算:直接操作二进制比特位

1. 六种基础位运算符

位运算仅支持整型数据(char/short/int/long),浮点数float、double无法参与运算。

运算符运算规则典型场景
& 按位与对应bit全1才为1,否则0指定位清零、提取特定位
| 按位或对应bit有1则1,全0才0将指定bit置1
^ 按位异或对应bit相同为0,不同为1翻转bit、交换两数无临时变量
~ 按位取反所有bit 0↔1配合与运算清零特定位
<< 左移整体左移N位,低位补0快速乘以2的N次方
>> 右移整体右移N位,有符号补符号位快速除以2的N次方

2. 工业级常用位操作模板

(1)将数字第n位设置为1
// n为目标bit下标,从0开始计数num|=(1<<n);
(2)将数字第n位清零
num&=~(1<<n);
(3)异或交换两个整数(无需临时变量)
voidswap(int*a,int*b){*a=*a^*b;*b=*a^*b;*a=*a^*b;}

3. 高频注意事项&易错坑

  1. 区分逻辑运算符与位运算符
    && ||是逻辑运算,结果只有0/1;& | ^是位运算,操作二进制每一位,完全不能混用。
  2. 移位运算优先级低于加减
    1 + 3 << 1等价(1+3) << 1 = 8,不是1 + (3<<1)=7,复杂运算建议加括号。
  3. 有符号数右移补符号位
    负数右移永远为负数,无符号数字右移统一补0;移位溢出会丢失数据,避免超大移位。
  4. ~取反容易踩坑
    ~1结果不是0,而是所有bit翻转的负数(计算机用补码存储负数),不能直接用~num判断正负。

二、 C程序内存分区管理(Linux环境)

1. 五大内存分区完整图解

程序运行时内存从低地址到高地址分为:文本段、数据区、栈区、堆区、CPU寄存器。

  1. .text 文本段(只读)
    存放所有函数代码、程序指令,权限只读,修改会直接段错误,生命周期全程伴随程序。
  2. 数据区(编译阶段分配,程序结束释放)
    • .data:已初始化全局变量、static静态变量;
    • .bss:未初始化全局/static变量,程序加载时自动填充0;
    • .rodata:字符串常量、const只读常量,禁止写操作。
  3. 栈区 stack(操作系统自动管理)
    存放局部变量、函数形参、函数返回地址;进入函数分配,函数执行完毕自动回收。
    坑:局部变量不初始化,值为随机脏数据;栈空间很小,禁止超大数组。
  4. 堆区 heap(程序员手动管理)
    唯一自主控制生命周期的内存,通过malloc/calloc/realloc申请,free手动释放。
    • 忘记释放 → 内存泄漏,程序长时间运行内存占用持续上涨;
    • 重复free、free栈变量/全局变量 → 程序崩溃。
  5. 寄存器 register
    CPU高速存储单元,register修饰的变量优先存入寄存器,读写速度远超内存。

2. 堆区动态内存核心API

#include<stdlib.h>// 申请size字节堆内存,返回void*,未初始化void*malloc(size_tsize);// 申请count个size空间,自动初始化为0void*calloc(size_tcount,size_tsize);// 扩容/缩容已有堆内存void*realloc(void*ptr,size_tnew_size);// 释放堆内存voidfree(void*ptr);

规范写法:free后手动置空,杜绝野指针

int*p=malloc(40);free(p);p=NULL;// 释放后置空,避免野指针

3. 共用体union与大小端存储

  1. union特点:所有成员共享同一块内存,空间大小等于最大成员占用字节;
  2. 大小端模式:
    • 小端(PC、ARM主流):低内存地址存放数据低位;
    • 大端(网络协议):低内存地址存放数据高位;
      可通过union快速判断当前设备存储模式。

4. 内存模块易错点汇总

  1. 函数绝对不能返回局部变量地址:局部变量存栈,函数结束栈销毁,指针变为野指针;
  2. "hello"字符串常量存.rodata只读段,不能修改字符:char *s = "abc"; s[0]='x';直接崩溃;
  3. static修饰局部变量,存储在数据区,仅第一次调用函数初始化;普通局部变量每次进函数重建;
  4. 栈空间有限,大容量数组、缓冲区统一放堆;
  5. 堆内存只能free一次,重复free、释放非malloc指针直接触发段错误;
  6. 数组越界读写会破坏相邻内存,产生无规律随机bug,极难调试。

三、今日学习总结

  1. 位运算偏向底层硬件开发,熟记置1、清零、异或交换三大模板,区分位运算与逻辑运算;
  2. 内存分区是C语言排错核心,分清栈/堆/数据区存放数据类型,牢记堆内存malloc/free配对使用;
  3. 高频踩坑:野指针、内存泄漏、栈溢出、修改只读字符串、返回局部变量地址;
  4. 拓展方向:后续结合指针、结构体、动态数组,实战堆内存管理,实现动态链表。
http://www.jsqmd.com/news/1337348/

相关文章:

  • 【实时Linux核心技术:从概念到实战】01:实时Linux到底是什么?从实时性定义到核心指标
  • BilibiliDown:如何轻松下载B站视频并建立个人媒体库?
  • C语言基础:指针(三)
  • 从零构建企业级数据治理体系:DataArts Studio核心模块与实战路径解析
  • 模拟CMOS单级放大器设计:从共源到共源共栅的电路直觉与工程权衡
  • 2026年8月台州太阳能排风扇/浙江屋顶排风扇厂家厂家推荐_浙江海天机械有限公司 - 品牌宣传支持者
  • 钉钉审批流实战:从设计到上线的全流程指南与避坑经验
  • 采购四川比较好的菱形勾花网热门厂家怎么选才不踩坑 - 品牌优推
  • MacBook新手指南:从系统设置到开发环境配置的完整上手教程
  • 从开环到闭环:基于PID算法与灰度传感器的智能小车巡线控制实践
  • Linux审计框架auditd实战:从内核事件捕获到高级规则定制
  • LangChain集成百度千帆SDK:从零构建可落地的LLM应用实战指南
  • 论文降AI率免费额度只有1000字,先拿哪一段去试才不浪费?
  • 长春空气能选购门店哪家专业:【芬尼】寒地定制 - 18002239949
  • AI驱动智能合约安全审计:从Claude实战到未来攻防范式变革
  • 2026年8月四川防腐储罐/成都衬塑储罐厂家怎么选_成都臻沃通科技有限公司 - 行业平台推荐
  • 【C 语言入门第 15 天】共用体、枚举、位运算核心知识点梳理
  • Mac上SVN配置与开发实战:从工具链选型到高效工作流
  • 重庆菜市场商户采购指南,津白适合需要稳定大批量供货
  • 利用Cadence Allegro SKILL脚本实现PCB设计自动化:零件导出与引脚统计
  • 寻找河北纸箱印刷机供应商怎么选看这几点就够了 - 品牌优推
  • 2026年AI模型选型实战:从API到自托管对比
  • Inkling-Small:MoE架构如何以12B激活参数实现高效多模态推理
  • 汽车电子SBC休眠唤醒实战:TLE9262精准功耗管理与调试指南
  • 龙井镇附近的衣帽间定制热门厂家怎么选更靠谱? - 品牌优推
  • 抖音批量下载终极指南:如何高效获取无水印视频与完整元数据
  • 物理不可克隆函数(PUF)原理与应用:从硬件指纹到安全密钥的实战解析
  • i.MX6ULL HAB安全启动实战:从PKI构建到镜像签名与熔丝烧录
  • HTML5语义化标签与文档结构详解:从基础到实战的网页骨架构建指南
  • SPICE磁滞建模实战:从Jiles-Atherton模型到工程调试技巧