面试题答案
一键面试常见注意事项
- 宏定义没有作用域:宏定义从定义处开始到文件结束都有效,除非用
#undef
取消定义。例如在不同函数中定义相同名字宏,可能会导致意外结果。 - 宏替换不进行类型检查:宏只是简单的文本替换,不进行任何类型检查。如
#define ADD(a, b) a + b
,当使用ADD(1, 2 * 3)
时,结果是1 + 2 * 3
而不是预期的(1 + 2) * 3
,应写成#define ADD(a, b) ((a) + (b))
以避免优先级问题。 - 宏可能导致代码膨胀:如果宏定义比较复杂且在多处使用,会使生成的目标代码体积增大,因为每次使用宏都会进行文本替换。
- 调试困难:宏替换在编译预处理阶段完成,调试时看到的是替换后的代码,难以直接定位宏定义本身的错误。
应用场景
- 定义常量:例如
#define PI 3.1415926
,用宏定义常量比直接使用字面量更易读且便于修改。在数学计算相关的项目,如几何图形计算模块中,用于定义圆周率等常量。 - 条件编译:根据不同条件编译不同代码。如
#ifdef DEBUG #define LOG(x) std::cout << x << std::endl; #else #define LOG(x) #endif
,在开发阶段开启DEBUG
宏可打印调试信息,发布阶段关闭宏,不产生额外调试代码。常用于跨平台开发项目,根据不同平台编译不同代码部分。 - 代码简化:比如
#define SAFE_DELETE(p) { if(p) { delete p; p = nullptr; } }
,在管理动态内存时,通过宏简化重复的内存释放和指针置空操作,在游戏开发中管理对象资源释放时常用。