Depois de ler características ocultas e Dark Corners de C ++ / STL on comp.lang.c++.moderated
, I foi completamente surpreso que o seguinte trecho compilado e trabalhou em ambos os Visual Studio 2008 e G ++ 4.4.
Aqui está o código:
#include <stdio.h>
int main()
{
int x = 10;
while (x --> 0) // x goes to 0
{
printf("%d ", x);
}
}
Resultado:
9 8 7 6 5 4 3 2 1 0
Eu diria que este é C, pois também funciona no GCC. De onde isso é definido no padrão e de onde veio?
c++
c
operators
code-formatting
standards-compliance
GManNickG
fonte
fonte
++
ou--
antes ...#define upto ++<
,#define downto -->
. Se você está se sentindo mal, você pode fazer#define for while(
e#define do ) {
(e#define done ;}
) e escreverfor x downto 0 do printf("%d\n", x) done
Oh, a humanidade ...Respostas:
-->
não é um operador. Na verdade, são dois operadores separados,--
e>
.O código da condicional diminui
x
, enquanto retornax
o valor original (não diminuído) e, em seguida, compara o valor original com o0
uso do>
operador.Para entender melhor, a declaração pode ser escrita da seguinte maneira:
fonte
while (x-- > 0)
seria mais adequado. Também torna mais óbvio o que está acontecendo (pelo menos em um editor de fonte fixa), significando que os parênteses nesta resposta não seriam necessários.Ou para algo completamente diferente ...
x
desliza para0
.Não é tão matemático, mas ... toda imagem pinta mil palavras ...
fonte
why waste words when a picture does a better job
, usado como uma piada neste contexto. (na verdade, existem duas palavraswhile
- chave eprintf
)Esse é um operador muito complicado, portanto, mesmo o ISO / IEC JTC1 (Comitê Técnico Conjunto 1) colocou sua descrição em duas partes diferentes do Padrão C ++.
Brincadeiras à parte, eles são dois operadores diferentes:
--
e>
descritos respectivamente nos §5.2.6 / 2 e §5.9 da Norma C ++ 03.fonte
É equivalente a
x--
(pós-decremento) é equivalente ax = x-1
, o código se transforma em:fonte
0 >-- x
neste caso,x
é diminuído antes da lógica. No postfix, a lógica é executada antes do decremento e, portanto, as duas amostras são equivalentes. Sinta-se livre para escrevê-los em umConsole
e testá-los.while(x=x-1,x+1 > 0)
é equivalente.x
pode ir para zero ainda mais rápido na direção oposta:8 6 4 2
Você pode controlar a velocidade com uma flecha!
90 80 70 60 50 40 30 20 10
;)
fonte
Está
Apenas o espaço faz as coisas parecerem engraçadas,
--
diminui e>
compara.fonte
O uso de
-->
tem relevância histórica. Decrementar foi (e ainda é, em alguns casos), mais rápido que incrementar na arquitetura x86. Usar-->
sugere que issox
vai0
e apela para aqueles com formação matemática.fonte
é assim que é analisado.
fonte
Totalmente nerd, mas vou usar isso:
fonte
do ... while
é uma lista de instruções. Em C, é um bloco, por isso deve serdo { ... } while
.do statement while ( expression ) ;
. Dito isto, espero que entenda que eu quis dizer o exemplo como uma piada.Um livro que li (não me lembro corretamente de qual livro) declarou: Os compiladores tentam analisar expressões para o maior token usando a regra esquerda direita.
Nesse caso, a expressão:
Analisa os maiores tokens:
A mesma regra se aplica a esta expressão:
Após a análise:
Espero que isso ajude a entender a expressão complicada ^^
fonte
a-----b
e pensará(a--)-- - b
, o que não compila porquea--
não retorna um lvalue.x
e--
são dois sinais separados.-->
é um operador (o que está implícito na pergunta), essa resposta não ajuda em nada - você pensará que o token 2 é-->
, não apenas--
. Se você sabe que-->
não é um operador, provavelmente não tem problemas para entender o código da pergunta; portanto, a menos que tenha uma pergunta completamente diferente, não tenho muita certeza de como isso poderia ser útil.a
operador pós- decréscimo foi sobrecarregado, o que retorna lvalue. coliru.stacked-crooked.com/a/e1effc351ae79e9fÉ exatamente o mesmo que
para números não negativos
fonte
for(--x++;--x;++x--)
?unsigned
é para--x++
tem um comportamento indefinido de acordo com §1.9.15unsigned
, teria usado%u
De qualquer forma, temos um operador "vai para" agora.
"-->"
é fácil ser lembrado como uma direção, e "enquanto x chega a zero" tem sentido direto.Além disso, é um pouco mais eficiente do que
"for (x = 10; x > 0; x --)"
em algumas plataformas.fonte
for (size_t x=10; x-->0; )
o corpo do loop é executado com 9,8, .., 0 enquanto a outra versão tem 10,9, .., 1. É bastante complicado sair de um loop para zero com uma variável não assinada.++>
para fazer o trabalho incremental.int
, portanto, ele poderia comer o seu cão com tanta facilidade quanto levarx
a zero se começar negativo.0
. (Para comparação, o idioma de omitir testes para zero, como escreverwhile (n--)
para não assinadon
, não compra nada e para mim dificulta bastante a legibilidade.) Ele também possui a propriedade agradável de especificar um a mais que o índice inicial, que geralmente é o que você deseja (por exemplo, para um loop sobre uma matriz, você especifica seu tamanho). Também gosto-->
sem espaço, pois isso facilita o reconhecimento do idioma.Esse código primeiro compara x e 0 e depois diminui x. (Também foi dito na primeira resposta: você está decrescendo x e depois comparando x e 0 com o
>
operador.) Veja a saída deste código:Agora, primeiro comparamos e depois diminuímos vendo 0 na saída.
Se quisermos primeiro diminuir e depois comparar, use este código:
Essa saída é:
fonte
Meu compilador imprimirá 9876543210 quando eu executar esse código.
Como esperado. O que
while( x-- > 0 )
realmente significawhile( x > 0)
. Ax--
postagem diminuix
.é uma maneira diferente de escrever a mesma coisa.
É bom que o original pareça "enquanto x vai para 0".
fonte
while( x-- > 0 ) actually means while( x > 0)
- Não sei ao certo o que você estava tentando dizer, mas a maneira como você expressou isso--
não tem significado algum, o que obviamente está muito errado.x
será-1
depois que sair do loop, enquanto nesta respostax
será0
.Falta um espaço entre
--
e>
.x
é pós-decrementado, ou seja, diminuído após a verificação da condiçãox>0 ?
.fonte
#define foo()
versus#define foo ()
.--
é o operador de decremento e>
é o operador maior que .Os dois operadores são aplicados como um único
-->
.fonte
É uma combinação de dois operadores. Primeiro,
--
é para diminuir o valor e>
verificar se o valor é maior que o operando do lado direito.A saída será:
fonte
Na verdade,
x
é pós-decrementar e com essa condição está sendo verificada. Não é-->
, é(x--) > 0
Nota: o valor de
x
é alterado após a condição ser verificada, porque é pós-decrescente. Alguns casos semelhantes também podem ocorrer, por exemplo:fonte
x
iniciado em 1, mas owhile ( (x--) > 0 )
faria. {edit} Eric Lippert abordou ambos em suas notas de versão do C # 4: blogs.msdn.microsoft.com/ericlippert/2010/04/01/…C e C ++ obedecem à regra "máxima mastigação". Da mesma forma que a --- b é traduzido para
(a--) - b
, no seu caso, éx-->0
traduzido para(x--)>0
.O que a regra diz essencialmente é que, da esquerda para a direita, as expressões são formadas usando o máximo de caracteres que formarão uma expressão válida.
fonte
Por que toda a complicação?
A resposta simples para a pergunta original é apenas:
Faz a mesma coisa. Não estou dizendo que você deve fazer assim, mas faz a mesma coisa e teria respondido à pergunta em um post.
O
x--
é apenas uma abreviação para o acima exposto e>
é apenas um normal maior queoperator
. Nenhum grande mistério!Há muita gente complicando as coisas simples hoje em dia;)
fonte
The OP's way: 9 8 7 6 5 4 3 2 1 0
eThe Garry_G way: 10 9 8 7 6 5 4 3 2 1
x=x-1
antes,printf
então você pode dizer "ele faz a mesma coisa".Da maneira convencional, definiríamos uma condição entre
while
parênteses do loop()
e uma condição de terminação dentro dos chavetas{}
, mas-->
definem as duas ao mesmo tempo.Por exemplo:
Isso diminui
a
e executa o loop enquantoa
é maior que0
.Convencionalmente, seria como:
Nos dois sentidos, fazemos a mesma coisa e alcançamos os mesmos objetivos.
fonte
test-write-execute
como na pergunta, obrigado por apontar!(x --> 0)
significa(x-- > 0)
(x -->)
output -: 9 8 7 6 5 4 3 2 1 0
(-- x > 0)
é mau(--x > 0)
output -: 9 8 7 6 5 4 3 2 1
output -: 9 8 7 6 5 4 3 2 1
output -: 9 8 7 6 5 4 3 2 1 0
output -: 9 8 7 6 5 4 3 2 1 0
output -: 9 8 7 6 5 4 3 2 1 0
Da mesma forma, você pode tentar vários métodos para executar este comando com sucesso
fonte