解决方案很明显,但这是关于好的解决方案的问题。
(编辑:nice 我的意思是,例如 1)没有代码冗余 2)没有牺牲性能 3)没有强制程序员创建一些不必要的函数或临时变量)
假设我想根据 a
、b
、c
中哪个数字最小来执行 3 个不同的代码块。
代码看起来像这样:
if( a < b ){
if( a < c ){
// code block for "a is minimum" case
}else{
// code block for "c is minimum" case
}
}else{
if( b < c ){
// code block for "b is minimum" case
}else{
// code block for "c is minimum" case
}
}
我不喜欢的是我必须复制 //"c is minimum"case
代码块两次。
有几种解决方案。例如。我可以将"c is minimum"
的代码块放入内联函数 或宏 中。但我不喜欢它(阅读起来似乎不太清楚)。
老派的解决方案是使用 goto
,例如:
if( a < b ){
if( a < c ){
// code for "a is minimum" case
goto BRANCHE_END;
}
}else{
if( b < c ){
// code for "b is minimum" case
goto BRANCHE_END;
}
}
// code for "c is minimum" case
BRANCHE_END:
但是人们不喜欢看到 goto(有充分的理由)。另一方面,在这种特殊情况下,它甚至具有很好的可读性。
如果代码块是独立的函数,它可以这样写
void myBranching( double a, double b, double c ){
if( a < b ){
if( a < c ){
// code for "a is minimum" case
return;
}
}else{
if( b < c ){
// code for "b is minimum" case
return;
}
}
// code for "c is minimum" case
return;
}
(实际上和那个goto
几乎一样)但是在很多情况下,类似的代码块必须是更复杂算法的一部分,并且将它放在函数中是不方便的。封装在函数中需要传递许多在内部和外部都使用的变量(例如,请参见下面的用例)。
在 C/C++ 中是否有任何控制结构可以优雅地解决这个问题。
注意:考虑性能关键代码。 (例如光线追踪器、GLSL 着色器、物理模拟)。任何会增加一些不必要的计算开销的事情都是不可能的。
其他问题/评论
- 这是我觉得 Structured programming 的几个例子之一绑住我的手,这只是
jump
指令可能做的事情的子集。您是否知道使用goto
而不是标准控制结构的算法会更加简单明了的其他示例? - 您能想象更复杂的分支,需要多次复制某些代码块吗?
编辑:用例
我认为有些困惑是由于我没有指定要在其中使用它的上下文。这是光线追踪规则算法的一部分 triclinic 3D 网格(类似于 3D 中的 Bresenham's line algorithm,但起点是 float 的(未与任何框的中心对齐))
但是请不要关注算法本身,它也可能是错误的,我正在调试它。
double pa,pb,pc,invPa,invPb,invPc,mda,mdb,mdc,tmax,t;
int ia,ib,ic;
// for shortness I don't show initialization of these variables
while( t<tmax ){
double tma = mda * invPa;
double tmb = mdb * invPb;
double tmc = mdc * invPc;
if( tma < tmb ){
if( tma < tmc ){ // a min
t += tma;
mda = 1;
mdb -= pb*tma;
mdc -= pc*tma;
ia++;
}else{ // c min
t += tmc;
mda -= pa*tmc;
mdb -= pb*tmc;
mdc = 1;
ic++;
}
}else{
if( tmb < tmc ){ // b min
t += tmb;
mda -= pa*tmb;
mdb = 1;
mdc -= pc*tmb;
ib++;
}else{ // c min
t += tmc;
mda -= pa*tmc;
mdb -= pb*tmc;
mdc = 1;
ic++;
}
}
// do something with ia,ib,ic,mda,mdb,mdc
}
最佳答案
您可以使用 std::min
轻松解决此问题并使用带有 std::initializer_list
的版本。您对三个变量调用 min
以获得最小值,然后您有三个 if 语句来检查每个变量的返回值。
void foo(int a, int b, int c)
{
int min = std::min({a, b, c});
if (min == a)
{
// a case
}
else if (min == b)
{
// b case
}
else
{
// c case
}
}
关于c++ - 根据 3 个数字中最小的那个进行分支,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37399010/