我正在尝试使下面的代码既可读又具有高效性。我想避免对getFlagB()
进行任何不必要的调用,同时也不要重复任何事情。下面我写了两种方法,每种方法都满足其中一个标准。
假设getFlagB()
不能以任何方式改变。有没有办法在C中同时满足这两个要求,而不创建额外的标志?
// Method 1 - doesn't repeat code blocks but calls getFlagB even when it may not need to
void foo(int flagA)
{
int flagB;
getFlagB(&flagB);
if(flagA & flagB)
{
// Code block 0
}
else
{
// Code block 1
}
}
// Method 2 - doesn't no extra call to getFlagB, but repeats code block 1
void foo(int flagA)
{
int flagB;
if(flagA)
{
getFlagB(&flagB);
if(flagB)
{
// Code block 0
}
else
{
// Code block 1
}
}
else
{
// Code block 1
}
}
答案 0 :(得分:3)
你可以这样做:
void foo(int flagA)
{
int flagB;
if(flagA)
{
getFlagB(&flagB);
if(flagB)
{
// Code block 0
return ;
}
}
// code block 1
}
答案 1 :(得分:3)
在另一个方法中包装getFlagB()
,然后让编译器为你排序。
int myGetFlagB() { int b; getFlagB(&b); return b; }
void foo(int flagA)
{
/* note: assume you mean && and not &, otherwise there is no way
* to short circuit - you always need to call getFlagB for a
* bitwise AND.
*/
if(flagA && myGetFlagB())
{
// Code block 0
}
else
{
// Code block 1
}
}
答案 2 :(得分:1)
我无法明确地说什么,因为我没有看到任何实际的代码,但在我看来,flagA是无关紧要的,可以忽略。虽然必须评估flagB,因为它是相关的并导致代码更改。
void foo()
{
getFlagB(&flagB)
if(flagB)
{
//Code 1
}
else
{
//Code 0
}
}
但我假设您的程序中没有不必要的标记。所以我建议做一个借调的,它更有效和优雅,即使它看起来不那样。
答案 3 :(得分:1)
修改强>
只要将flagB初始化为0,您也可以执行以下操作。这避免了我之前发布的代码中的错误,该错误假定在代码块0中未修改标志,这可能导致代码块0和1执行。我推荐这个新的只是因为你可能在某些时候想要修改foo()中的标志:
int flagB = 0;
if (flagA)
getFlagB(&flagB);
if (flagA && flagB) {
// code block 0
} else {
// code block 1
}
是的,flagA经过两次测试。你有一个三元条件,但你要求一组二元结果。如果没有像上面提到的那样使用序列点,则必须测试两次或重复代码或不必要地调用函数或者如果设置了flagA则添加额外的函数调用开销。
他们都是有效的解决方案恕我直言。这只是一个可读性和您希望代码表现如何的问题,更不用说避免代码重复......没人喜欢! : - )
快乐的编码!
答案 4 :(得分:1)
如果您真的不想封装getFlagB调用或拆分if,则可以滥用逗号运算符:
if(flagA && (getFlagB(&flagB), flagB)) {
即使看起来不太好,但它确实是你想要的。
答案 5 :(得分:1)
在if
之前明确计算条件。
_Bool condition = flagA;
if ( flagA ) { /* First decide what to do. */
_Bool flagB;
GetFlagB( & flagB );
condition = flagA && flagB; /* Prefer && over &. */
}
if ( condition ) { /* Then do it. */
Code1();
} else {
Code2();
}