嵌入式技术公开课精华笔记:CSDN专版
嵌入式技术公开课详细笔记——CSDN专版
本文整理自一次嵌入式技术公开课的完整回顾,涵盖笔试/面试真题解析、C++运算符重载、字符串拷贝函数实现、位操作技巧以及 sizeof
运算符底层机制等内容,适合嵌入式初学者与进阶开发者学习。
嵌入式开发笔试题解析:二进制 1 的个数统计
在嵌入式开发笔试中,二进制位运算类问题非常高频。本次课程重点分析了微软/京东的一道经典题目:统计整数 $X$ 的二进制表示中 1
的个数。
核心思路
函数 F(X)
的关键语句为:
X &= (X - 1);
这行代码的作用是 将 X 的二进制表示中从右往左的第一个 1
置为 0
,并且它右侧的所有位保持不变(因为减 1 会翻转右侧位)。
示例:
假设:
X=200(10)=11001000(2) X = 200_{(10)} = 11001000_{(2)} X=200(10)=11001000(2)
执行:
X &= (X - 1);
过程:
- $X - 1 = 11000111_{(2)}$
- 按位与:$11001000 \ &\ 11000111 = 11000000$
结果:
X=192(10)=11000000(2) X = 192_{(10)} = 11000000_{(2)} X=192(10)=11000000(2)
重复这个过程,直到 $X = 0$,统计执行次数即可得到 1
的总数。
扩展应用:判断一个数是否为 2 的 N 次方
如果一个整数是 $2^N$,它的二进制表示中 仅有最高位是 1,其余全是 0。
因此可以使用:
(X & (X - 1)) == 0
判断。例如:
- $8_{(10)} = 1000_{(2)}$ →
(8 & 7) = 0
→ 是 $2^3$ - $6_{(10)} = 0110_{(2)}$ →
(6 & 5) = 4
→ 不是 $2^N$
运算符重载与常量性
在面向对象的嵌入式开发中,运算符重载是常见考察点。本次课程分析了 student
类中两个 []
运算符重载函数的区别:
class student {
public:double& operator[](int index); // 非 const 版本double operator[](int index) const; // const 版本
};
区别解析
-
非 const 版本
double& operator[](int)
返回引用,可作为左值,允许修改元素值。 -
const 版本
double operator[](int) const
返回值为副本,不能直接修改,只能读取。
示例
student scores;
scores[0] = 3.14; // 调用非 const 版本,可修改
double val = scores[0]; // 调用 const 版本,只读
在实际开发中,const 成员函数保证了对象内容不会被无意修改,尤其在传递常量对象引用时非常有用。
字符串拷贝函数实现(my_strcpy)
课程中讲解了如何手写实现一个字符串拷贝函数 my_strcpy
,要求:
- 禁止使用
strcpy
等库函数。 - 处理 空指针 情况。
- 考虑 内存重叠(
src
和dst
指向同一块内存的不同位置)。 - 优化寻址步骤,减少 CPU 指令。
基础实现
char* my_strcpy(char* dst, const char* src) {if (!dst || !src) return NULL; // 空指针检查char* ret = dst; // 保存起始地址while ((*dst++ = *src++) != '\0'); // 逐字符拷贝return ret; // 返回起始地址
}
核心优化
- 原版实现:7 次操作完成一次字符拷贝。
- 优化版本:通过指针自增减少寻址,降至 5 步操作,提升速度。
位操作实战技巧
位操作是嵌入式编程的基本功,尤其在寄存器控制中应用广泛。
设置某位为 1(置位)
a |= (1 << n);
例如将第 3 位置 1:
a |= 0x08; // 二进制 00001000
将某位清零
a &= ~(1 << n);
例如将第 3 位清零:
a &= 0xF7; // 二进制 11110111
应用场景
- 控制单片机外设寄存器开关某功能位。
- 位掩码运算进行状态标志管理。
sizeof 运算符底层行为
最后,课程解析了 sizeof
的特殊性:
sizeof
是运算符,不会对表达式求值。
示例:
int i = 10;
printf("%zu\n", sizeof(i++)); // 输出类型大小
printf("%d\n", i); // 依然是 10
原因:
sizeof(i++)
在编译期计算类型int
的大小(假设 4 字节)。- 不会真正执行
i++
,因此i
的值不变。
总结
本次嵌入式技术公开课的重点是:
- 掌握位运算技巧及其应用(统计 1 的个数、判断 2 的 N 次方、寄存器位控制)。
- 理解 C++ 中运算符重载与 const 的作用。
- 学会自己实现高效的字符串拷贝函数。
- 理解
sizeof
的编译期行为,避免被陷阱题误导。