Apenas uma observação aleatória, parece que no StackOverflow.com, há perguntas sobre se "++ i == i ++". Essa pergunta é feita o tempo todo, acho que a vi perguntada cerca de 6 ou 7 vezes nos últimos 2 meses.
Eu só me pergunto por que os desenvolvedores C estão tão interessados nisso? O mesmo conceito / pergunta existe também para desenvolvedores de C # e Java, mas acho que vi apenas uma pergunta relacionada ao C #.
É porque tantos exemplos usam ++ i? É porque existe algum livro ou tutorial popular? É porque os desenvolvedores de C adoram amontoar o máximo possível em uma única linha para 'eficiência' / 'desempenho' e, portanto, encontram construções 'estranhas' usando o operador ++ com mais frequência?
c
undefined-behavior
Michael Stum
fonte
fonte
++i == i++
ou, de maneira mais geral, à diferença de significado entre++i
ei++
?Respostas:
Suspeito que pelo menos parte disso seja um pouco mais simples: mesmo agora, vemos muitas perguntas como essa começando no início do ano letivo e elas gradualmente diminuem ao longo do ano.
Como tal, acho que é justo adivinhar que algumas delas são simplesmente o resultado de aulas nas quais o professor fala pelo menos um pouco sobre isso, mas não explica muito bem seus pontos (muitas vezes não porque ele realmente não os entende). Especialmente com base nas pessoas que parecem fazer essas perguntas, poucas são baseadas na codificação real.
fonte
Porque os programadores C precisam entender a ordem das operações. Os desenvolvedores de C # não usam necessariamente os operadores bit a bit (&, |, ~) ou prefixos, pois normalmente estamos mais preocupados com outras coisas. No entanto, o que nós C # devs não percebemos é que devemos saber o que os operadores que usamos diariamente fazem e como usá-los adequadamente. A maioria de nós evita os lugares onde isso pode ser um problema.
De cabeça para baixo, qual é o resultado desse snippet?
Eu diria que um bom número de desenvolvedores C # experientes não tem idéia de qual é a saída para o console.
fonte
if (myList[i++] == item)
. Esperto. Eu achei que estava procurando a fonte de uma exceção IndexOutOfRange ... De fato, muito "inteligente".++
usado em um carro alegórico antes, e devo dizer que não parece muito apropriado. As pessoas fazem isso? (Eu prefiro+= 1
)Eu acho que isso é óbvio. Em C #, para um
int i
,i++ == ++i
é sempre falso, enquanto++i == i++
é sempre verdade, de forma confiável, e todos os interessados podem descobrir isso facilmente, apenas aprendendo as regras do C # (ou simplesmente executando-o).Em C e C ++, por outro lado, é quase indefinido porque depende do compilador, do ambiente de execução, da plataforma etc., por isso é uma pergunta muito mais difícil de responder, e muitas pessoas fazem isso.
fonte
É uma pergunta popular, porque é uma pergunta complicada. Está indefinido .
O link acima vai para uma FAQ na página inicial de Bjarnes Stroustrup, que aborda essa questão especificamente e explica por que essa construção é indefinida. O que diz é:
fonte
Provavelmente porque em C, realmente importa se você escreve
i++
ou++i
quando faz aritmética de ponteiros. Lá, aumentari
antes ou depois de uma operação pode ser crucial. Eu daria um exemplo, mas a última vez que escrevi C foi há 10 anos ...Em C #, nunca me deparei com uma situação que exigisse que eu pensasse
i++
ou++i
porque o AFAIK, pelos loops for / while, não importa.fonte
i++
e++i
, mas combiná-los na mesma expressão.Alguns anos atrás, li que esses operadores eram considerados perigosos e tentei cavar mais informações. Se o stackoverflow estivesse ativo naquele momento, eu teria perguntado lá.
Agora é porque algumas pessoas distorcidas escrevem loops como
Mesmo agora, não tenho muita certeza do que acontecerá / deveria acontecer, mas está bem claro para mim que vários ++ [var] na mesma linha estão pedindo problemas.
fonte
x = ++j;
estão bem definidas em C. O item acima é indefinido porquej
é modificado duas vezes sem pontos de sequência intervenientes.Duas razões.
A implementação correta do ++ i é incrementar i e depois devolvê-lo. A implementação correta do i ++ é salvar o valor atual, incrementar i e retornar o valor salvo. Saber que isso não é implementado como sinônimo é importante.
A questão então se torna quando o compilador as aplica enquanto avalia uma expressão, como igualdade.
Se o teste de igualdade for feito primeiro, os operadores de pré e pós-incremento terão que escrever uma lógica diferente do que se o lado esquerdo (lhs) e o lado direito (rhs) forem avaliados primeiro e, em seguida, a igualdade.
É tudo uma ordem de operações, e isso, por sua vez, afeta o código que se escreve. E, não surpreendentemente, nem todos os idiomas estão de acordo.
A lista de testes básicos permite que os desenvolvedores testem para ver se suas suposições estão corretas, bem como se a implementação real corresponde à especificação de idioma.
Isso pode ter todos os tipos de impacto ao trabalhar com ponteiros, loops ou retornar valores.
fonte
++i
é usar o valori+1
e em algum momento, talvez antes ou depois disso, mas antes do próximo ponto de sequência, incrementei
.Eu acho que é uma coisa de choque cultural.
Como já apontado, o comportamento de uma expressão em C ou C ++ pode ser indefinido porque a ordem de execução dos pós-incrementos etc. não é estritamente definida. O comportamento indefinido é bastante comum em C e, é claro, muito disso foi importado para C ++.
Para alguém que fez alguma programação em outra linguagem - alguém que entendeu a idéia de que as linguagens de programação deveriam ser precisas e que os computadores deveriam fazer o que eles deveriam fazer ... bem, é um choque descubra que C é intencionalmente vago sobre algumas coisas.
fonte
++
e os--
operadores não eram baseados no PDP-11, que não existia quando esses operadores foram introduzidos na linguagem B anterior do C. Consulte cm.bell-labs.com/who/dmr/chist.html e procure por "incremento automático".Talvez seja apenas o fato de os desenvolvedores de C usarem o incremento ++ com mais frequência em geral - visto que C não possui "foreach" ou declaração semelhante para iterar através de matrizes. Ah, e é claro, aritmético, como mencionado anteriormente!
fonte
A diferença entre as duas partes: a postagem e o pré-incremento estão funcionando da maneira que esses dois pedaços de código devem funcionar em todos os idiomas. ISTO NÃO É DEPENDENTE DA LÍNGUA !!!
Isso é pré-incremento. Este trecho de código aumentará primeiro o valor de
i
antes de enviar o valor para a linha em que é usado.Este é o pós-incremento. Este trecho de código retornará o valor de
i
antes de aumentar o valor dai
linha em que é usado.Em outro pequeno exemplo:
Este código compilando com resultados no codepad.
Isso tem a ver com a implementação interna da sobrecarga do operador.
++i
aumenta diretamente o valor (e, portanto, é um pouco mais rápido)i++
primeiro cria uma cópia que é retornada ao local onde necessário e depois o valor original dai
variável é aumentado em um.Espero que isso esteja claro agora.
fonte
++i
não é mais rápido ei++
não cria uma cópia. Além disso,++i
comporta-se de maneira ligeiramente diferente em C e em C ++, sem falar entre outras linguagens.