malloc、new、free和delete的比较
new分配内存分为两个步骤
- 给对象分配内存(operator new())和malloc等同
- 调用构造函数
delete销毁对象也分为两个步骤
- 调用析构函数
- 回收空间(如果是malloc就用free回收)
malloc和free
- malloc只是分配内存不调用构造函数
- free只是回收内存不调用析构函数
#define和const的比较
-
处理阶段不同(预处理 vs 编译):#define在预处理时展开,const在编译时定义;
-
类型检查不同(无 vs 有):#define的机械替换导致其不会进行类型检查,const作为代码部分会进行类型检查;
-
内存分配不同(无 vs 有):#define没有内存分配,const有;
-
代码展开不同(每次都展开 vs 只有一份):#define在代码中引用了几次就展开几份,const只保留一份。
*p++、*(p++)、(*p)++、*++p、++*p
优先级问题
- 这些东西的优先级是这样的:() > 后置++ > 前置++和*
- 当优先级不同时候,先讨论优先级;当优先级相同时,讨论结合性
实例
*p++
- 这里由于优先级后置++高于*,先计算后面p++,但是由于后置++,返回值为本身p指针,所以解引用为p
*(p++)
- 这里先计算后面的,但是返回还是p之前的值
(*p)++
- 先解引用p,对p指向的地址的值++,但是还是返回*p
*++p
- 前置++和*优先级相同,按顺序结合计算,这里要先计算++p,先后移后解引用
++*p
- 优先级相同,按照结合性计算,那么先解引用,然后++
inline和宏的比较
特性 | 内联函数 | 宏 |
---|---|---|
定义方式 | inline 函数 | #define 预处理器指令 |
类型检查 | 有 | 无 |
副作用控制 | 参数求值一次 | 可能多次求值 |
调试支持 | 较好 | 较差 |
功能复杂性 | 支持复杂逻辑 | 仅简单替换 |
编译器控制 | 可优化选择是否内联 | 强制展开 |
使用场景 | 小型性能敏感函数 | 常量定义、条件编译 |
- 一般情况下,宏的开销在小规模、简单场景下可能稍小,但在复杂场景或大规模使用时,其代码体积和潜在副作用会导致总体开销大于内联函数。内联函数因其安全性、可控性和现代编译器优化支持,通常是更优选择,实际开销也更低或至少更可预测。也就是说,inline开销普遍小于宏