Qual é o termo para o loop "while (true)" com "break" por dentro? [fechadas]

24

Suponha que eu tenha um loop em C ++ ou C # que seja assim:

while( true ) {
    doSomething();
    if( condition() ) {
        break;
    }
    doSomethingElse();
}

Isso é comumente chamado de "loop infinito". No entanto, não é tecnicamente infinito - ele irá parar quando o controle fluir break.

Qual é o termo para esse loop - que possui uma declaração de controle de loop "loop para sempre" e "quebra" dentro?

dente afiado
fonte
22
Eu não acho que exista um termo especial.
ChrisF
2
Existe alguma garantia de que o controle fluirá através do intervalo? Nesse exemplo, e se condition()sempre retornar falso? Eu diria que é um loop infinito com quebras condicionais.
precisa saber é
11
Mesmo sem a break, o loop não é infinito ( kill, ctrl-alt-del, desconecte ...). Então, por que se preocupar com os detalhes da terminologia?
Mouviciel
5
"Qual é o termo?" - "Isso é comumente chamado de loop infinito". Essa é a sua resposta aqui. Você claramente não está satisfeito com o termo, mas isso não tira o fato de que as línguas (naturais) são descritivas. O "termo para X" é o que as pessoas estão usando, não o que deveriam estar usando.
MSalters
5
Esta pergunta parece estar fora do tópico, porque é uma pergunta "nomeie essa coisa". "Nomeie essa coisa" são perguntas ruins pelas mesmas razões que "identificam esse obscuro programa de TV, filme ou livro por seus personagens ou história" são perguntas ruins: você não pode pesquisá-las no Google, elas não são práticas de forma alguma, elas não ajude mais ninguém, e permitir-lhes abre a porta para a realização de outros tipos de perguntas marginais. Veja blog.stackoverflow.com/2012/02/lets-play-the-guessing-game
mosquito

Respostas:

24

Estudando CS, esse professor nos ensinou que existem loops de verificação prévia ( while(cond) {}), loops de verificação posterior ( do {} while(cond);) e loops de verificação média . (Talvez eu tenha traduzido mal para o inglês, mas você entendeu.)

C e C ++ não possuem o último (ISTR Ada, BICBW); portanto, sua construção é usada para isso em C e C ++.

sbi
fonte
11
Sim, Ada tem o seguinte:loop ... exit when condition; ... end loop;
Keith Thompson
@ Keith: Obrigado por confirmar! Faz quase 20 anos desde que fiz Ada.
SBI
11
Pelo que vale, sou programador profissional há mais de 20 anos (e um hobby por mais tempo do que isso) e nunca ouvi esses termos.
offby1
Em relação à tradução - acho que "in" geralmente é mais adequado quando "pré" e "post" são usados, por exemplo, "pré-encomenda / pós-encomenda / passagem de árvore inorder".
Oak
11
O termo com que cresci foi "loop de saída intermediária". Eu trabalhei em dois idiomas diferentes, com suporte explícito para loops no meio da saída.
mjfgates
13

O primeiro curso de CS em Stanford ( Metodologia de Programação por Mehran Sahami ) refere-se a isso como um ciclo e meio . E não é necessariamente uma prática ruim de programação. Considere este exemplo ao coletar informações do usuário (extraídas de The Art and Science of Java de Eric Roberts , onde Roberts também o chama de loop e meio ):

prompt user and read in the first value
while (value != sentinel) {
    process the data value
    prompt user and read in a new value
}

E então a mesma coisa resolvida usando a idéia de loop e meio para evitar código duplicado:

while (true) {
    prompt user and read in a value
    if (value == sentinel) break;
    process the data value
}
ernes7a
fonte
10

Na falta de um nome oficial, eu o chamaria de Broken Loop . A ambiguidade deste termo é pretendida, uma vez que uma interrupção no meio de um loop é um pouco impura, quase como a goto.

user281377
fonte
Eu diria, muito pior do que ir. Eu prefiro ver um goto do que uma condição falsamente construída em um loop como esse.
Brian Knoblauch
14
@Brian What? A condição 'verdadeira' torna isso óbvio e loops como esse são realmente comuns. Por exemplo, se você quiser adicionar todas as linhas de um arquivo a uma lista, tente ler a linha (faça alguma coisa), pare se falhar (se a condição quebrar), caso contrário, adicione-a à lista e repita (faça algo outro).
Craig Gidney
7
Não há nada errado com a pausa no meio de um loop. Se você precisar executar alguma operação em cada início do ciclo, será necessário duplicar o código ou inserir essas operações na condição. Qualquer uma das variantes tem claramente desvantagens. gototambém tinha aplicativos válidos, por exemplo, emulação de uma tentativa ... finalmente bloqueia C.
Malcolm
11
Malcolm: O possível problema é que, durante a leitura do código, é mais difícil ver quando e por que o loop foi encerrado. Problemas adicionais surgem quando você aninha dois ou mais desses loops e deseja interromper o loop externo com base em uma condição encontrada no loop interno.
User281377
Vamos dizer que você tem um ciclo de eventos conduzindo uma aplicação Xorg, como (em pseudo-código :) while(XEventGet(&ev) != NULL){ ... }, você vai naturalmente querer verificar as chaves dentro do loop: if(ev.key == XK_q) break;. Fazer o seguinte while(XEventGet(&ev) != NULL && ev.key != XK_q){ ... }:, é feio e sem dúvida mais difícil de ler do que uma pausa no meio do ciclo. Além disso, e se algo precisar ser feito primeiro com o valor antes que possa ser verificado? Você não está seriamente colocando tudo isso no caso base do loop, não é?
Braden Best
8

