Por que o código abaixo retorna verdadeiro apenas para A = 1?
-
02-07-2019 - |
Pergunta
Por que o código abaixo retorna verdadeiro apenas para A = 1?
main(){
int a = 10;
if (true == a)
cout<<"Why am I not getting executed";
}
Solução
Quando um bool true é convertido em um INT, ele sempre é convertido para 1. Seu código é, portanto, equivalente a:
main(){
int a = 10;
if (1 == a)
cout<<"y i am not getting executed";
}
Isso faz parte do Padrão C ++, então é algo que você esperaria que acontecesse com todos os compiladores compatíveis com padrões C ++.
Outras dicas
A razão pela qual sua declaração de impressão não está sendo executada é porque seu booleano está sendo implicitamente convertido em um número em vez do contrário. Ou seja, sua declaração IF é equivalente a isso: se (1 == a)
Você pode contornar isso primeiro convertendo -o explicitamente em um booleano:
main(){
int a = 10;
if (((bool)a) == true)
cout<<"I am definitely getting executed";
}
Em C/C ++ False é representado como 0.
Todo o resto é representado como não zero. Isso às vezes é 1, às vezes qualquer outra coisa. Portanto, você nunca deve testar a igualdade (==) para algo que é verdadeiro.
Em vez disso, você deve testar a igualdade a algo que é falso. Como False tem apenas 1 valor válido.
Aqui estamos testando para todos os valores não falsos, qualquer um deles está bem:
main(){
int a = 10;
if (a)
cout<<"I am definitely getting executed";
}
E um terceiro exemplo apenas para provar que é seguro comparar qualquer número inteiro considerado falso a um falso (que é apenas 0):
main(){
int a = 0;
if (0 == false)
cout<<"I am definitely getting executed";
}
Seu booleano é promovido a um número inteiro e se torna 1.
Em C e C ++, 0 é falso e tudo menos zero é verdadeiro:
if ( 0 )
{
// never run
}
if ( 1 )
{
// always run
}
if ( var1 == 1 )
{
// run when var1 is "1"
}
Quando o Compiler calcula uma expressão booleana, é obrigado a produzir 0 ou 1. Além disso, há alguns typedefs e defines úteis, que permitem que você use "verdadeiro" e "falso" em vez de 1 e 0 em suas expressões.
Então, seu código realmente se parece com o seguinte:
main(){
int a = 10;
if (1 == a)
cout<<"y i am not getting executed";
}
Você provavelmente quer:
main(){
int a = 10;
if (true == (bool)a)
cout<<"if you want to explicitly use true/false";
}
ou realmente apenas:
main(){
int a = 10;
if ( a )
cout<<"usual C++ style";
}
Porque true é 1. Se você deseja testar um valor diferente de zero, basta escrever se (a).
Eu sugiro que você mude para um compilador que o avisa sobre isso ... (VC ++ produz o seguinte: Aviso C4806: '==': Operação insegura: nenhum valor do tipo 'bool' promovido a tipo 'int' pode ser igual à constante dada; Eu não tenho outro compilador à mão.)
Eu concordo com Lou Franco - você quer saber se uma variável é maior que zero (ou desigual), teste isso.
Tudo o que é feito implicitamente pelo compilador é perigoso se você não conhece o último detalhe.
Aqui está a maneira como a maioria das pessoas escreve esse tipo de código:
main(){
int a = 10;
if (a) // all non-zero satisfy 'truth'
cout<<"y i am not getting executed";
}
Eu também vi:
main(){
int a = 10;
if (!!a == true) // ! result is guaranteed to be == true or == false
cout<<"y i am not getting executed";
}
Eu não esperaria que esse código fosse definido e você não dependa de qualquer comportamento que seu compilador esteja dando a você. Provavelmente, o verdadeiro está sendo convertido em um int (1), e A não está sendo convertido em um bool (verdadeiro) como você espera. Melhor escrever o que você quer dizer (a! = 0) do que depender disso (mesmo que seja definido).
algo diferente de 0 (que é falso) não é necessário (ou seja, 1)
Porque TRUE é igual a 1. É definido em uma diretiva pré-processadora, portanto, todo o código com verdadeiro é transformado em 1 antes do tempo de compilação.
Porque um booleano está um pouco em C/C ++ e True é representado por 1, falso por 0.
ATUALIZAÇÃO: Como dito no comentário, minha resposta original é falsa. Então, ignore.