O que torna os desenvolvedores de C tão curiosos se “i ++ == ++ i”? [fechadas]

14

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 eu perguntei 6 ou 7 vezes nos últimos 2 meses.

Pergunto-me por que os desenvolvedores de C estão tão interessados nele? O mesmo conceito / questão existe para desenvolvedores C # e Java também, mas acho que vi apenas uma questão relacionada ao C #.

É porque muitos exemplos usam ++ i? É porque existe algum livro ou tutorial popular? É porque os desenvolvedores C só gostam de empinar o máximo possível em uma única linha para 'eficiência' / 'desempenho' e, portanto, encontrar construções 'estranhas' usando o operador ++ com mais frequência?

    
por Michael Stum 02.11.2010 / 00:34
fonte

10 respostas

29

Eu suspeito que pelo menos parte é um pouco mais simples: mesmo agora, vemos muitas questões como esta começando no começo do ano letivo, e elas gradualmente diminuem ao longo do ano.

Como tal, eu acho que é justo adivinhar que muitos deles são simplesmente o resultado de aulas em que o professor fala pelo menos um pouco sobre isso, mas não explica muito bem o (s) seu (s) ponto (s) 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 em códigos reais.

    
por 02.11.2010 / 00:51
fonte
12

Porque os programadores C TÊM que entender a ordem das operações. Os desenvolvedores de C # não usam necessariamente os operadores bitwise (& amp ;, |, ~) ou operadores de prefixo, já que normalmente estamos mais preocupados com outras coisas. No entanto, o que nós, desenvolvedores de C #, não percebem é que devemos saber o que os operadores que usamos diariamente e como usá-los adequadamente. A maioria de nós apenas evita os lugares onde isso pode ser um problema.

Na parte superior da sua cabeça, qual é a saída deste trecho de código?

    double x = 5.5;
    Console.WriteLine(x++);
    x = 5.5;
    Console.WriteLine(++x);

Eu diria que um bom número de usuários experientes em C # não tem idéia de qual é a saída para o console.

    
por 02.11.2010 / 01:06
fonte
8

Eu acho que isso é óbvio. Em C #, para um int i , i++ == ++i é sempre falso enquanto ++i == i++ é sempre verdadeiro, confiável, e todos que estão interessados podem descobrir isso facilmente aprendendo as regras do C # (ou simplesmente rodando).

Em C e C ++, por outro lado, é quase indefinido porque depende do compilador, do ambiente de execução, da plataforma, etc., então é uma pergunta muito mais difícil de responder, então muitas pessoas perguntam.

    
por 27.05.2011 / 16:05
fonte
5

Provavelmente porque em C, realmente importa se você escreve i++ ou ++i quando estiver fazendo aritmética com ponteiros. Lá, aumentar i 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 encontrei uma situação que exigisse que eu pensasse em i++ ou ++i porque a AFAIK, para os loops for / while, isso realmente não importa.

    
por 02.11.2010 / 00:43
fonte
3

É uma pergunta popular porque é uma questão complicada. É indefinido .

O link acima vai para um FAQ na página inicial da Bjarnes Stroustrup, que aborda essa questão especificamente, e explica por que essa construção é indefinida. O que diz é:

Basically, in C and C++, if you read a variable twice in an expression where you also write it, the result is undefined.

Having the order of evaluation undefined is claimed to yield better performing code.

    
por 27.05.2011 / 17:44
fonte
2

Há alguns anos, eu li que esses operadores eram considerados perigosos, então tentei descobrir mais informações sobre isso. Se o stackoverflow estivesse ativo naquele momento, eu teria perguntado lá.

Agora, é porque algumas pessoas distorcidas escrevem loops como

while( [something] )
{
  a[++j] = ++j;
}

Mesmo agora, não tenho muita certeza sobre o que acontecerá / deverá acontecer, mas está bem claro para mim que vários + [var] na mesma linha estão pedindo problemas.

    
por 02.11.2010 / 04:13
fonte
2

Duas razões.

A implementação correta do ++ i é incrementar i e depois retorná-lo. A implementação correta do i ++ é salvar o valor atual, incrementar i e retornar o valor salvo. Sabendo que estes não são implementados como sinônimo é importante.

A questão então se torna quando o compilador as aplica enquanto avalia uma expressão, como a igualdade.

Se o teste de igualdade for feito primeiro, então os operadores pré e pós-incremento, você terá que escrever uma lógica diferente do que se o lado esquerdo (lhs) e o lado direito (rhs) forem avaliados primeiro, depois a igualdade.

É tudo uma questão de ordem de operações, e isso, por sua vez, afeta o código que se escreve. E, não surpreendentemente, nem todas as línguas estão de acordo.

A lista de testes básicos permite que os desenvolvedores testem se suas premissas estão corretas, bem como se a implementação real corresponde à especificação do idioma.

Isso pode ter todos os tipos de impacto ao trabalhar com ponteiros, loops ou valores de retorno.

    
por 02.11.2010 / 16:30
fonte
2

Eu acho que é uma coisa de choque cultural.

Como já foi 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 o C ++.

Para alguém que tenha feito alguma programação em outro idioma - alguém que tenha percebido que as linguagens de programação devem ser precisas e que os computadores devem fazer o que é mandado fazer ... bem, é um choque ao descobrir que C é intencionalmente vago sobre algumas coisas.

    
por 28.05.2011 / 06:04
fonte
1

Talvez seja apenas porque os desenvolvedores C usam a incremento ++ com mais frequência em geral - vendo como C não tem "foreach" ou declaração semelhante para iterar por arrays. Ah, e claro ponteiro arithmatic, como mencionado anteriormente!

    
por 16.07.2011 / 22:30
fonte
-1

A diferença entre as duas partes: o post e o preincrement estão funcionando da mesma maneira que esses dois códigos devem funcionar em todos os idiomas. ISTO NÃO É DEPENDENTE DA LÍNGUA !!!

++i

Isso é pré-incremento. Essa parte do código primeiro aumentará o valor de i antes de enviar o valor para a linha em que é usado.

i++

Este é o incremento de postagem. Essa parte do código retornará o valor de i antes de aumentar o valor de i na linha em que é usado.

Em outro pequeno exemplo:

int main(void)
{
  int i = 0; 
  int result; 
  result = 10 + ++i; 
  printf("%d \n", result); // = 11 

  int j = 0; 
  result = 10 + j++; 
  printf("%d \n", result);// = 10
  return 0;
}

Este código é compilado com resultados no controlador remoto

Isso tem a ver com a implementação interna da sobrecarga de operadores.

++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 da variável i é aumentado em um.

Espero que isso esteja claro agora.

    
por 17.07.2011 / 03:31
fonte