Jump to content

Recommended Posts

Posted

Olá

Estou a seguir o manual online que o Bscara me disse e deparei-me aí com um erro estranho. num exercício diz para compilar este código:

#include <stdio.h>
int main()
{
 int index = 0, contador;
 char letras[5] = "Joao";
 for (contador=0; contador < 1000; contador++)
 {
printf("\n%c",letras[index]);
index="(index" 4)? index="0:" ++index;
 }
}

Vem logo estes erros

D:\2012\c_exe\C410_If_Else\main.c||In function 'main':|

D:\2012\c_exe\C410_If_Else\main.c|9|warning: assignment makes integer from pointer without a cast [enabled by default]|

D:\2012\c_exe\C410_If_Else\main.c|9|error: expected ';' before numeric constant|

D:\2012\c_exe\C410_If_Else\main.c|9|error: expected statement before ')' token|

D:\2012\c_exe\C410_If_Else\main.c|9|error: expected expression before '?' token|

D:\2012\c_exe\C410_If_Else\main.c|9|error: lvalue required as increment operand|

D:\2012\c_exe\C410_If_Else\main.c|11|warning: control reaches end of non-void function [-Wreturn-type]|

||=== Build finished: 4 errors, 2 warnings ===|

Estive a ver a linha e isso está mal aqui

index="(index" 4)? index="0:" ++index;

Na teoria diz

condição?expressão_1:expressão_2;

em vez de um if pode trocar-se por isso

O nome Joao é escrito na tela verticalmente até a variável contador determinar o término do programa. Enquanto isto a variável index assume os valores 0, 1, 2, 3, 4, 0, 1, ... progressivamente.

index=index>4?0:++index;

Não está bem pois não?

gmc11

 

Posted

Sugestão: usa o if em vez do "operador ternário".

if (index > 4) index = 0; else index++;

Como vês no if acima, as operações a efectuar são diferentes: atribuição ou incremento.

Não é nada prático (para não dizer que é impossível) usar o "operador ternário" com operações diferentes.

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Posted

Obrigado

Estava a tentar seguir o exemplo dado mas quando vi que não compilava tentei perceber se daquela maneira dava.

O objetivo era não usar o if, mas no fundo...para quê complicar

Muito obrigado

gmc11

 

Posted

Pela minha experiencia, o uso dessas expressoes simplificadas fazem com que o código seja menos evidente. Usando ciclos normais percebes bem o código e não te dá erros inesperados. Keep it simple dude

Posted

Pela minha experiencia, o uso dessas expressoes simplificadas fazem com que o código seja menos evidente. Usando ciclos normais percebes bem o código e não te dá erros inesperados. Keep it simple dude

só é menos evidente para quem não está habituado ...

se usadas correctamente não existe nenhum problema em serem usadas.

IRC : sim, é algo que ainda existe >> #p@p
Posted

A linha 'index="(index" 4)? index="0:" ++index;' não é C válido, nem nenhuma outra linguagem. Se é assim que está no exercício (que não vi) está mal.

Mas a linha 'index=index>4?0:++index;' é válida e é equivalente ao 'if ... else' que o pmg te indicou. Essa linha mostra a utilização do operador '?' mas também o pré-incremento duma variável.

Do ponto de vista do compilador a utilização do operador '?' poderá permitir optimizar mais agressivamente ou com menos esforço o código aquando da tradução para código-máquina.

Posted

Mas a linha 'index=index>4?0:++index;' é válida ...

Quando index <= 4, a linha assinalada torna-se index = ++index que é um exemplo chapado de "Comportamento indefinido" por alterar o valor do mesmo objecto duas vezes sem um "sequence point" de intervalo.

Quando muito, assumindo que index nunca podia ser 6 ou 7 ou mais, poderias usar

index += index > 4 ? -5 : 1;

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Posted

Quando index <= 4, a linha assinalada torna-se index = ++index que é um exemplo chapado de "Comportamento indefinido" por alterar o valor do mesmo objecto duas vezes sem um "sequence point" de intervalo.

Obrigado pela correcção.

Posted (edited)

Quando index <= 4, a linha assinalada torna-se index = ++index que é um exemplo chapado de "Comportamento indefinido" por alterar o valor do mesmo objecto duas vezes sem um "sequence point" de intervalo.

Não me parece comportamento indefinido, está bem definido o que acontece.

Ele executa:

index++;
// seguido de:
index = index // que é bem inútil
Edited by brunoais

"[Os jovens da actual geração]não lêem porque não envolve um telecomando que dê para mirar e atirar, não falam porque a trapalhice é rainha e o calão é rei" autor: thoga31

Life is a genetically transmitted disease, induced by sex, with death rate of 100%.

Posted (edited)

Não me parece comportamento indefinido...

Citação do Standard de C2011

6.5/2 If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined.

Na expressão index = ++index; há dois "side-effects": o da atribuição dum valor ao objecto identificado como index e o do incremento do valor desse mesmo objecto. Não há sequência nenhuma explicíta (ou implícita) sobre a ordem em que estes "side-effects" sobre o mesmo objecto ocorrem.

Edited by pmg

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Posted

Não há sequência nenhuma explicíta (ou implícita) sobre a ordem em que estes "side-effects" sobre o mesmo objecto ocorrem.

Tendo em conta que foi usado o operador prefixo, diria que o incremento teria que ser realizado antes da atribuição.

Mas esta não seria a primeira vez em que uma situação em que a ordem me parece óbvia tem comportamento indefinido de acordo com os standards. Por isso não me admira que também seja este o caso.

Posted

Não me parece comportamento indefinido, está bem definido o que acontece.

O meu raciocínio original era de que a linha 'index = ++index' seria equivalente à atribuição do resultado da expressão da direita à variável da esquerda, o que seria compatível com a linguagem do Standard que diz que o fim duma expressão completa (++index) implica um 'sequence point'.

O que não levei em consideração é que, ao contrário de outras linguagens, em C o '=' é um operador, tal como '+' e '-'. É isso que permite que isto seja possível:

if ((block = malloc(100)) != NULL)

Assim sendo a linha 'index = ++index' é, na totalidade, uma expressão. Como tal o 'sequence point' apenas acontece depois da atribuição.

Agora uma questão mais interessante é porque é que as regras de precedência dos operadores, que explicitam que o '=' tem uma precedência inferior ao '++' (pré ou pós), não bastam para garantir a ordem dos 'side effects'.

Posted

Agora uma questão mais interessante é porque é que as regras de precedência dos operadores, que explicitam que o '=' tem uma precedência inferior ao '++' (pré ou pós), não bastam para garantir a ordem dos 'side effects'.

Suspeito que seja para ajudar os compiladores na optimização. Se não houver uma ordem definida, os compiladores podem gerar código para executar as operações em qualquer ordem, os que lhes dá a liberdade de escolherem a ordem mais eficiente.

Fica nas mãos do programador escrever código em que a ordem de execução não interesse.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.