Compartilhar via


Instrução if-else (C++)

A instrução if-else controla a ramificação condicional. As instruções no if-branch serão executadas somente se a avaliação condition for de um valor não zero (ou true). Se o valor de condition não for zero, a instrução a seguir será executada e a instrução após a opcional else for ignorada. Caso contrário, a instrução a seguir será ignorada e, se houver uma else a instrução elseseguinte, será executada.

As expressões condition que são avaliadas como não zero são:

  • true
  • um ponteiro não nulo,
  • qualquer valor aritmético diferente de zero ou
  • um tipo de classe que define uma conversão não ambígua em um tipo aritmético, booleano ou de ponteiro. (Para obter mais informações sobre conversões, consulte Conversões Standard.)

Sintaxe

init-statement:
expression-statement
simple-declaration

condition:
expression
attribute-specifier-seqoptdecl-specifier-seqdeclaratorbrace-or-equal-initializer

statement:
expression-statement
compound-statement

expression-statement:
expressionopt;

compound-statement:
{statement-seqopt}

statement-seq:
statement
statement-seq statement

if-branch:
statement

else-branch:
statement

selection-statement:
ifconstexpropt17(init-statementopt17condition)if-branch
ifconstexpropt17(init-statementopt17condition)if-branchelseelse-branch

17 Esse elemento opcional está disponível a partir de C++17.

Instruções if-else

Em todos os formatos da instrução if, condition, que pode ter qualquer valor exceto uma estrutura, é avaliada, inclusive todos os efeitos colaterais. O controle passa da instrução if para a próxima instrução no programa, a menos que executado if-branch ou else-branch contenha um break, continue ou goto.

A cláusula else de uma instrução if...else é associada à instrução anterior mais próxima de if no mesmo escopo que não tem uma instrução correspondente de else.

Exemplo

Este código de exemplo mostra várias instruções if em uso, com e sem else:

// if_else_statement.cpp
#include <iostream>

using namespace std;

int main()
{
    int x = 10;

    if (x < 11)
    {
        cout << "x < 11 is true!\n";  // executed
    }
    else
    {
        cout << "x < 11 is false!\n"; // not executed
    }

    // no else statement
    bool flag = false;
    if (flag == true)
    {
        x = 100; // not executed
    }

    int *p = new int(25);
    if (p)
    {
        cout << *p << "\n"; // outputs 25
    }
    else
    {
        cout << "p is null!\n"; // executed if memory allocation fails
    }
}

Saída:

x < 11 is true!
25

instrução if com um inicializador

A partir do C++17, uma instrução if também pode conter uma expressão init-statement que declara e inicializa uma variável nomeada. Use essa forma da instrução if quando a variável for necessária apenas no escopo da instrução if. Específico da Microsoft: esse formulário está disponível a partir do Visual Studio 2017 versão 15.3 e requer pelo menos a opção /std:c++17 do compilador.

Exemplo

// Compile with /std:c++17

#include <iostream>
#include <mutex>
#include <map>
#include <string>
#include <algorithm>

using namespace std;

map<int, string> m{ {1, "one"}, {2, "two"}, {10,"ten"} };
mutex mx;
bool shared_flag = true; // guarded by mx
int getValue() { return 42; }

int main()
{
    if (auto it = m.find(10); it != m.end())
    {
        cout << it->second << "\n";
    }

    if (int x = getValue(); x == 42)
    {
        cout << "x is 42\n";
    }

    if (lock_guard<mutex> lock(mx); shared_flag)
    {
        cout << "setting shared_flag to false\n";
        shared_flag = false;
    }

    string s{ "if" };
    if (auto keywords = { "if", "for", "while" }; any_of(keywords.begin(), keywords.end(), [&s](const char* kw) { return s == kw; }))
    {
        cout << "Error! Token must not be a keyword\n";
    }
}

Saída:

ten
x is 42
setting shared_flag to false
Error! Token must not be a keyword

if instruções constexpr

A partir do C++17, você pode usar uma instrução if constexpr em modelos de função para tomar decisões de ramificação em tempo de compilação sem precisar recorrer a várias sobrecargas de função. Específico da Microsoft: esse formulário está disponível a partir do Visual Studio 2017 versão 15.3 e requer pelo menos a opção /std:c++17 do compilador.

Exemplo

Este exemplo mostra como você pode compilar condicionalmente um modelo com base no tipo enviado a ele:

// Compile with /std:c++17
#include <iostream>

template<typename T>
auto Show(T t)
{
    //if (std::is_pointer_v<T>) // Show(a) results in compiler error for return *t. Show(b) results in compiler error for return t.
    if constexpr (std::is_pointer_v<T>) // This statement goes away for Show(a)
    {
        return *t;
    }
    else
    {
        return t;
    }
}

int main()
{
    int a = 42;
    int* pB = &a;

    std::cout << Show(a) << "\n"; // prints "42"
    std::cout << Show(pB) << "\n"; // prints "42"
}

A instrução if constexpr é avaliada no momento da compilação e o compilador só gera código para o branch if, que corresponde ao tipo do argumento enviado ao modelo de função. Se você comentar a instrução if constexpr e cancelar o comentário da instrução if, o compilador gerará código para ambos os branches. Isso significa que você obtém um erro:

  • Se você chamar ShowValue(a);, receberá um erro em return *t porque t não é um ponteiro, mesmo que a instrução if seja falsa e o código nunca seja executado.
  • Se você chamar ShowValue(pB);, você receberá um erro return t porque t é um ponteiro, mesmo que a instrução if seja verdadeira e o código nunca seja executado.

O uso de if constexpr resolve esse problema porque somente a instrução que corresponde ao tipo do argumento enviado ao modelo de função é compilada.

Saída:

42
42

Confira também

Instruções de seleção
Palavras-chave
switch Instrução (C++)