How can I rewrite this (purely) without gotos?

How can I do this cleanly without gotos?

loop: if(condition1){ something(); } else if (condition2) { somethingDifferent(); } else { mostOfTheWork(); goto loop; } 

I would prefer not to use breaks. In addition, it is expected that it will run several (up to 40) times before doing anything else, so that part of mostOfTheWork will most likely be as high as possible, even if it's just for readability. Thanks in advance.

EDIT: this was published in accordance with the misconception that the compiler optimizer did not work intermittently, which, while generally stupid, from the very beginning, I turned out to be wrong for myself through experimentation (performance). On the other hand, thanks for your answers; they were interesting to read in different styles.

+4
source share
8 answers

It is clear that you will exit the loop if any condition occurs.

  while ((!condition1) && (!condition2)) { MostOfTheWork(); } if (condition1) { something(); } else if (condition2) { somethingDifferent(); } 

So loop until no condition quit, and then look which one you got.

Now, someone will scream that I appreciated the conditions more than I need to. For their benefit, the modified version:

 { bool t1, t2; while ((!(t1 = condition1)) && (!(t2 =condition2))) { MostOfTheWork(); } if (t1) { something(); } else if (t2) { somethingDifferent(); } } 
+10
source
 bool done = false ; while( !done ) { if(condition1){ something(); done = true ; } else if (condition2) { somethingDifferent(); done = true ; } else { mostOfTheWork(); } } 
+10
source

No breaks?

 function foo(){ if(condition1){ something(); return; } else if (condition2) { somethingDifferent(); return; } mostOfTheWork(); foo(); //(Tail recursive for those worried about stack overflows) } 

However, there are interruptions to the flow control, they are much clearer about what they are doing than goto, so I would recommend using them. However, in this case, I would recommend @John's answer as the right way to do this.

+2
source

No bunkers or beaks. Cleanliness as always, subjective

  do { if ( condition1 ) something(); else if( condition2 ) somethingElse(); else mostOfTheWork(); } while( !(condition1 || condition2) ); 

This, of course, is incredibly stupid. Just use a break.

+1
source

You may have taught CS professors that this is bad and will cause chaos in your code. Gotos are actually quite effective when used properly and intentionally. This is why most programming languages ​​have not given up on this.

In your particular case, goto is great because the code block is small and you can easily see the program flow. You can write spaghetti code with other control structures, although this is a bit more difficult to do.

+1
source

Since you were not language specific, some languages ​​have continue , next or skip , which you can use goto instead.

0
source
 do { if(condition1){ something(); } else if (condition2) { somethingDifferent(); } else { mostOfTheWork(); } } while (!condition1 && !condition2) 
0
source

In my opinion, this version of the code most clearly conveys the program flow to the offspring and most easily extends. Yes, I use break . I can’t think of any real reason not to do this.

 while(true) { if (condition1) { something(); break; } if (condition2) { somethingDifferent(); break; } mostOfTheWork(); } 

If you really don't want to use break , you can use goto to exit the loop or use return to execute the function (if this loop is part of a larger function you will have to refactor it).

 while(true) { if (condition1) { something(); goto exit; } if (condition2) { somethingDifferent(); goto exit; } mostOfTheWork(); } exit: 

or

 while(true) { if (condition1) { something(); return; } if (condition2) { somethingDifferent(); return; } mostOfTheWork(); } 

And if you refuse to use any flow control other than if and while, how about this:

 bool ok = true; while(ok) { if (condition1) { something(); ok = false; } if (ok && condition2) { somethingDifferent(); ok = false; } if (ok) { mostOfTheWork(); } } 

Also, see my canonical answer to this question (and vote for it!)

0
source

Source: https://habr.com/ru/post/1305891/


All Articles