Eu tenho esse professor, ele é bastante inteligente (às vezes, haha), ele disse que bons programadores tentam usar while
loops em vez de for
loops. a razão que ele deu para isso é porque os while
loops podem ser comprovados, como em, pode-se explicar completamente o que acontece em um while
loop, enquanto você não pode fazer isso para um for
loop. ele também disse algo sobre os programadores da NASA que usam apenas while
loops e não têm permissão para fazer for
loops por causa disso.
Eu tenho dificuldade em entender isso, pois ambos os loops podem ser explicados como eles funcionam em detalhes, certo? para ambos, você sempre saberia o que vai acontecer?
alguém pode me explicar por que os while
loops podem ser comprovados (e, por isso, pode ser melhor do que os for
loops, pelo menos em alguns casos).
EDIT:
talvez ele estivesse se referindo a:
2: Todos os loops devem ter um limite superior fixo. Deve ser trivialmente possível para uma ferramenta de verificação provar estaticamente que um limite superior predefinido no número de iterações de um loop não pode ser excedido. Se o limite do loop não puder ser provado estaticamente, a regra será considerada violada.
Embora isso ainda não diga nada sobre a diferença entre while e for loops.
for
ao invés dewhile
simplesmente não faz sentido. Pode haver um, mas não é isso.for (init; test; step) { body }
tem um Dessacarificação trivialwhile
:{init; while (test) { step; body }}
.Respostas:
Em poucas palavras : o que seu professor provavelmente quis dizer é que a semântica de
while
é praticamente a mesma na maioria dos idiomas, enquanto a semântica defor
pode mudar consideravelmente (veja a discussão abaixo). Portanto, a prova independente da linguagem abstrata é mais confiável com awhile
, mas é preciso ter cuidado para que uma prova com umfor
loop possa não corresponder à semântica dofor
loop em muitos idiomas.Sua pergunta não é precisa o suficiente (embora isso possa não ser sua culpa).
O ponto é que, depois, não existe um padrão oficial suportado pela ISO ou outra definição de referência
for
ewhile
loops oficialmente aceitos . A definição depende da linguagem de programação.Portanto, você não pode fazer nenhuma declaração geral sobre sua equivalência antes de definir com precisão o que cada um pode fazer. Abordo isso com mais precisão, já que é um dos principais argumentos usados em outras respostas (e a discussão será útil a seguir).
Sobre intertranslatabilidade de
for
ewhile
loopsResumo : depende da linguagem de programação, mas sempre é possível desde que você possa ter um loop infinito e uma maneira de sair dele.
Mas você pode fazer essa afirmação para uma linguagem de programação específica, e a resposta dependerá dos recursos da linguagem.
Isso também significa que não há provas gerais, mas apenas uma para cada linguagem de programação.
Uma coisa que geralmente é verdadeira é que um
while
loop geralmente pode imitar umfor
loop, porque o loop while pode fazer o teste da condição de saída do loop for, fazendo a inicialização da variável de controle com uma atribuição antes de entrar no loop e fazendo a incrementação no final do corpo do loop, para quetorna-se
Isso funciona mais ou menos para a maioria dos idiomas, mas não é tão óbvio quanto parece, e pode haver muitos "detalhes" com que se preocupar.
Por exemplo, em muitos idiomas, o
for
loop avalia três argumentos (valor inicial, incremento e valor final) como argumentos estritos , avaliados uma vez antes de entrar no loop, enquanto outros consideram argumentos thunk para serem reavaliados a cada turno, ou possivelmente como argumento preguiçoso para ser avaliado apenas quando necessário.Outro ponto pode ser que a variável de incremento possa ser local para o
for
loop ou precise ser uma variável local da função em que o loop aparece.Dependendo de tais questões, a tradução de a
for
para awhile
pode variar muito, embora seja geralmente possível alcançá-la.O mesmo vale para o inverso, traduzindo um
while
para umfor
loop.O primeiro problema é que um
while
loop sempre reavaliará a condição de saída a cada turno. Mas algunsfor
loops não fornecem uma condição que é reavaliada a cada turno, exceto a comparação da variável de controle com algum valor fixo calculado na entrada do loop. Portanto, a tradução não é possível, a menos que haja outro meio de sair do loop em algumas condições arbitrárias.Isso é possível com vários dispositivos, geralmente começando com uma instrução condicional testando a condição, seguida de um salto implementado, conforme disponível, por uma instrução de saída do loop, uma instrução de retorno (depois de encapsular o loop em uma função), uma instrução goto ou um aumento de exceção.
Em outras palavras, é novamente muito dependente de idiomas e, possivelmente, de recursos sutis dos idiomas.
Dito isto, como respondido por @milleniumbug , a intertradução é fácil na linguagem C, porque um
for
lopp é essencialmente umwhile
loop mais alguns extras para uma variável de controle incrementada.Mas isso não se aplica necessariamente a outros idiomas e, provavelmente, não da mesma maneira.
Dito isto, as linguagens de programação geralmente têm poder de Turing com apenas um desses loops, pois tudo o que você precisa é de um loop infinito. Portanto, desde que você tenha alguma maneira de repetir para sempre e possivelmente decidir parar, você tem certeza de que pode imitar qualquer outra construção ... mas não necessariamente facilmente.
Em relação às provas
Resumo : Não há razão para mim afirmar que as provas devem ser significativamente mais difíceis com uma ou outra (a menos que haja algum recurso estranho da linguagem).
Provavelmente há um mal-entendido, ou seu professor estava pensando em outra coisa.
A semântica de elementos formais pode ser definida para os vários tipos de loops definidos nas linguagens de programação e, em seguida, usada para provar propriedades.
Pode ser, novamente, dependendo do idioma, que a realização de provas formais sobre os programas possa ser mais complexa em alguns casos. Mas isso depende do idioma.
Não consigo imaginar uma razão pela qual as provas devam ser significativamente mais difíceis com um construto do que com o outro. O
for
loop pode ser mais complexo, pois pode oferecer, como em C, tudo o que é feito comwhile
outras coisas. Mas se você fizesse isso com awhile
, teria que adicionar os extras de alguma outra forma.Eu poderia usar o argumento geral formal de intertraduzibilidade, desde que haja a possibilidade de um único loop infinito. No entanto, evitarei fazer isso, pois as construções envolvidas não são nada com que você queira lidar com uma prova e seria claramente uma afirmação injusta, pelo menos na prática.
Após a discussão acima, no entanto, vimos que as dificuldades para a intertradução resultam da grande variabilidade do
for
loop de linguagem para linguagem. Daí a seguinte conclusão, que provavelmente é a resposta certa:Uma possibilidade de entender a afirmação do professor é que a semântica do
while
loop é praticamente a mesma em todas as linguagens de programação, enquanto a sintaxe e a semântica dofor
loop podem variar significativamente de idioma para idioma. Portanto, é possível fazer provas "abstratas" gerais comwhile
loops que tenham uma semântica independente da linguagem em boa medida, enquanto isso não é possível para ofor
loop que tem sintaxe e semântica mudando muito de idioma para idioma. Mas isso não se aplica a um determinado idioma, quando a semântica de ambos é definida com precisão.Minha melhor sugestão é que você pergunte ao seu professor o que ele quis dizer com precisão e se ele pode lhe dar um exemplo. Erros de interpretação ou mal-entendidos são um evento comum.
fonte
Na linguagem C, você pode reescrever cada
for
loop em umwhile
loop equivalente e vice-versa.while -> for
transformação:Reescrever
para
for -> while
transformação:Isso é um pouco mais complicado, especialmente se você tiver uma
continue
declaração no seu loop.Reescrever:
para:
mas substitua toda
continue;
declaração porgoto next_label;
declaração. Secondition
for uma instrução nula, substitua-a portrue
.Como você pode ver, na linguagem C, nenhum dos dois é mais "provável" (o que quer que isso signifique) do que o outro, pois, mesmo que um dos loops fosse, você poderia reescrevê-lo em termos de outro loop.
Agora, existem outros idiomas onde essa
while <-> for
equivalência não existe. Por exemplo, em Pascal, você pode assumir mais informações sobre ofor
loop. Isso significa que você não pode expressar todos os conceitos ao escrever umfor
loop, mas pode provar mais sobre o fluxo do código:Aqui, o
n
é salvo no início do loop, para que as alteraçõesn
não influenciem a iteração e você não possa modificari
no corpo do loop. Isso significa que você pode provar trivialmente que esse loop acabará eventualmente (comon
é finito e não pode ser modificadoi
).fonte
goto
. Se adicionarmos sinalizadores, todos os outros loops poderão ser emulados usando um único "while (1) ..." em torno de uma função que será executada até um "retorno"; se adicionar "goto", todos os outros loops podem ser emulados usando isso.Na lógica de Floyd-Hoare , o sistema formal mais comum de raciocínio sobre a correção de programas de computador, existe a regra while .
Em palavras, se você tiver uma cláusula de guarda (a expressão entre colchetes no
while()
), uma função variante (uma expressão com valores discretos que podem ser mostrados para diminuir monotonicamente toda vez que o loop for executado e sempre seja positivo) e um loop invariável (uma declaração lógica que sempre é verdadeira antes e depois de cada vez que o loop é executado), você pode provar que o loop while terminará (porque a função variante não pode continuar diminuindo) e que, eventualmente, a cláusula guard será falsa e o loop invariável seja verdadeiro.A lógica de Floyd-Hoare não possui regras para
for
loops ou quaisquer construções que as linguagens reais possam ter.No entanto, como outras respostas explicam, os loops sempre podem ser escritos em termos de while. Isso significa que eles podem ser fundamentados, basta um pouco mais de trabalho.
Se o seu professor teve cursos na universidade, onde ele teve que fornecer provas de correção de seus programas, ele provavelmente escreveu programas usando apenas loops. Eu sei que sim. E uma vez que você está acostumado a pensar em termos de guardas, funções variantes e invariantes de loop, eles parecem muito naturais. O uso excessivo de loops é um hábito que você vê com os graduados em CS, tive que aprender a parar de fazer isso nos meus primeiros meses como desenvolvedor profissional.
Em algum momento, seu professor se lembrou de tudo isso como "bons programadores usam loops", enquanto o que realmente acontece é mais como "alguns graduados em informática transformam seus hábitos de correção em hábitos práticos de programação".
fonte
for
loop, que não tem definição fixa e é mais complexo, sem ser formalmente necessário.Na verdade, em certo sentido, o exato oposto é verdadeiro.
Um idioma com apenas
for
loops não é completo em Turing, apenas pode calcular as funções primitivas-recursivas, nem todas as funções computáveis em Turing. Como todo o cálculo em uma linguagem com apenasfor
loops sempre termina, o Problema da Parada e todos os outros Problemas de Decidibilidade com base nele simplesmente não surgem, portanto, é possível decidir mecanicamente muitas propriedades estáticas dos programas do que em uma linguagem comwhile
-rotações.OTOH, uma linguagem com apenas números naturais, uma única variável e
while
-loops é Turing-complete e, portanto, não é possível decidir nem a mais simples das propriedades: este programa retornará um resultado?fonte
for
linguagem apenas pode produzir umwhile
comportamento equivalente, diminuindo a variável do loop (assumindo que a linguagem permita) durante iterações que não deveriam resultar em terminação. (Por exemplo,for n in 1 to 2 { if condition then n := n-1 }
)Gostaria de dizer que, na realidade, não há diferença. Sua pergunta é irrelevante. Pode ser que seu professor pretenda usar o loop while, quando não. de iterações não é conhecido de antemão. Em muitos casos, precisamos usar um loop while para extrair dígitos de um não. quando o usuário digita o não. que pode ter qualquer comprimento. Tecnicamente falando, a semelhança entre o loop for & while é que ambos são loops com controle de entrada em que a (expressão / condição de teste) é avaliada antes de entrar no corpo do loop. Essa é a distinção entre loops while & do-while.
fonte
Provavelmente, vem da programação C inicial, na qual, pelas normas atuais, os loops foram amplamente abusados e mal utilizados, especialmente a modificação condicional. Quando os programadores começaram a entender o efeito que certos estilos de programação tiveram, o abuso e o uso indevido de condicionais de loop caíram em desuso, e a afirmação, embora (indiscutivelmente) uma vez válida, já não é verdadeira.
A afirmação não tem absolutamente nenhuma verdade se você olhar apenas para a definição e sintaxe da linguagem e ignorar como ela estava sendo usada.
A declaração em si, no entanto, oferece uma lição valiosa para quem quer entendê-la, sua história e por que não é mais considerada verdadeira. - Qual é a expressão sobre aprender, errar e repeti-los .....
fonte
Seu professor está correto!
O motivo é o seguinte é C válido
Você não pode garantir que as variáveis de condição não foram violadas!
fonte
while
loops se saiam melhor aqui?while
loops, você pode realmente garantir que a variável de condição não foi adulterada? De fato, adulterar a variável de condição é a única maneira de sair de umwhile
loop! Eu geralmente evito fazer votos negativos, mas para esta resposta, farei uma exceção.