HAL*_*HAL 31 c c++ if-statement
是否有更好(或更清洁)的方法来编写以下代码?
if(conditionX)
{
if(condition1)
{
// code X1
}
else if(condition2)
{
// code X2
}
}
else if(conditionY)
{
if(condition1)
{
// code Y1
}
else if(condition2)
{
// code Y2
}
}
Run Code Online (Sandbox Code Playgroud)
我还有一些条件,但我想你明白了.
das*_*ght 34
这个问题有四种方法,其中没有一种是通用的:
condition1并且condition2很棘手,请预先计算它们并将它们存储在bool变量中conditionX并conditionY产生结果,让您统一condition1和condition2 -这并不总是可能的,但在某些情况下,你可以,比方说,使用函数指针或拉姆达准备一个统一的两个分支所采取的活动的变量.conditionX/ conditionY创建一个创建子类的地方,然后通过调用接口中虚拟函数的正确覆盖来"重用"该决定.switch - 此技巧统一条件,减少嵌套.以下是最后一种方法的示例:
int caseNumber = ((conditionX?1:0) << 3)
| ((conditionY?1:0) << 2)
| ((condition2?1:0) << 1)
| ((condition1?1:0) << 0);
switch (caseNumber) {
case 0x09:
case 0x0D:
case 0x0F: // code X1
break;
case 0x0A:
case 0x0E: // code X2
break;
case 0x05:
case 0x07: // code Y1
break;
case 0x06: // code Y2
break;
}
Run Code Online (Sandbox Code Playgroud)
pax*_*blo 25
如果您在查看源代码时关注的是干净的代码,我的建议是将块分隔到它们自己的部分,例如:
if (conditionX) processConditionX();
else if (conditionY) processConditionY();
Run Code Online (Sandbox Code Playgroud)
等等.
然后,在子功能中,放置"肉":
void processConditionX (void) {
if(condition1) {
// code X1
} else if(condition2) {
// code X2
}
}
Run Code Online (Sandbox Code Playgroud)
您可以修改它以传入并根据需要返回参数,我会使条件和函数名称更具描述性,但我认为它们只是示例.
bar*_*nos 14
您可以改为实现状态机:
#define COMBINATION(a,b,c,d) (((a)<<3)|((b)<<2)|((c)<<1)|((d)<<0))
switch (COMBINATION(conditionX,conditionY,condition1,condition2))
{
case COMBINATION(0,0,0,0): break;
case COMBINATION(0,0,0,1): break;
case COMBINATION(0,0,1,0): break;
case COMBINATION(0,0,1,1): break;
case COMBINATION(0,1,0,0): break;
case COMBINATION(0,1,0,1): CodeY2(); break;
case COMBINATION(0,1,1,0): CodeY1(); break;
case COMBINATION(0,1,1,1): CodeY1(); break;
case COMBINATION(1,0,0,0): break;
case COMBINATION(1,0,0,1): CodeX2(); break;
case COMBINATION(1,0,1,0): CodeX1(); break;
case COMBINATION(1,0,1,1): CodeX1(); break;
case COMBINATION(1,1,0,0): break;
case COMBINATION(1,1,0,1): CodeX2(); break;
case COMBINATION(1,1,1,0): CodeX1(); break;
case COMBINATION(1,1,1,1): CodeX1(); break;
}
Run Code Online (Sandbox Code Playgroud)
这仅包括一个分支操作,因此它可能更高效(即使它还包括额外的运行时计算(switch在线)).
至于更清洁,我想这是一个透视问题,但上面的模板还为您提供了一种检测代码中所有未处理分支的便捷方法.
请注意,如果任何条件变量的值不是1或0,那么您应该:
#define COMBINATION(a,b,c,d) (((a)?8:0)|((b)?4:0)|((c)?2:0)|((d)?1:0))
Run Code Online (Sandbox Code Playgroud)
更新(在以下评论之一中归因于@Jonathan Wakely):
如果你正在使用C++ 11,那么你可以COMBINATION用一个constexpr函数替换宏:
constexpr int COMBINATION(bool a,bool b,bool c,bool d)
{
return ((int)a<<3) | ((int)b<<2) | ((int)c<<1) | ((int)d<<0);
}
Run Code Online (Sandbox Code Playgroud)
我将在第一个if中作为参数提供给分离函数的决定,然后决定执行哪个代码,例如:
if(conditionX)
{
Method1(Condition Parameters)
}
else if(conditionY)
{
Method1(Condition Parameters)
}
Run Code Online (Sandbox Code Playgroud)
另一种方法是向决策方法(矩阵)提供所有需要的信息,此方法返回一个整数,您在switch语句中使用该整数来决定执行哪个代码.通过这种方式,您可以将desicion逻辑分开,使其可读并且在需要时可以轻松进行单元测试:
DecisionMatrix(conditionX, conditionY, condition1, condition2)
{
// return a value according to the conditions for Example:
// CoditionX + Condition1 => return 1
// CoditionX + Condition2 => return 2
// CoditionY + Condition1 => return 3
// CoditionY + Condition2 => return 4
}
switch(DecisionMatrix)
{
case 1: //run code X1
break;
case 2: //run code X2
break;
case 3: //run code Y1
break;
case 4: //run code Y2
break;
}
Run Code Online (Sandbox Code Playgroud)