Muitas respostas parecem focar na capacidade de cair como o motivo para exigir a break
declaração.
Acredito que foi simplesmente um erro, devido em grande parte porque quando C foi projetado, não havia quase tanta experiência com a forma como essas construções seriam usadas.
Peter Van der Linden defende seu livro "Expert C Programming":
Analisamos as fontes do compilador Sun C para ver com que frequência a falha padrão foi usada. O front end do compilador Sun ANSI C possui 244 instruções de opção, cada uma com uma média de sete casos. A queda ocorre em apenas 3% de todos esses casos.
Em outras palavras, o comportamento normal da troca está errado 97% das vezes. Não é apenas em um compilador - pelo contrário, onde o fall through foi usado nessa análise foi geralmente para situações que ocorrem com mais frequência em um compilador do que em outro software, por exemplo, ao compilar operadores que podem ter um ou dois operandos :
switch (operator->num_of_operands) {
case 2: process_operand( operator->operand_2);
/* FALLTHRU */
case 1: process_operand( operator->operand_1);
break;
}
A queda de casos é tão amplamente reconhecida como um defeito que até existe uma convenção de comentário especial, mostrada acima, que diz ao fiapo "este é realmente um daqueles 3% de casos em que a queda foi desejada".
Eu acho que foi uma boa ideia para o C # exigir uma instrução de salto explícita no final de cada bloco de caso (enquanto ainda permite que vários rótulos de caso sejam empilhados - desde que haja apenas um único bloco de instruções). No C #, você ainda pode fazer com que um caso caia para outro - você só precisa tornar explícita a queda saltando para o próximo caso usando a goto
.
É uma pena que o Java não tenha aproveitado a oportunidade para romper com a semântica C.
De várias maneiras, c é apenas uma interface limpa para idiomas de montagem padrão. Ao escrever o controle de fluxo acionado por tabela de salto, o programador tem a opção de cair ou saltar da "estrutura de controle", e um salto exige uma instrução explícita.
Então, c faz a mesma coisa ...
fonte
NULL
. (Continua no próximo comentário.)NUL
seqüências de caracteres terminadas são a pior idéia de todas.DO
loop Fortran .Para implementar o dispositivo de Duff, obviamente:
fonte
Se os casos foram projetados para serem quebrados implicitamente, você não pode ter sucesso.
Se o switch foi projetado para ocorrer implicitamente após cada caso, você não teria escolha. A estrutura da caixa do switch foi projetada da maneira que deve ser mais flexível.
fonte
As instruções de caso em uma instrução switch são simplesmente rótulos.
Quando você ativa um valor, a instrução switch efetivamente vai para o rótulo com o valor correspondente.
Isso significa que a interrupção é necessária para evitar a passagem para o código no próximo rótulo.
Quanto ao motivo pelo qual foi implementado dessa maneira - a natureza de falha de uma instrução switch pode ser útil em alguns cenários. Por exemplo:
fonte
break
onde é necessário. 2) Se as instruções do caso tiveram sua ordem alterada, a queda pode resultar na execução do caso errado. Portanto, acho o manuseio do C # muito melhor (explícitogoto case
para falhas, exceto para rótulos de casos vazios).break
em C # - a mais simples é quando você não quercase
fazer nada, mas se esqueça de adicionar umbreak
(talvez você tenha ficado tão envolvido no comentário explicativo ou tenha sido chamado por algum motivo) outra tarefa): a execução cairá apenas para ocase
abaixo. 2) encorajargoto case
é encorajar a codificação "espaguete" não estruturada - você pode terminar com ciclos acidentais (case A: ... goto case B; case B: ... ; goto case A;
), especialmente quando os casos são separados no arquivo e difíceis de grok em combinação. No C ++, o fall-through é localizado.Para permitir coisas como:
Pense na
case
palavra - chave como umgoto
rótulo e ela será muito mais natural.fonte
if(0)
no final do primeiro caso seja ruim, e só deve ser usado se o objetivo for ofuscar o código.Elimina a duplicação de código quando vários casos precisam executar o mesmo código (ou o mesmo código em sequência).
Como no nível da linguagem assembly, não importa se você quebra entre eles ou não existe zero de sobrecarga para os casos de qualquer maneira, por que não permitir isso, pois eles oferecem vantagens significativas em certos casos.
fonte
Por acaso, me deparei com um caso de atribuição de valores em vetores a estruturas: tinha que ser feito de tal maneira que se o vetor de dados fosse menor que o número de membros de dados na estrutura, o restante dos membros permaneceria em seu valor padrão. Nesse caso, omitir
break
foi bastante útil.fonte
Como muitos aqui especificaram, é para permitir que um único bloco de código funcione para vários casos. Isso deveria ser uma ocorrência mais comum para as instruções do switch do que o "bloco de código por caso" especificado no seu exemplo.
Se você tiver um bloco de código por caso sem falhas, talvez considere usar um bloco if-elseif-else, pois isso pareceria mais apropriado.
fonte