15

My Software Engineering teacher just said: "Avoid using continue and break, always make it work without using these". Is there a problem with these instructions? I would say he didn't say something so coherent, but maybe I don't know something about it?

Shi Nha
  • 181

5 Answers5

44

Some teachers oversimplify on this topic (especially when they only teach, but don't do daily real-world programming any more). Of course, I don't know if that applies to your teachers, but I would not listen to the advice against continue and break too literally.

continue and break can make loops more readable or less readable, depending on how they are used. The real problem are loops with too large inner bodies and many conditions for stopping them or executing only parts. Having multiple continue and break in such a loop is only a symptom for this "disease", but working around those keywords just formally isn't the cure.

If running into such a situation, one could try to avoid the mentioned keywords by using boolean flags and complex if/else blocks instead, but that will not make the code simpler. Quite the opposite - often it will become even uglier.

So what is the cure?

  • Refactor inner parts of large loops into smaller functions. These functions might return some status information which can be used to control the outer calling loop, and it can be perfectly fine to use break or continue controlled by the returned status. If the functions are still complex, decompose them to smaller functions themselves.

  • Avoid processing too many things in one loop. Instead, organize your code to process sets of data, which can lead to a sequence of two or three simpler loops instead of one complex one. So there might be one loop which produces some intermediate array of data, then a second one which takes the output of the first loop, iterates over this data and hands the result set to a third. Often, each of these loops can be put into a function on their own, returning its result set, which is passed as a parameter into the next function.

You will be astonished how much much simpler your code will get when you just apply these two guidelines rigorously.

Doc Brown
  • 218,378
19

You've been given some incomplete and oversimplified advice. However, that's not necessarily a bad thing on your teacher's part, as it's nearly impossible to explain the finer nuances of software development practices to newcomers straight out of the gate (without teaching at a snail's pace and boring the students to death).

What your teacher is trying to achieve here is that you learn to write iterations the proper way, without immediately starting to reach for the crutches that continue and break are. It's not that you'll never be allowed to use them as a developer, it's that you are being forbidden from using them right now as a student, specifically so that you learn to write iterations the right way.

It's the equivalent of telling a math student that they can't use a calculator, or an apprentice carpenter that they can't use a nail gun. Not because calculators and nail guns are bad, but because they are a shortcut that causes you to not learn how to do math in your head or create proper fitting wood joints.

Flater
  • 58,824
4

Good programming requires prioritizing a number of principles. Two of those principles are to avoid needlessly using "break" and, especially, "continue", but those principles should be set aside when they would conflict with other more important principles.

When I was first learning to program in the 1970s, a common paradigm was:

Read a record
While last read was successful
  Process a record
  Read a record
End While

Writing the code in this way will ensure that every iteration of the loop will run to completion, which is a desirable principle to uphold, but violates another principle "Don't repeat yourself" by requiring that the instructions to read a record be included twice in the code. I think it's valuable to be able to give priority to different principles depending upon circumstances, even though I think for most purposes today a better pattern would be:

Begin Loop
  Read a record
  If read failed then
    Exit Loop
  End If
  Process a record
End Loop

Thus, for purposes of an academic exercise, writing the loop with the old pattern is useful, even though in most situations the modern approach would be more appropriate.

supercat
  • 8,629
2

Very often the advice for a beginner and for an advanced person is different. In your case: If you ask whether you should avoid continue and break, then you should. Until you are advanced enough to make your own decision.

Important: In following the advice, don't replace continue and break with something worse. Both continue and break can be easily replaced with a goto statement (if your instructor didn't mention goto). That would be 100 times worse. Often break inside a loop can be replaced with a return statement - which is say twice as bad. Often continue or break are the natural way to express your intent, and replacing them makes your code worse.

Where it is excellent advice is when you use break or continue as a convoluted solution to your problem when something else is much easier. For example, if I saw this just at the end of a loop:

if (x == 0) continue;
y = x;

instead of the simple

if (x != 0) y = x;

then get rid of the continue.

gnasher729
  • 49,096
0

One point not already mentioned is that with break, and possibly continue, reasoning formally about/with loop invariants (also on SO) becomes more complicated.

Pablo H
  • 684