Tomando decisões com if
Os programas reagem o tempo todo aos dados: aprovado ou reprovado, em estoque ou esgotado, válido ou não. A instrução if é como o C++ escolhe qual código executar com base em uma condição.
Um if recebe uma condição entre parênteses e executa o bloco entre chaves apenas quando essa condição é verdadeira:
A condição score >= 60 é verdadeira, então a mensagem é impressa. A linha após a chave de fechamento sempre executa: ela fica fora do if. Mude score para 40 e a linha de "passed" é totalmente ignorada.
A condição é convertida para bool. Comparações como >, >=, ==, != já retornam um bool, mas o C++ também trata qualquer número diferente de zero como verdadeiro e 0 como falso, de modo que if (count) significa "se count não for zero". Essa conversão implícita é conveniente, mas também é a origem de alguns bugs clássicos que você verá abaixo.
Adicionando um else
else dá a você o caminho do "caso contrário": código que executa apenas quando a condição é falsa:
Exatamente um dos dois blocos executa: nunca ambos, nunca nenhum. O else não tem condição própria; ele simplesmente captura tudo o que o if não capturou.
Encadeando com else if
Quando há mais de dois resultados possíveis, encadeie condições com else if. O C++ as verifica de cima para baixo e executa o primeiro bloco cuja condição for verdadeira, depois ignora o restante:
A ordem importa. Como 84 é comparado primeiro com >= 90 (falso) e depois com >= 80 (verdadeiro), ele para em B e nunca verifica os limites inferiores. É por isso também que você não precisa de score >= 80 && score < 90: chegar ao segundo ramo já garante que score era menor que 90. Coloque sua condição mais restritiva ou de maior prioridade primeiro.
Observe que não existe a palavra-chave elif em C++: else if é literalmente um else cujo corpo é outro if. As chaves apenas fazem com que isso se leia como uma única escada.
Uma grande armadilha: = versus ==
O bug de instrução if mais comum em C e C++ é escrever = (atribuição) onde você queria == (comparação):
x = 5 atribui 5 a x e a expressão inteira é avaliada como 5, que é convertida para true, então o ramo sempre executa e você sobrescreveu x sem perceber. Isso compila; a maioria dos compiladores só emite um aviso. Duas defesas: ative os avisos (-Wall) para que o compilador sinalize, e considere colocar a constante na frente —if (5 == x)— porque if (5 = x) é um erro grave que o compilador detecta imediatamente.
A mesma armadilha se esconde com bool: if (ready = true) compila e atribui, enquanto if (ready == true) (ou simplesmente if (ready)) compara.
Combinando e aninhando condições
Combine condições com && (e), || (ou) e ! (não), ou aninhe um if dentro de outro quando uma verificação só fizer sentido depois que outra anterior passar:
&& e || fazem avaliação em curto-circuito: em a && b, se a for falso o C++ nunca avalia b. Isso é essencial para se proteger contra acessos inválidos à memória: if (ptr != nullptr && ptr->ready) é seguro porque a desreferência do ponteiro é ignorada quando ptr é nulo. Prefira achatar com && em vez de aninhar profundamente quando puder; uma condição plana se lê com mais clareza que uma pirâmide de chaves.
Cuidado com o encadeamento de comparações que não significa o que parece: if (0 < x < 10) não testa um intervalo. Ele avalia 0 < x como um bool (0 ou 1) e depois o compara com 10: sempre verdadeiro. Escreva if (0 < x && x < 10) em vez disso.
O operador ternário
Quando tudo o que você quer é escolher entre dois valores, o operador ternário ?: é uma linha única e compacta. Leia condition ? a : b como "se a condição for verdadeira, então a, senão b":
O ternário produz um valor que você pode atribuir, passar ou imprimir diretamente, algo que um if simples não consegue fazer. Reserve-o para seleções simples: se algum ramo precisar de várias instruções ou de lógica de verdade, um if-else completo permanece legível onde um ternário aninhado rapidamente se torna um quebra-cabeça. (Uma sutileza: os dois ramos precisam compartilhar um tipo comum, então não misture, por exemplo, uma string e um int.)
if com inicializador (C++17)
Desde o C++17 você pode declarar uma variável logo dentro do if, com escopo limitado ao if/else. Isso evita que auxiliares de vida curta vazem para o código ao redor:
A parte antes do ; executa uma vez e seu resultado fica visível tanto na condição quanto no else. Isso é ótimo para padrões de "calcular algo e depois ramificar com base nisso"; e, como a conversão do resultado acontece uma única vez no início, você evita recalcular ou reutilizar acidentalmente um valor desatualizado depois. Recorra a isso sempre que um temporário só for necessário para a ramificação.
Uma armadilha: o problema das chaves soltas
O C++ permite que você omita as chaves quando um ramo tem uma única instrução, mas isso convida a um bug sutil: a indentação mente:
if (loggedIn)
cout << "Welcome\n";
cout << "Loading dashboard\n"; // NÃO faz parte do if!
Apenas a primeira linha é controlada pelo if; a segunda sempre executa, independentemente de loggedIn, apesar de a indentação sugerir o contrário. Um clássico relacionado é o ponto e vírgula perdido: if (x > 0); encerra o if com um corpo vazio, então o bloco que vem em seguida executa incondicionalmente. Use sempre chaves —mesmo para uma única linha— e a maior parte desse tipo de erro desaparece.
Próximo: switch
As cadeias if-else if são perfeitas quando cada ramo testa uma condição diferente. Mas quando você está verificando um único valor contra muitas possibilidades fixas —uma opção de menu, um enum, um código de status— uma longa escada de else if fica repetitiva e fácil de ordenar errado. A instrução switch foi feita exatamente para isso, e é sobre isso que trata a próxima página.
Perguntas frequentes
Como se escreve uma instrução if-else em C++?
Coloque uma condição entre parênteses depois de if, o código a executar entre chaves e um bloco else opcional para quando a condição for falsa: if (score >= 60) { cout << "Pass"; } else { cout << "Fail"; }. A condição é convertida para bool, então qualquer número diferente de zero conta como verdadeiro e 0 conta como falso.
Qual é a diferença entre = e == em uma instrução if de C++?
== compara dois valores quanto à igualdade, enquanto um único = atribui. Escrever if (x = 5) atribui 5 a x e depois avalia 5 (sempre verdadeiro): um bug clássico. Ele compila apenas com um aviso, então ative os avisos e considere escrever a constante primeiro: if (5 == x).
O que é o operador ternário em C++?
O operador ternário condition ? valueIfTrue : valueIfFalse é um if-else compacto que produz um valor. Por exemplo, string label = age >= 18 ? "adult" : "minor"; escolhe um de dois valores. Use-o para seleções simples de valores; recorra a um if-else completo quando cada ramo tiver lógica de verdade.