当前位置: 首页 > 科技观察

全屏if-else,如何消除?

时间:2023-03-16 22:22:14 科技观察

本文转载自微信公众号《程序喵大师》,作者程序喵大师。转载本文请联系程序大师喵公众号。之前在知乎上写过一篇回答,里面详细介绍了if-else的效率。过多的if-else不仅会导致程序运行效率低下,还会导致代码循环复杂度过高。如果你使用过静态代码分析工具,就会知道圈复杂度是衡量代码质量的重要指标。圈复杂度越高,出现代码错误的可能性就越大。我们一开始写的代码可能很简洁,只有一个if-else分支,但是由于需求和各种错误处理的叠加,我们有时不得不多加几个if-else,让你讨厌你写的代码。至于如何消除if-else,可以说是八仙过海大显神通了。下面介绍几种常用的方法:表结构的巧妙利用:一般情况下,如果有些条件可以存,可以考虑把条件存下来去掉if-else,例如:longlongfuncfor(unsignedc=0;c=128)sum+=data[c];}returnsum;}代码中的if分支可以通过表结构longlongfunc()去掉{constunsignedARRAY_SIZE=50000;intdata[ARRAY_SIZE];constunsignedDATA_STRIDE=256;intlookup[DATA_STRIDE];for(unsignedc=0;c=128)?c:0;}for(unsignedc=0;c30)return;if(c<18)return;}可以改成voidfunc(){if(a<20||b>30||c<18)return;}策略模式:熟悉设计模式的同学可能都知道,if-else里面太多了一般代码,那么可以考虑使用策略模式,例如:enumclassCalOperation{add,sub};intNoStragegy(CalOperationope){if(ope==CalOperation::add){std::cout<<"thisisaddoperation"<classCalculation{public:Calculation(){}virtual~Calculation(){}virtualvoidoperation(){std::cout<<"baseoperation"<operation();deletecal;Calculation*cal2=newSub();//这个以后可以用工厂模型改,不会违反开闭原则cal2->operation();deletecal2;return0;}以后如果有乘法、除法等运算规则,只需要增加一个继承基类的子类,方便扩展,遵循设计原则即可。责任链模式:责任链模式虽然不能消除if-else,但是可以用来改进if-else,使其更加灵活,例如:#includeusingstd::cout;voidfunc(intnum){if(num>=0&&num<=10){cout<<"0-10\n";}elseif(num>10&&num<=20){cout<<"10-20\n";}elseif(num>20&&num<=30){cout<<"20-30\n";}elseif(num>30&&num<=40){cout<<"30-40\n";}elseif(num>40&&num<=50){cout<<"40-50\n";}elseif(num>50&&num<=60){cout<<"50-60\n";}else{cout<<"nothandle\n";}}intmain(){func(25);func(43);return0;}可以考虑如下:#includeusingstd::cout;structHandle{virtualvoidprocess(intnum){}};structHandle1:publicHandle{Handle1(Handle*processor):processor_(处理器){}voidprocess(intnum)override{if(num>=0&&num<=10){cout<<"0-10\n";}else{processor_->process(num);}}Handle*processor_;};structHandle2:publicHandle{Handle2(句柄*处理器):processor_(处理器){}voidprocess(intnum)override{if(num>=10&&num<=20){cout<<"10-20\n";}else{processor_->process(num);}}Handle*processor_;};structHandle3:publicHandle{Handle3(Handle*processor):processor_(processor){}voidprocess(intnum)override{if(num>=20&&num<=30){cout<<"20-30\n";}else{cout<<"nothandle\n";}}Handle*processor_;};intmain(){Handle*handle3=newHandle3(nullptr);Handle*handle2=newHandle2(handle3);Handle*handle1=newHandle2(handle2);handle1->process(24);handle1->process(54);return0;}三元运算符:在一些简单的情况下,可以使用三元运算符来消除if-else,例如:intfunc(intnum){if(num>20)return1;elsereturn0;}三元运算符:在一些简单的情况下,可以使用三元运算符来消除if-else,例如:intfunc(intnum){if(num>20)return1;elsereturn0;}可以改成:intfunc(intnum){returnnum>20?1:0;}这样是不是让代码更清晰了?else-if消除:有时候有些人写的代码确实是这样的,比如:intfunc(intnum){intret=0;if(num==1){ret=3;}elseif(num==2){ret=5;}else{ret=6;}returnret;}是否可以考虑改成:intfunc(intnum){if(num==1)return3;if(num==2)return5;return6;}