Digamos que você tenha o seguinte for
loop *:
for (int i = 0; i < 10; ++i) {
// ...
}
que também poderia ser escrito como:
for (int i = 0; i != 10; ++i) {
// ...
}
Os resultados finais são os mesmos, então existem argumentos reais para usar um sobre o outro? Pessoalmente, eu uso o primeiro caso, i
por algum motivo, dê errado e pule o valor 10.
* Desculpe o uso de números mágicos, mas é apenas um exemplo.
int i = 10; while(i --> 0) { /* stuff */ }
while ((i--) > 0)
Respostas:
A razão para escolher um ou outro é por causa da intenção e, como resultado, aumenta a legibilidade .
Intenção: o loop deve ser executado contanto que
i
seja menor que 10, não contanto quei
não seja igual a 10. Embora o último possa ser o mesmo nesse caso específico, não é o que você quer dizer, portanto não deve ser escrito assim.Legibilidade: resultado de anotar o que você quer dizer é que também é mais fácil de entender. Por exemplo, se você usar
i != 10
, alguém lendo o código pode se perguntar se, dentro do loop, há alguma maneira dei
se tornar maior que 10 e que o loop deve continuar (btw: é péssimo estilo mexer com o iterador em outro lugar que não na cabeça de afor
declaração, mas isso não significa que as pessoas não o façam e, como resultado, os mantenedores esperam).fonte
i
seja "menor que 10", deve ser executado desde que o limite superior (nesse caso) não seja atingido. Ao usar a lógica do intervalo de C ++ / intervalo do iterador, é muito mais lógico expressar isso por meio!=
de<
.<
realmente expressará isso com precisão.for
loop. Usar<
aqui seria bobagem. Além disso, Deckard parece reconhecer isso. Eu concordo muito com o comentário dele em resposta ao meu.!=
O
<
padrão é geralmente utilizável, mesmo que o incremento não seja exatamente 1.Isso permite uma única maneira comum de fazer loops, independentemente de como isso é realmente feito.
fonte
i
modificar o interior do loop de forma totalmente segura, se necessário.<
, como iteradores em uma sequência, e, portanto,!=
seria uma maneira comum de executar loops em C ++.<
padrão porque requer um pressionamento de tecla em vez de dois com o>
padrão e quatro com!=
. É realmente uma questão de eficiência semelhante ao TOC.Em C ++, a recomendação de Scott Myers em C ++ mais eficaz (item 6) é sempre usar o segundo, a menos que você tenha um motivo para não fazê-lo, porque isso significa que você tem a mesma sintaxe para índices iterador e inteiro, para que você possa alternar perfeitamente entre
int
iterador e sem nenhuma alteração na sintaxe.Em outras línguas, isso não se aplica, então acho que
<
é provavelmente preferível por causa do argumento de Thorbjørn Ravn Andersen.By the way, no outro dia eu estava discutindo isso com outro desenvolvedor e ele disse que a razão para preferir
<
mais!=
é porquei
poder incrementar acidentalmente por mais de um, e que pode causar a condição de pausa para não ser cumprida; isso é IMO um monte de bobagens.fonte
<
-se uma programação mais defensiva do que!=
então ...<
é mais defensivo e meus colegas odeiam se eu escrevo,!=
então não escrevo . No entanto, há um caso!=
em C ++ e foi isso que eu apresentei.i++
é quando um loop while é alterado para um loop for. Não tenho certeza de que ter metade do número de iterações seja melhor do que um loop (quase) infinito; o último provavelmente tornaria o bug mais óbvio.Usar (i <10) é, na minha opinião, uma prática mais segura. Ele captura o número máximo de possíveis casos de desistência - tudo que é maior que ou igual a 10. Compare isso com o outro caso (i! = 10); ele só captura um possível caso de desistência - quando eu tenho exatamente 10 anos.
Um subproduto disso é que melhora a legibilidade. Além disso, se o incremento for qualquer outro 1, pode ajudar a minimizar a probabilidade de um problema, se cometermos um erro ao escrever o caso de encerramento.
Considerar:
Embora ambos os casos sejam provavelmente falhos / incorretos, o segundo provavelmente será MAIS errado, pois não será encerrado. O primeiro caso será encerrado e há uma chance maior de que ele seja encerrado no local certo, embora 14 seja provavelmente o número errado (15 provavelmente seria melhor).
fonte
Aqui está outra resposta que ninguém parece ter encontrado ainda.
for
loops devem ser usados quando você precisar iterar sobre uma sequência . Usar!=
é o método mais conciso de indicar a condição de término do loop. No entanto, o uso de um operador menos restritivo é um idioma de programação defensiva muito comum. Para números inteiros, isso não importa - é apenas uma escolha pessoal sem um exemplo mais específico. Fazendo loop nas coleções com iteradores que você deseja usar!=
pelos motivos que outras pessoas declararam. Se você considera sequências defloat
oudouble
, então deseja evitar!=
a todo custo.O que eu queria ressaltar é que
for
é usado quando você precisa iterar em uma sequência. A sequência gerada possui um ponto inicial, um intervalo e uma condição final. Eles são especificados de maneira concisa nafor
declaração. Se você (1) não incluir a parte da etapafor
ou (2) especificar algo comotrue
a condição de guarda, não deverá usar umfor
loop!O
while
loop é usado para continuar o processamento enquanto uma condição específica é atendida. Se você não está processando uma sequência, provavelmente deseja umwhile
loop. Os argumentos da condição de guarda são semelhantes aqui, mas a decisão entre awhile
e umfor
loop deve ser muito consciente. Owhile
loop é subestimado nos círculos C ++ IMO.Se você estiver processando uma coleção de itens (um
for
uso muito comum de loops), deverá realmente usar um método mais especializado. Infelizmente,std::for_each
é bastante doloroso em C ++ por vários motivos. Em muitos casos, separar o corpo de umfor
loop em uma função independente (embora um pouco dolorosa) resulta em uma solução muito mais limpa. Ao trabalhar com coleções, considerestd::for_each
,std::transform
oustd::accumulate
. A implementação de muitos algoritmos se torna concisa e clara quando expressa dessa maneira. Sem mencionar que o isolamento do corpo do loop em uma função / método separado força você a se concentrar no algoritmo, em seus requisitos de entrada e em resultados.Se você estiver usando Java, Python, Ruby, ou mesmo C ++ 0x , então você deve estar usando uma coleta adequada foreach loop. À medida que os compiladores C ++ implementam esse recurso, vários
for
loops desaparecem, assim como esses tipos de discussões.fonte
while
,for
, eforeach
(ou língua equivilant)while
circuito é usado para continuar o processamento até um estado específico é não conheci<
) ou ao operador ser indulgente nos valores que falha (!=
).Usar "menor que" é (geralmente) semanticamente correto, você quer dizer contar até
i
não mais que 10, portanto "menos que" transmite claramente suas intenções. Usar "não igual" obviamente funciona praticamente em casos de chamada, mas transmite um significado ligeiramente diferente. Em alguns casos, isso pode ser o que você precisa, mas, na minha experiência, nunca foi esse o caso. Se você realmente teve um caso em quei
pode ser maior ou menor que 10, mas deseja continuar fazendo um loop até que seja igual a 10, esse código realmente precisaria ser comentado com muita clareza e provavelmente poderia ser melhor escrito com alguma outra construção, como como umwhile
laço, talvez.fonte
Uma das razões pelas quais eu preferiria um
less than
over anot equals
é atuar como guarda. Em algumas circunstâncias limitadas (programação ruim ou higienização), issonot equals
poderia ser ignorado, enquantoless than
ainda estaria em vigor.Aqui está um exemplo em que a falta de uma verificação de higienização levou a resultados estranhos: http://www.michaeleisen.org/blog/?p=358
fonte
Aqui está uma razão pela qual você pode preferir usar em
<
vez de!=
. Se você estiver usando um idioma com escopo de variável global, o que acontecerá se outro código for modificadoi
? Se você estiver usando<
, em vez de!=
, o pior que acontece é que a iteração acabamentos mais rápidos: talvez alguns outros incrementos de códigoi
por acidente, e você pular algumas iterações no loop for. Mas o que acontece se você fizer um loop de 0 a 10, e o loop chegar a 9, e alguns threads mal escritos aumentaremi
por algum motivo estranho. Em seguida, seu loop conclui a iteração e aumentai
para que o valor seja agora 11. Como o loop ignorou a condição de saída (i
nunca igual a 10), ele será repetido infinitamente.Não precisa necessariamente ser uma lógica do tipo de variáveis-de-threading e variáveis globais particularmente esquisitas que causa isso. Pode ser que você esteja escrevendo um loop que precisa voltar atrás. Se você está mudando
i
dentro do loop e estraga sua lógica, tê-lo com um limite superior em vez de a!=
é menos provável que o deixe em um loop infinito.fonte
No mundo incorporado, especialmente em ambientes ruidosos, você não pode contar com a RAM necessariamente se comportando como deveria. Em um condicional (para, enquanto, se) em que você compara usando '==' ou '! =', Você sempre corre o risco de que suas variáveis pulem esse valor crucial que encerra o loop - isso pode ter consequências desastrosas - Mars Lander conseqüências de nível. Usar '<' ou '>' na condição fornece um nível extra de segurança para capturar as 'incógnitas desconhecidas'.
No exemplo original, se
i
fosse inexplicavelmente catapultada para um valor muito maior que 10, a comparação '<' capturaria o erro imediatamente e sairia do loop, mas '! =' Continuaria a contar atéi
contornar 0 e voltar para 10.fonte
for (i=4; i<length; i++) csum+=dat[i];
onde pacotes legítimos sempre teriamlength
pelo menos quatro, mas um pode receber pacotes corrompidos. Se tipos diferentes de pacotes tiverem requisitos de comprimento diferentes, convém validar o comprimento como parte do processamento diferente para cada tipo de pacote, mas valide a soma de verificação como parte da lógica comum primeiro. Se um pacote de menor tamanho for recebido, não importa realmente se o cálculo da soma de verificação relata "bom" ou "ruim", mas não deve travar.