I believe this question is a duplicate to this one, answered robustly by @Micahel Burr :
Many answers seem to focus on the ability to fall through as the reason for requiring the break statement.
I believe it was simply a mistake, due largely because when C was
designed there was not nearly as much experience with how these
constructs would be used.
Peter Van der Linden makes the case in his book "Expert C
Programming":
We analyzed the Sun C compiler sources to see how often the default
fall through was used. The Sun ANSI C compiler front end has 244
switch statements, each of which has an average of seven cases. Fall
through occurs in just 3% of all these cases.
In other words, the normal switch behavior is wrong 97% of the time.
It's not just in a compiler - on the contrary, where fall through was
used in this analysis it was often for situations that occur more
frequently in a compiler than in other software, for instance, when
compiling operators that can have either one or two operands:
switch (operator->num_of_operands) {
case 2: process_operand( operator->operand_2);
/* FALLTHRU */
case 1: process_operand( operator->operand_1);
break; }
Case fall through is so widely recognized as a defect that there's
even a special comment convention, shown above, that
tells lint "this is really one of those 3% of cases where fall through
was desired."
I think it was a good idea for C# to require an explicit jump
statement at the end of each case block (while still allowing multiple
case labels to be stacked - as long as there's only a single block of
statements). In C# you can still have one case fall through to another
- you just have to make the fall thru explicit by jumping to the next case using a goto.
It's too bad Java didn't take the opportunity to break from the C
semantics.