Should you use break in for?

18

I have a question about the ties of repetition. I had a class where my teacher said that you should never use for if you do not run it from start to finish.

I've seen many, many codes using this repeat structure containing a break in the middle to stop.

Is this wrong? What's the problem of wanting to iterate over a list and in case you find what you want, stop?

I commented this with him and he says that in these cases, I should not use for because it would not be an elegant solution / strategy.

Does this apply? In cases where I have to stop the loop in the middle, I should either while or while and only use for for cases that I will process all elements from x to N?

    
asked by anonymous 24.09.2015 / 16:38

4 answers

16

I do not know if he's talking about some specific language. I will speak in general terms.

Some people are dogmatic.

It even makes sense for this option. Semantically% w / w% would indicate that you want to go from one point to another and there should be no interruptions. Some people will say that if there is to be an interrupt then use for . It seems to me a preciosismo that does not give any advantage. Certainly no technique. At most the idea goes that it can stop at any time and I do not have to go to the end as specified in while . This is if everyone involved with the code follows this rule.

There is no mistake in this. But if you work on a team (your class is your team right now) and she says you should follow this rule. Follow her. Not without question, of course. How are you doing. This is good. But if you do not have a problem following the established rule and "everyone" agrees with it, do not be different.

Elegance depends a little on taste. Some things are universal, some are not. For my taste I would not blindly follow it. It could be that some case I chose a construction or another one for other reasons but hardly by this presented.

Even the performance could make me choose one or the other in some specific situations.

Looking at OnoSendai's answer, something came to mind. If you make a for that goes from start to finish. Then one fine day needs to change the implementation and find a situation that needs to have an interruption in a given situation. Would you be "forced" to change for to for ? For what? It can do, but it does not seem necessary to me, something that will add something to the clarity of the code. On the contrary. I think in some cases using% w / w when sweeping a sequence, even if it can be stopped, may even make it less clear that this is indeed true. I think less clear, but not less, would also not strongly oppose this change. The code would still be clear enough.

Reasons to choose one of the two

A good reason to opt for while is when the control variable will be used outside the loop.

Perhaps the main advantage of while over while is precisely to encapsulate the control variable in the scope of the loop. If you do not need this, for loses strength.

If you do not initialize the variable outside of the loop, the condition that the while has has, and the step to be executed on each repetition.

This step is already criticized by some people since it is written at the beginning of the loop but only runs at the end of it. Remembering that the condition is executed in the beginning.

Of course, it's okay to declare and / or initialize the variable outside the loop, but use a for . It only has fewer advantages.

And it's good to remember that there are languages that do not have an internal block scope in the code of a function, so that does not make any difference to them.

But the big reason for choosing one of the two constructs is just when there will be interruption of the normal flow but still inside the loop. How do I want the step to be executed if there is a jump to the end of the loop? Do you want it to always run or should the skip be omitted if there is a jump? Example:

for (i = 0; i < 10; i++) {
    ...
    if (condiçao) {
        continue;
    }
    ...
}

The while will be incremented even if it enters for and the flow is bypassed. Already:

i = 0;
while(i < 10) {
    ...
    if (condiçao) {
        continue;
    }
    ...
    i++;
}

You will skip the increment of i when you enter if . This is a semantic change that produces a very different result. And it is not easy to simulate this using the wrong construction. Some people may try and cause more problems, even a race condition .

Has the teacher talked about this? If not, I hope you'll talk in the next class, because this is key to knowing about choosing one or the other building. This has real practical implications in the code.

Avoid interruptions

The mgibsonbr answer speaks well of this. Ideally, you should not have i or even if . This is break and everyone knows that continue is from the devil (please read my answer in link to understand sarcasm).

Well, it's a better way to goto and although we try to avoid this type of construction, we should not do this at any cost. If you are going to write a convoluted code, it is preferable for goto or goto , or even break in much rarer cases and make the code clearer.

The same goes for a continue which is a goto more aggressive. And using return , even within a loop, is not a bad thing .

    
24.09.2015 / 16:48
9

Strictly speaking, does not proceed . In several real situations you have objects that can change state during the execution of a loop, and the treatment can induce an assessment that the loop is no longer necessary or valid - the loop interruption being the most desired attitude. p>

Another factor would be performance. In C #, for example, language control mechanisms can cause a loop for is more performative than while .

    
24.09.2015 / 16:46
8

Stopping a loop in the middle (any loop, not just for ) has a drawback that is making it more difficult for the programmer to understand what state the program is in. Regardless of the construction employed, this problem exists. Sometimes it's inevitable, but when you can structure your code to make it clearer to human readers, it's worth doing.

As for for , I would break its use in two cases basically:

  • The control variable of for is unique to it, not being used anywhere else.

    Example:

    for ( int i = 0 ; i < lista.length ; i++ ) {
        ...
        if ( condição )
            break;
    }
    

    What will be the value of i at the end of the loop? Now that is irrelevant! No one will use i out of the loop, in fact depending on the language i nor will there be more at that moment. So the use of break does not get in the way of understanding the code.

  • The control variable of for is used more than once, perhaps even for more than one loop.

    Example:

    // Remove um elemento de uma lista
    int indice;
    for ( indice = 0; indice < alvo ; indice++ )
        destino[indice] = origem[indice];
    for ( indice++ ; indice < origem.length ; indice++ )
        destino[indice-1] = origem[indice];
    

    In this case, if the first for had a break , what would be the value of indice after its end? It could be anyone, and you would have to program very carefully not to presume an incorrect value. Note that the for stop condition does not help you, since the value of indice would not necessarily be equal to alvo at the end of the first loop, nor equal to origem.length at the end of the second.

    Would using a while in this case help? Little - you still would not know the exact state of indice after each loop. Whether or not it is useful depends on the programmer's expectations when reading the code. If you already expect a while to contain break s, but do not expect it to for , then you'll pay more attention to that detail if a while is used. Otherwise, it makes no difference ...

  • The ready key is to adjust the expectations of who is reading your code to what the code actually does. If everyone agrees to a convention, then the best thing to do is follow it, or at least document each time you deviate from that convention (for good reason, preferably). After all, it makes no difference to drive from the left or from the right, as long as everyone drives on the same side ...;)

        
    24.09.2015 / 17:04
    4

    Maybe it depends on the language. But that would be more a matter of good practice recommended by your teacher, than having a "right" and "a wrong." I say this because there are people who use affirmations like "you can not do that."

    There are cases of languages such as Python , for example, where we can use for for other types of iterations (like lists, objects, generators), which is not common in other languages. >

    An expression that returns an infinite generator, for example, might require the use of a break to terminate this infinite loop.

    In other cases, in languages such as PHP , where we can use foreach to iterate with array or Iterator , there is no need to use for .

        
    24.09.2015 / 17:20