携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第30天,点击查看活动详情
宏、枚举和常量(上)
之前的文章中曾经简单讨论了指针常量和常量指针的区别。这里继续聊聊相关话题。
宏
宏其实是C里面的语法,在C++中不再推荐使用类似语法了。那么宏都有哪些用法呢?
保证同一个头文件只被包含一次
这个用途应该是使用频率最高的了。大家在阅读一些比较底层的一些源码时会经常看到下面这种语句:
#ifndef XXX_H
#define XXX_H
...
#endif
这个作用其实不仅可以用来保证同一个头文件不被包含多次,还可以保证同样的代码块不被包含两次。这里假设a.h和b.h的内容完全一样,但这两个文件显然文件名是不一样的,借助这种方法,也可以实现他们两个之中最多只有一个会被包含。这里由于都是头文件级别的标识,所以宏在起名时都遵从Google的命名规则,尽量做到全局唯一。对于代码块的话,则无需用_H结尾的宏进行标识,起名可以更随意一点。
这里当然还要提一下一种看起来可能更优雅的、由编译器支持的语法,那就是#pragma once。这个语法大家在Windows可能见得更多一些。基于宏的方法是C/C++标准所支持,那么显然,宏更通用一点。当然,如果用宏没有一点缺点的话,大概率也就不会有新的特性来支持这种行为了。
在这里,宏的缺点其实很明显,一是看起来相对比较繁琐(起码有三行),二是编译器每次都需要打开头文件才能判定是否有重复定义使得在编译大型项目时编译时间会相对较长,三是其实纵然有命名规范约定,也很难保证没有宏名撞车的情况(当然,如果严格按照Google的规范来进行定义,是一定不会撞车的,因为它的表述是为保证唯一性,头文件的命名应该基于所在项目源代码树的全路径)。