2026/2/9 20:24:22
网站建设
项目流程
做汽车特卖会的网站,wordpress连接谷歌地图,湖南手机版建站系统开发,免费网络连接一、综述
在C语言中#xff0c;宏与constexpr(const)#xff0c;主要于常量和表达式的处理#xff0c;特别是在编译期计算时#xff0c;有着重要的作用。很多开发者可能对二者的使用非常多#xff0c;但二者到底有什么不同可能不是很清楚。或者说#xff0c;无法清晰的描…一、综述在C语言中宏与constexpr(const)主要于常量和表达式的处理特别是在编译期计算时有着重要的作用。很多开发者可能对二者的使用非常多但二者到底有什么不同可能不是很清楚。或者说无法清晰的描述出二者的不同只可意会无法言传。下面将对二者在不同的角度进行细节上的区分和说明。二、宏与constexpr的区别对于宏于常量处理可以从形式和内容、编译期和作用域等角度进行对比其区别在于类型检查对于宏来说是不进行类型检查的而constexpr作为C中的关键字是要进行强类型检查的#definePI3.14159constexprintx100;doubleretPI*3;constexprdoubledx*3;作用域的处理宏只是单纯的替换不受作用域的控制而constexpr则不然它作为关键字当然受作用的限制如名空间等#define PI 3.14 namespace Demo{ #define LEN 10 constexpr int d 10; } int ret PI*2; ret LEN *2; ret Demo::d *2;应用范围宏可以用在预处理阶段编译前和条件编译而constexpr只能用于编译阶段且不能用于条件编译但它可用于编译期计算#ifdefDEBUG#defineSIGNAL100#else#defineSIGNAL1#endif对字符串的处理不同宏可以使用“#”和“##”来进行字符串的处理而constexpr则只是一种关键字进行常量限定但支持复杂的字符串操作#defineSTRING(x)#x#defineCONCAT(s1,s2)s1##s2constevalautostr_concat(){returnstd::string_view(hello) world;}对调试的友好度宏由于只是在编译期进行替换动作所以其对调试并不友好调试相对困难而constexpr则对调试非常友好可以展现相关的错误信息便于调试异常的引入对宏来说由于开发复杂比如小括号的处理和换行符的处理往往导致异常的情况而constexpr则定义清楚安全可控#defineMUL(x,y)x*y//表达复杂的情况下会出现问题MUL(23,10);//32,期望是50复杂编程宏可以从简单到复杂的应用但使用宏来实现复杂的逻辑对于开发者的水平要求非常高而constexpr则只是一个关键字谈不上简单复杂的应用一说。有兴趣的可以看一下前面的反射相关中的复杂的宏应用此处不再赘述可维护性简单的宏还好但对于稍微复杂一些的宏来说可维护性就相对差不少了而对constexpr来说可维护性只与其使用的场景有关而与其自身无关需要赘述一下的是在C20以后扩展了constexpr的应用范围增加了consteval关键字这都是对常量表达式的一种更广泛的推广应用。大家可紧密的跟踪新标准的中相关说明不断的扩展自己的眼界。三、应用场景选择在前面的文中也反复提到过在没有特殊的情况下不建议使用宏特别是复杂的宏开发。宏与C的强类型语言本身还是有些相悖的所以一般都是推荐使用constexpr。同时constexpr对调试的友好性也容易在出现问题后便于定位和解决问题。但宏也有其优势之处特别是在条件编译和预处理时constexpr则只能望洋兴叹力有所不逮。另外对于控制头文件的重复包含、编译器或硬件平台的特性支持以及一些底层预定义应用的宏也都是宏应用的优势之处。四、例程下面给出一个对比的例程#includeiostream#includechrono#includearray// 宏#defineSQUARE(x)((x)*(x))// constexprconstexprintconstSquare(intx){returnx*x;}constexprintcompileTest(){constintmRetSQUARE(5);constexprintcRetconstSquare(5);static_assert(SQUARE(3)7,cacl err);//可修改7为9static_assert(constSquare(3)9,constexpr cacl err);return0;}intmain(){//编译期测试constexprintretcompileTest();intx2;intmacRetSQUARE(x);std::coutcur cacl ret is:ret,macRetstd::endl;//编译期和运行期计算constexprintcSquareconstSquare(2);intrSquareconstSquare(x);std::coutcur cacl ret is:cSquare,rSquarestd::endl;//加和计算inty3;intsumRetSQUARE(xy);intcSumRetconstSquare(xy);std::coutcur cacl ret is:sumRet,cSumRetstd::endl;return0;}五、总结十八般武器各有各的优势长得相近的武器未必就可以互相替代。哲学上不是有句名言么“存在即合理”。宏和constexpr就是这种情形。在一个好的开发者的眼中只有最合适的方法没有最优的方法。至于如何选择宏和constexpr多吃几回亏就好了。