Não existe um nome definitivo. Loop infinito é, penso eu, o termo apropriado. Nenhum loop é verdadeiramente infinito, mas isso tem o potencial de ser efetivamente infinito, pois é possível que o ramo que contém a interrupção nunca ocorra.

Se você disser a alguém "crie um loop infinito e use uma pausa para a condição X", eles saberão o que você quer dizer. Se alguém estiver revisando seu código e disser nada mais do que "Não gosto do loop infinito que você escreveu", saberá do que eles estão falando (a menos que você tenha mais de um, é claro).

Bryan Oakley
fonte
11
Não é um loop infinito; ele tem uma condição de finalização bem definida, assim como um whileloop normal e a maneira como você faz a prova de finalização é exatamente a mesma (encontrar uma métrica monotonicamente decrescente é um ótimo começo).
Donal Fellows
8

É um loop do-while com o condicional no lugar errado.

Malfist
fonte
2
Sim, deve estar escrito: while (keep_going) {doSomething (); if (condição) {keep_going = false; } else {doSomethingElse (); }}
Stephen Gross
10
então ... você está dizendo que, se estiver ministrando um curso de informática e quiser descrever isso, diria "e agora, vamos aprender sobre o loop * do-while com a condicional no lugar errado "? Isso parece mais uma opinião religiosa do que um nome.
Bryan Oakley
5
@StephenGross Esse trecho de código é uma sugestão horrível. Refatorar para colocar a condição real na definição de loop, ou apenas use breakou continue. Evite os valores das sentinelas a todo custo, eles são apenas mais um pedaço de estado arbitrário para acompanhar mentalmente, que disfarça o objetivo do código.
Izkata
2
Os valores sentinais são gotos atrasados.
Winston Ewert
2
-1 por ser um weenie de saída única.
Donal Fellows
6

Eu votaria em "loop incondicional" , semelhante ao "salto incondicional". Ele ilustra exatamente o que está acontecendo (o código faz um loop incondicionalmente), sem mentir (ao contrário de "loop infinito").

tdammers
fonte
11
Mas ele tem uma condição de terminação; que if/ breakno meio faz parte do padrão.
Donal Fellows
5

Qual é o termo para esse loop - que possui uma declaração de controle de loop "loop para sempre" e "quebra" dentro?

É um loop infinito com uma condição de interrupção.

Eu concordo com ammilind que, se você quisesse dar um nome especial, poderia chamá-lo de Loop Parcial Infinito

Ramhound
fonte
11
Não é infinito; o ponto em que a condição de término é verificada está apenas em um local diferente.
Donal Fellows
5

No Código Rosetta, esse padrão específico é descrito como um loop "N mais meio" . Embora não seja meu termo favorito, não é terrível e é claramente um padrão útil para alguns tipos de loops. (As alternativas são duplicar o código antes da condição - potencialmente complicado em programas reais - ou aumentar a profundidade de aninhamento do código após a condição ao adicionar uma variável de condição de loop; nem melhorar a manutenção ou a compreensibilidade do código A única razão para rejeitar tais construções é se alguém insistir em escrever loops para ser breaklivre.)

Donal Fellows
fonte
4

Não existe um termo padrão, mas eu diria isso como loop parcial .

Este loop é usado quando você deseja interromper apenas após executar uma parte do loop uma última vez (ou seja, execução parcial). É usado quando você não encontra uma situação adequada em que possa quebrar o loop inteiro .

Nesse caso, você deseja interromper o loop depois de executar pelo menos doSomething()uma última vez.

iammilind
fonte
2

Eu tenho que concordar com o sbi aqui - eu gosto do termo do loop de verificação do meio . Esse tipo de construção era mais popular quando a Programação Estruturada começou a rolar e muitos idiomas tinham suporte sintático para eles.

Dito isso, agora é amplo o conhecimento de que os whileloops são geralmente mais sustentáveis, já que é mais fácil argumentar sobre invariantes e eles geralmente lidam melhor com o caso vazio complicado.

No seu caso particular, seu loop é apenas equivalente a

for(; doSomething(), !condition(); doSomethingElse()){}

então eu só iria usar a breakversão se quer doSomethingou doSomethingElseenvolvidas várias instruções e eu prefiro não guardá-los em funções distintas como você fez.

Dito isto, se seu loop for mais complicado do que uma iteração (iniciar, verificar, incrementar), considere refatorá-lo para algo mais simples.

hugomg
fonte
1

Acho que se tentarmos criar um termo para isso, talvez:

Loop Escapável

LarsTech
fonte
-1. a questão não é criar um nome, é se um nome comum já existe. Além disso, todos os loops são "escapáveis", por isso não é um nome particularmente eficaz.
Bryan Oakley
@BryanOakley Um loop infinito, por definição, não deve ser quebrável. Provavelmente não deveria haver um termo para isso, exceto programação ruim.
LarsTech
0

Não é tão ruim em todos os casos. Eu me pego escrevendo esse tipo de loops com certos tipos de APIs. Digamos, por exemplo, que você tenha um objeto de loop e precise verificar se há alguma condição profunda, como:

while (loop
    .getAExecutionModelFactory()
    .getActiveXexecutor()
    .getYCancelModelHandler()
    .getCurrentHandler()
    .isCancelled()) {
        // ... do something with the current Handler ....
        loop = ..... // prepare for next loop
}

Agora, suponha que todo método getXXX possa retornar nulo. Ainda seria possível escrever uma expressão booleana, embora bastante complicada e ilegível. E então temos que refazer quase o mesmo para obter o objeto manipulador atual. Nesses casos, acho mais fácil escrever um while (true)loop com pausa e continuar.

Ingo
fonte