
1) 定义整型变量,要三思!
2) 如何选择整数类型?
3) 你自以为uint8_t省内存了? 可能是个大麻烦!
4) 高手说:C语言,一切从编译器出发!
1) int类型到底有几个字节?
2) C语言的跨平台能力
3) 嵌入式高手要了解 GCC
4) 定义整型变量 不建议直接用short int long
5) 定义整型变量,别忘了考虑跨平台特性!
1) 指针变量到底能不能连续定义
2) 看透C语言中的变量定义
3) 指针中*符号的真正含义
4) 嵌入式高手:要自信 并 对代码有掌控力!
1)函数的声明,你真的会吗?
2)高手不容忍 warning!
3)extern的真正意义
4)自解释型代码:谁写代码谁解释!
5)访问外部变量 必须作外部声明
1)extern声明常见错误 你犯过吗?
2)冲突剖析:多个.C访问同一变量或函数
3)哪里使用 哪里声明 这样作对吗?
4).C.H文件成对出现 程序模块
5)高手:善于积累程序模块
1)振南曾经写代码的 “掉坑” 经历
2)关于C语言中变量的重复定义
3)早期基于GCC开发STM32遇到的“雷”
4)笨方法:特有前缀+变量名 不再怕重名
5)关于Static 你真得理解透了吗?
1)类型重定义 最好用typedef
2)高手:宏是一个好东西!
3)几个常见的宏定义 弱爆了
4)高手:宏定义 我们这样用
5)关于头文件重复包含
6)课后题:经典面试题
1)经典面试题两则 宏定义 FPOS与FSIZ
2)STM32 HAL库中 外设寄存器的定义 详解
3)打印调试log 这样作更高效
4)关于C语言代码的选择性预编译
1) 定义结构体变量的N种写法
2) 高手:typedef简化结构体类型定义
3) 掌握秘诀 函数指针定义再复杂也不怕
4) 课后题 挑战一下
1)解决上节课遗留问题
2)const变量?它和常量有何区别?
3)你和高手:差在思维方式
4)要有代码效率优化意识
5)const变量在内存中还是在ROM中?
6)振南曾在商业项目中 做代码优化 的经历
1)const变量?应该叫它const常量吧!
2)指针视角:const变量 毫无隐私
3)const离谁近,就保护谁!
4)const变量声明时无需再加const
5)函数形参中的const,加深理解
1)面对屎山:你焦虑了吗? (给别人擦屁股!)
2)函数指针数组的定义的技巧
3)sizeof()计算数组大小的误区
4)获取其他.C文件中的数组大小?三种方法
5)高手,是创造技巧的人!
1)如何正确的定义main函数?
2)main函数为何必须return一个int值?
3)单片机main函数跑到尽头 它又会怎样?
4)main函数返回值在操作系统中的重要意义
5)main函数形参有重要作用
6)把代码写规范 提高可移植性
7)不是你想学什么 而是老板希望你学什么!
1)main函数中放大数组 运行不起来?
2)“栈” 很重要 但有多少人懂它
3)单片机程序的存储空间分布
4)栈在哪里?栈如何工作?它需要注意什么?
1)“栈”是C语言函数运行根本基础
2)灵魂拷问:CPU为何在运行此函数 而非其它函数
3)函数内部的局部变量到底存在哪里?
4)函数调用层数不要超过4 极限为7
1)函数调用和返回时 CPU到底做了什么?
2)函数返回时 CPU如何准确找到其上级函数?
3)用链表结构来管理函数栈帧?不合适
4)函数层层调用和返回 形如递归
5)先入后出 后入先出 这不就是栈吗?
6)当心程序的“栈溢出”风险!
1)函数形参实际上就是函数局部变量
2)什么是“硬件栈” ?
3)函数出栈入栈的效率问题
4)STM32硬件栈操作如何知道“栈”在哪?
5)没有“硬件栈”就没有“硬件中断响应”!
6)“栈”是现代CPU和软件的重要技术根基!
1)定义时未被赋初值的变量 它到底是什么值?
2)函数内部局部变量未赋初值 它的值又是什么?
3)用 字符串 给指针变量赋初值 应该如何做?
4)字符串作为初始值 它到底存在ROM中还是内存中
5)内存中的流浪数据 毫无意义
1)结构体变量赋初值(基本方法)
2)结构体变量赋初值(数组化方法)
3)C99标准到底是什么?其实还不只它!
4)看看MDK都支持哪些C语言编译器
5)结构体变量赋初值(成员化方法)
6)结构体变量复制的三种方法
7)空结构体占用内存空间吗?它有什么意义?
8)高手:关于“占位”编程思想!
1)通信数据帧的典型形式
2)变长数据帧?Modbus就是典型的变长数据帧
3)使用结构体指针强转进行定长数据帧解析
4)“占位”思想在变长数据帧中的应用
5)不用“占位”如何找到数据的开始
6)使用预留“空结构体”对数据进行直接解析
1)什么是 选择性数据解析?典型应用
2)通过结构化方法进行选择性数据解析
3)通用联合体进行选择性数据解析
4)函数形参中的结构体 批量传参
5)结构体直接传参 毫无意义
6)努力提升自己 作嵌入式软件架构师
1)C++面向对象的思想精髓:封装
2)C语言中的封装思想和实现
3)结构体+函数指针对驱动进行封装
4)多考虑架构性问题
5)抽象封装 规避产品研发风险
1)使用结构体对同类参数进行统一管理
2)单片机重启后 参数依然生效 如何实现?
3)如何确定读到的参数数据是有效的?
4)MagicCode(魔码)的应用
5)用魔码来实现内存溢出检测
6)问题:结构体各成员变量访问速度都一样吗?
1)结构体前128字节访问速度较快 为什么?
2)面向用户 和 面向机器 它们是一对矛盾
3)结构体的 “空洞”问题
4)sizeof(struct) 到底是多少?(计算结构体体积)
5)编译器的策略:用空间换时间
6)例说 计算结构体体积的明确规则
1)有嵌套的结构体体积如何计算?
2)调整成员顺序后结构体体积又是多少?
3)结构体“空洞”问题会引发兼容性问题
4)强制结构体对齐 也有可移植性问题
5)跨平台通用序列化方法 JSON
1)结构体的嵌套与赋初值
2)数组局部赋初值(区间化方法)
3)结构体类型的多重定义
4)Linux源码是C语言开发技巧的源泉
5)Linux宏定义剖析1:offsetof 获取结构体成员偏移量
6)Linux宏定义揭秘2:container_of 宏组合高阶技巧
1)Linux经典宏定义:container_of 剖析
2)关于GCC中的typeof关键字
3)typeof的普通应用
4)typeof的高阶应用
5)typeof在宏中的应用
6)作嵌入式开发 Linux和GCC 你躲不开的
1)初学者困惑:单片机代码到底为何能操作物理硬件?
2)从 STM32的寻址 到 GPIO外设寄存器
3)高手:我们更喜欢直接操作寄存器
4)老道理:面向用户 和 面向机器 是对矛盾!
5)位域方式操作寄存器(位级别的结构化)
6)位域的初衷:节省内存
1)位域成员同结构体成员一样 永远从低地址开始
2)嵌入式中所谓的“大小端”问题到底是什么?
3)小端 低字节放低地址 大端 低字节放高地址
4)大小端对位域定义都有哪些影响
5)关于位域中的“类型域”的概念
1)大小端影响位域各成员中的位序
2)嵌入式中所谓的“大小端”问题到底是什么?
3)小端 低字节放低地址 大端 低字节放高地址
4)大小端对位域定义都有哪些影响
5)关于位域中的“类型域”的概念
1)单片机上无硬件接口 只能用IO模拟
2)那些经典的低速串行器件
3)典型的高速串行器件VS1003芯片
4)用51单片机实现SDMP3播放器的思路
5)IO模拟SPI速率不够怎么办?
6)IO模拟SPI 基本实现 中规中矩
7)用空间换时间 优化后接口速率翻倍
8)借51硬件特性“硬位域”IO模拟SPI达极致
9)在STM32上还有必要搞GPIO模拟SPI吗?
1)充分利用现有硬件特性 优化代码
2)STM32的位带技术(Bit-Banding Remap)
3)关于STM32 GPIO的BSRR寄存器
4)如何高效地将表达式转为逻辑值 !!
5)GPIO模拟SPI 加入位域后的初步优化
6)STM32中的位带到底是什么?
7)位带地址的计算方法详解
8)使用位带特性对GPIO模拟SPI进行终极优化
1)联合体没用?C语言50年沉淀皆为利器
2)联合体就是同一块内存 多种意义
3)联合体的典型应用
4)使用联合体进行多义数据解析
5)联合体用于通信数据协议解析与封装
1)高手:表达式/运算符认知不同
2)赋值操作:先算右值 再作赋值
3)细数C语言中的那些表达式
4)运算优先级无意义 多用()更清晰
5)工作效率不高?是因为你太勤快!
6)算术表达式的一个奇怪问题
7)C语言算术运算重要原则:保证精度!
8)如何通过串口发送一个浮点数?
1)浮点的本质到底是什么?
2)double双精浮点内存表达(IEEE754标准)
3)printf(“%d”,(double)2.0)输出为 0
4)相同代码 不同平台 可能输出不同
5)嵌入式环境 保证精度 也要考虑资源问题
6)float单精浮点内存表达
7)printf(“%d”,(float)2.0)输出却为 超大值
8)变量赋值 谨防截断!
1)ALU(算术逻辑单元)比你想的更加重要(没有ALU就没有AI)
2)ALU到底负责做哪些计算?
3)ALU虽重要 但却只会作加法 WHY?
4)所有的整数减法都可以转化为加法操作
5)实例:现场推演 2-3 的补码计算过程
6)100*100到底等于多少?别犹豫!
7)莫名奇妙的死循环:变量数值范围要当心!
8)乘法计算是一项比较耗时的操作
9)所有的乘法计算都可转化为 位移+加法 操作
10)高手:从来不单纯的依赖工具 根本还是“人”!
11)负整数的右移操作要当心“算术右移”问题
1)除法比乘法要复杂得多(硬件乘除法器)
2)关于计算性能和实时性
3)除法分为 整数除 和 精确除
4)老原则:算术运算 保证精度
5)小题:如何快速对浮点数四舍五入
6)/ %典型应用1:取数值数位
7)/ %典型应用2:按格式打印16进制数据
8)/ %典型应用3:块数据的尾巴问题
9)高手:善于发掘总结“不可告人”技巧妙招
10)除0和模0问题:要擅长反向设计 防御性编程
11)/0 %0 可让程序崩溃 但有用
1)如何将 数值 转为 其它进制 的字符串?
2)初步实现(最直接的方案往往不是最佳的)
3)尝试对 初步方案 进行简化
4)终极实现方案?No 它还不是终极!
5)最简实现方案:字符串本身就是指针!
6)高手:代码要简洁 可读性要强(提高思维效率)
7)巧将值转为二进制字符串
8)浮点值为何不能直接判等?
9)+0.0和-0.0 它们相等于吗?
10)浮点判等正确方法:极小区间法(区间为何是1E7呢?)
1)莫把== 写成 = 这是一个大坑
2)多条件并列判断时 应将决定性条件放前面
3)C语言中到底有没有bool类型?看看C99
4)!2==1到底等于多少?(多用括号无坏处)
5)善用数字逻辑优化条件表达式
1)高手:位运算的技巧太多了
2)位运算典型应用:使用&>>计算二进制含1数
3) n=n&(n - 1) 一个神奇的式子!(解释原理)
4)判断一个数值是否为2次幂(一般方法 循环法)
5)同上 (巧妙方法 现场演算)
6)置位就用|= 清零就用&=~
7)-1就是极大值(全F为何是-1?现场演算)
8)x&(-x) 又一个神奇的式子!
9)高手2个特质:提前吸收知识 涉及算法思想
1)俗套:通过异或^实现变量互换
2)异或运算实质:不进位加法!
3)异或的运算性质(交换/结合/自反性)
4)俗套?异或换位的原理演算
5)异或运算的典型应用:加密和校验(CRC)
6)经典面试题:求重复数字
7)Google公司面试题:求奇数数字
8)刨根:51中 sbit P11=P1^1 的^是不是异或
9)51单片机SFR地址是8整数倍皆可位寻址
10)51中sbit的真正意义
1)你是否分不清 ! 和 ~
2)逻辑运算背后的数学理论
3)高手:知识要广 认知要深
4)关于变量连续赋值 a=b=c=d=e=f=6
5)条件运算符?: 三目运算的应用
1)宏定义中是否可实现复杂逻辑
2)C语言中的{...}是独立的:独立执行体
3)独立执行体 使宏功能更强大
4){...}中的代码是否可以有“返回值”?
5)如此“怪异”的宏 它到底有什么用?
6)#串化:将宏参数转为字符串
7)宏隐藏规则:””中参数不做文本替换
8)串化和字符串常量的连接
9)##黏结:将宏参数连续成代码文本
10)## 宏参黏结的典型应用
11)宏补充规则:有#或##宏参数不再展开
1)位图 它到底是什么?
2)振南项目经历:位图在OTA中的应用
3)OTA中途失败或断电怎么办?
4)如何记录1000万人的性别信息 用位图
5)如何确定某个数是否在40亿个乱序数据中
6)那些经典的排序算法
7)如何对巨量数据进行排序?
8)巨量数据中有重复怎么办?
1)指针的实质:有类型的地址!!
2)指针是C语言灵魂 是万能的 也是鬼魅
3)指针难于理解的根源 它面向机器 而非用户
4)高手:深入理解CPU内核 指针只是小儿科
5)CPU内核三大总线:数据、地址和控制
6)地址总线位宽决定了寻址空间范围
7)CPU位数:数据总线位宽
8)CPU内核寻址的具体过程(控制总线作用)
9)单片机运作的根本机理
10)((uint8_t *)(0X12345678)) 到底是什么?
1)重申:指针的实质就是有类型的地址!!
2)指令类型乱指 会引发警告和程序混乱
3)高手:C语言的一切 皆是指针
4)int32_t a (变量定义) a=1 (赋值) 你要看穿它
5)通过指针对变量进行 间接赋值
6)指针变量本身占用几个字节?
7)指针中的“怪胎” 多重指针
8)指针分为 指针变量 和 指针常量
9)滥用指针 可酿灾难(地址溢出风险)
1)指针变量++ 它到底+了几呢?
2)指针变量++ 看其类型(地址增加sizeof(类型))
3)C语言中[n] 真正的意义!
4)[n]的几个妙用(灵活用法)
5)提高认知:C语言中一切皆指针!
6)void *p 它算是指针吗?
7)void *p 是万能指针!
8)void 指针的真正意义
9)函数形参中的void指针 (void具有包容性)
10)函数返回值中的void指针 (用前要强转)
1)指针变量一定要赋初值(野指针问题)
2)关于C语言中的空指针(无效指针) NULL
3)傻傻分不清:指针数组和数组指针 其实很简单
4)指针数组 和 数组指针的定义方法
5)指针是什么 就让它优先跟什么结合
6)函数指针 和 双重指针 的定义
7)如何定义指针 就让它如何去指向
8)指向多维数组的指针 的定义
9)二维数组为何不能用 **p来访问
10)多维数组 >3维 已毫无意义
1)指向结构体变量的指针(基础用法)
2)嵌套结构体变量成员的引用方法
3)该死的“代码美学”洁癖症
4)理解了[n]本质之后 结构体可以这样写
5)关于结构体数组 没啥可说
6)结构体是否可以嵌套自已(链表)
7)高手:数据结构必须要掌握!
8)尝试把指针变量的地址码值打印出来
9)[n]中的n 谁说不能<0!(重要认知)
1)[]其实叫作 指针运算符
2)信心是用来打击的 来看这道题
3)回调函数callback到底是什么?(HAL库为例)
4)我们自己写个回调函数(函数指针)
5)回调函数存在的意义是什么?
6)函数指针如何定义?再说一遍
7)高手 和 成功:三个忠告
8)使用 联合体指针 快速取浮点相反数
1)单片机中的“栈” (函数栈)
2)单片机中的“堆” (动态内存源于这里)
3)malloc和free的使用注意事项
4)标准C中的malloc实现比较复杂
5)嵌入式中malloc的轻量级精简实现
6)malloc的具体实现:基本逻辑
7)malloc的具体实现:“内存碎片”如何产生的?
1)“内存碎片”问题会产生什么后果?
2)“内存碎片”的解决:空闲块链表整理
3)“内存碎片”的解决:相临空闲块合并
4)经典面试题1:malloc(0)返回什么?
5)一个笔误的例子:打印数字阶梯
6)经典面试题2:malloc(-1)返回什么?
7)这些并非“奇技淫巧” 而是 深知之引
1)malloc(-1) 返回是NULL 为什么?
2)关于所谓的“僵尸内存”问题
3)如何提高产品的长期稳定性?
4)高手:防止内存溢出的两大原则
5)RTOS可以让程序更加稳定(嵌入式必备技能)
6)重申:栈到底是如何影响程序运行的?
7)从上电到main 到底 STM32在做什么?(栈准备)
1)STM32上电执行的第一条指令是什么?
2)“栈”的开始地址(栈顶)在IVT的第一个字
3)STM32启动运行的第一个函数是什么?
4)关于SystemInit函数
5)__main函数是做什么的?
6)总结:STM32的整个启动过程
7)深刻认知:main的运行只是结果 而非开始
8)突破:在哪烧录 就在哪里启动(BootLoader思想)
9)高手:不求甚解 是你成为高手的一大障碍
1)程序烧录在哪里 就在哪里启动 有重大意义!
2)烧录程序过程中断 导致单片机变砖 怎么办?
3)“守护程序”常驻单片机 让烧录更方便
4)BootLoader的关键核心:AB区间跳转
5)跳转代码根本机理深入剖析
6)跳转代码实质:模拟STM32上电启动过程
7)关于柔性数组 Flexible Array:避免多次动态分配
1)知识点如纲举目张 撒一点而成一片(注意总结重点)
2)高手:悟透相似而差异微妙的概念
3)数组与指针:等价还是相似?
4)char a[6]的外部声明不能写成 extern char *a
5)为何a[6]中的”a”是数组首地址?标识符“退化”机制
6) void fun(char a[])和void fun(char *a)为何是等价的?
7)高手:其实根本不存在数组这个概念!
8)数组下标的起点是 0 你一定要适应!
1)数组本原:它是一种数据结构的载体
2)中段均值滤波算法: 这对数据采集稳定性很有用!
3)此算法应用于 触摸屏坐标采集
4)此算法应用于 加速度采集(倾角传感器)
5)精度和采样率是一对矛盾
6)振南自传《技术干货集》第2章 是此课程缩影
7)GPS NMEA协议解析的实现
8)长字符串解析实现:笨方法
9)长字符串解析技巧:“爆炸”
10)单个子串提取 与 多个子串同时提取
1)数组与字符串基本等价
2)字符串是有约束的字符数组
3)任何数组均可由 字符串+转义符 来表达
4)((float *)"\x1B\x0D\xA9\x41")[0] 是什么鬼?
5)一个问题:定义int a[n]违规吗?
6)安全使用strlen函数的秘诀
7)我们自己实现一个strlen函数(递归法)
8)strcpy函数应用实例 这样有问题吗?
1)细数字符串相关标准函数
2)高手:不重复造轮子 但造了就比现有的好
3)高手:比对巨量数组 傻瓜才一个个遍历
4)网盘秒传的背后机制 剖析!
5)关于数据序列的HASH码
6)海量HASH码快速匹配?查找算法!
1)细数:C语言字符串相关标准函数
2)快速判断某文件在巨量文件中是否存在:HASH值二分搜索
3)二分搜索算法的具体过程
4)细数:常用的搜索算法
5)单片机中数组的另一些典型应用
6)数组存储字模数据:液晶显示文字/图形
7)工具推荐:PCtoLCD、Image2LCD 字模/图模提取工具
8)有字模、图模 那有没有声模?如何取一段音频原始数据?
1)振南的音频播放器实验必备工具 - WinHex
2)将任何文件数据转换为C语言数组
3)中文字符串 什么是DBCS?还有MBCS
4)其实ASCII字符集只是一个特例 SBCS
5)Keil开发环境著名的中文0xFD bug
6)中英文混用字符串编码 C语言采用“紧凑型”方案
7)数组开发技巧两则1:定值初始化方法
8)数组开发技巧两则2:区间式初始化方法
1)你一定要了解断言Assert的意义
2)Assert可以找出代码中隐藏的错误
3)HAL库中的assert_param函数做了什么?
4)assert_param断言的具体实现
5)如何判断GPIO作为形参的合法性?
6)使用断言会使编译代码变大
1)剖析printf函数的本质
2)让printf直接打印在液晶上
3)多路串口格式化输出的实现(printf动态重定向)
4)函数最多可以有几个参数?
5)printf是如何做到参数数量不确定的呢?
1)printf的原型定义:... 代表不定参数
2)不定参数在函数栈内存中是顺序排布的
3)你见过printf函数源代码吗?来看看
4)printf函数源代码剖析解读
5)问题:参数与fmt字符串中的%个数不一致可以吗?
6)自己写个参数不定的函数:计算若干参数的和
7)关于嵌入式日志打印的一些常用方案
8)问题:用宏封装printf 宏参数如何传?
9)宏就是 文本替换?参数不定 却并非如此!
1)函数的调用是要付出代价的
2)例说:小函数频繁调用影响整体代码执行效率
3)内联函数inline:可提升代码运行效率
4)例说:使用inline加速排序算法(选择排序)
5)误解 1:inline函数一定会被展开!
6)误解 2:inline函数并不会被编译出一个函数实体!
7)inline是否被展开 重要因素:复杂度
8)inline函数也有作用域(仅限当前.C中)
9)inline的缺点(实际开发中自己权衡利弊)
10)嵌入式两个大道理:1、莫求完美 2、时空平衡
1)从C代码到可执行BIN总共分几步
2).o和.bin皆可执行文件 为何不能烧录.o文件呢?
3)Linker链接器都做了什么?
4)关于链接脚本文件
5)关于ELF文件(Executable and Linking Format)
6)单片机能否实现动态链接库(类型Windows DLL)
7)预告:嵌入式动态链接库的实现原理
1)吹出去的牛 要圆回来(STM32实现动态加载)
2)嵌入式开发的团队协作模式(裸机)
3)RTOS多任务 团队协作 并行开发 优势淋漓尽致!
4)程序不解耦 牵一发而动全局
5)“段定位”和“函数分散调用”思想 我们从头说
6)程序模块 把“分而治之”作得更彻底一些
7)想法不错 但我们有更好的办法(利用链接器特性)
1)关于单片机中“段”Section的概念
2)将变量分配在我们自己定义的“段”中(段定位)
3)各程序模块自行导出函数到段(分而治之)
4)main对“段”中函数的无差别调用(集中隔离调用)
5)架构:各自为战 并行开发 内聚解耦(核心目标)
6)遗留:“段”的开始和结束在哪里?
7)提示:关于振南知识直播 将学习融合日常!
1)1+2+...+100 用递归法求和
2)嵌入式中递归用得并不多(多采用非递归实现)
3)无停止条件的递归 可挫败世上最强大的计算机
4)可重入:一个函数是否可在多处同时调用?
5)重入函数:运行正确性与调用环境无关!
6)硬件中断响应中的“可重入”风险
7)RTOS:多任务中到处都是“可重入”问题
8)关于51单片机中的关键字reentrant
9)RTOS:解决对“独一份”资源的争抢问题
1)RTOS和Linux 嵌入式工程师的宿命
2)函数return时 CPU到底在做什么?
3)久盯定理:返回值return一瞬 不会有风险吗?
4)函数返回值是如何传递出去的?
5)函数中可以有多个return出口
6)问题:main函数的返回值有什么意义?
1)单片机main函数return到底会怎样
2)专家:你说不对 你真验证过吗
3)为何main函数return形如重启
4)编译器在main函数的最后都作了什么
5)0为成功 非0为失败 错误码约定成俗
6)函数返回错误码 建议使用枚举
1)标准函数也有坑 自己函数与之同名会如何?
2)遇问题勿瞎想 实际测试一下(例说此坑)
3)闭包表达式:({})让执行体有返回值!(例说)
4)独立执行体:函数内再定义函数?
5)临时小函数 就地定义或闭包更方便
1)执行结构:if else switch case do while 等
2)STM32 CPU内核两条重要总线 ICode DCode
3)关于STM32的指令预取技术
4)指令预取 却不一定高效(例说)
5)使用条件分支概率来优化代码(分支预测技术)
6)GCC中__builtin_expect关键字(宏LIKELY与UNLIKELY)
7)if else 不论代码多简单 都要加{}
8)高手:知道编译器到底对代码作了什么
1)将代码用{}包起来 好处多多
2)要注释掉大段代码 不如使用if(0) {...}
3)if(...) else {...} else {...} 多层条件语句(莫超3层)
4)多数if else过多层嵌套 都是自找的(例说简化)
5)“卫语句”的核心思想:先特例 再其它
6)《阿里巴巴编程规范》中对“卫语句”的解释
1)switch case 俗称“散转”
2)GCC中“散转”条件的闭合区间表示法
3)GCC和ARM嫡系编译器ARMCC的区别
4)GCC:嵌入式工程师必经之路
5)“散转”中浮点和字符串不可直接比较
6)变通:字符串的“散转”可使用索引法
7)拍平思想:减少switch case嵌套层数
8)打破定势:各个case和default分支并无次序
1)振南书中《C语言骚操作》:循环
2)for(A;B;C)中的A B C其实很灵活(看透)
3)死循环for(;;)这种写法的来历
4)printf函数的返回值 你有注意过吗?
5)趣味for循环:敢不敢用它来表白女生?
6)for循环的两个常见问题
7)看似多余的空循环 宏中的do while(0)
1)将闭包表达式用在for循环中
2)查找“水仙花数”:直接方法
3)逆向思维:3层for循环方法
4)for循环不要超过3层 否则影响可读性
5)2层循环典型应用:打印原始数据
6)for循环条件中应避免使用表达式
7)用循环测试代码执行效率
8)为什么死循环可使单片机重启:看门狗
9)高手:你到底是在写程序 还是在写bug?
1)莫名其妙的死循环:你在写代码还是bug
2)RTOS多任务:任务中有死循环while(1)会怎样?
3)RTOS时间片轮转 其实抢占式更多见!
4)RTOS vs 单片机裸机 延时函数的实现原理
5)问题:如何从for循环中提前退出?
6)其实break和continue适用于所有循环
1)用while(1)+if来检测脉冲的沿信号
2)do while用来替代goto语句
3)#define+#undef+#ifdef实现条件预编译
4)解决空宏的warning问题
5)独立执行体+闭包表达式 是绝配
6)goto语句使用上的若干注意点
7)goto语句必非不能用 它能让问题归一化
8)关于循环中定义变量和初始化的几点误解
1)《高阶C》课程民意调查:若有第2季 君会入否?
2)变量是否可以在代码中间定义
3)过程中变量定义的3种方法
4)从{}独立执行体的角度去看待变量定义
5)C99之后 变量定义可以在代码中间
高手C是RTOS的基础,学了这个更容易学会RTOS。 课如其名,它是与众不同的! 它有什么不同,又到底高在哪里呢?总体来说,这套课程不是像传统C语言课程那样对于基础知识的按部就班,而是对这些知识的实战化升华和深入剖析,其背后是振南嵌入式从业15年的项目经历和解决现实问题的心血倾注。 这套课程中包含来自项目的众多现实问题、我在课程中用简约生动的语言去讲述了很多不简单的嵌入式技术问题、同时我采用全部真人如临现场的授课方式,步步启发 层层剖析 将你带入一种高手的思维模式。