Quiz (if)

Quiz interativo sobre comandos if em C.

Questão 1 — Comportamento de if(a==10)

int a = 10;
if (a == 10) {
  printf("It's A\n");
  a = 20;
}
printf("a = %d\n", a);

O que isso imprime?

It's A
a = 20
It's A
a = 10
a = 20
Explicação: a==10 é verdadeiro → o corpo do if é executado → "It's A" é impresso → a é definido como 20 → o printf final mostra o valor atual (20).

Questão 2 — Pegadinha de if(a=10)

int a = 3;
if (a = 10) {    // = é atribuição! (queria ==)
  printf("entered\n");
}
printf("a = %d\n", a);

O que isso imprime?

a = 3 (o corpo do if é pulado)
entered
a = 10
Erro de compilação
Explicação: a = 10 é uma expressão de atribuição, e seu valor é 10 (diferente de zero, logo "verdadeiro"). O corpo do if é então executado, e a agora é 10, então o print final mostra a = 10.
O C não trata isso como erro por padrão (no máximo você recebe um aviso), e é por isso que é uma fonte clássica de bugs.

Questão 3 — Combinando E e OU

int x = 5;
if (x > 0 && x < 10 || x == 100) {
  printf("OK\n");
}

O que isso imprime?

OK
(nada)
Erro de compilação
Explicação: && tem precedência maior que ||, então isso equivale a (x>0 && x<10) || x==100.
Com x=5: (5>0 && 5<10) é verdadeiro → a expressão toda é verdadeira → "OK" é impresso.
Quando estiver em dúvida sobre precedência, adicione parênteses para deixar a intenção clara.

Questão 4 — O básico de if-else

int n = 7;
if (n > 5) {
  printf("big\n");
} else {
  printf("small\n");
}

O que isso imprime?

big
small
big
small (ambos)
(nada)
Explicação: Se a condição é verdadeira, o bloco if é executado; senão, o bloco else é executado — exatamente um dos dois é executado.
n=7 faz n > 5 ser verdadeiro → "big" é impresso, e o ramo else é pulado.

Questão 5 — Escada else if

Verifique várias condições em ordem. Apenas o primeiro ramo verdadeiro é executado.
int score = 75;
if (score >= 90) {
  printf("A\n");
} else if (score >= 70) {
  printf("B\n");
} else if (score >= 50) {
  printf("C\n");
} else {
  printf("D\n");
}

O que isso imprime?

A
B
C
B
C (ambos combinam)
Explicação: Numa escada else-if, a avaliação para assim que um ramo é verdadeiro.
score=75 não é ≥ 90 → a verificação seguinte >=70 é verdadeira → "B" é impresso → as condições restantes nunca são avaliadas.
As condições podem se sobrepor (são avaliadas de cima para baixo), então por convenção você coloca a mais restritiva primeiro.

Questão 6 — if sem chaves (uma armadilha)

Sem chaves { }, até onde vai o "alcance" do if?
int a = 5;
if (a > 10)
  printf("big\n");
  printf("always\n");   // cuidado com a indentação enganosa!

O que isso imprime?

always (só uma linha)
(nada)
big
always
big
Explicação: Sem chaves, um if executa condicionalmente apenas o único comando que vem logo depois dele.
Com a=5, a condição é falsa → printf("big"); é pulado.
O segundo printf("always"); fica fora do if, então sempre é executado — "always" é impresso (não se deixe enganar pela indentação!).
Lição: Sempre use chaves, mesmo quando o corpo for um único comando. Assim, adicionar uma segunda linha depois não introduz bugs silenciosamente.

Questão 7 — Comparando ponto flutuante com ==

Matematicamente, 0.1 + 0.2 = 0.3. Isso ainda é verdade em C?
double x = 0.1 + 0.2;
if (x == 0.3) {
  printf("equal\n");
} else {
  printf("not equal\n");
}

O que isso imprime?

equal
not equal
Erro de compilação
Explicação: Números de ponto flutuante são armazenados em binário, então 0.1 e 0.2 não podem ser representados exatamente.
O valor real de 0.1 + 0.2 dá 0.30000000000000004..., que não é exatamente 0.3. Resultado: not equal.
Lição: Não compare doubles com ==. Em vez disso, trate dois valores como iguais quando a diferença absoluta for pequena (ex.: fabs(x - 0.3) < 1e-9).

Questão 8 — Avaliação em curto-circuito (protegendo contra divisão por zero)

Quando o lado esquerdo de && é falso, o lado direito não é avaliado. Podemos usar isso para evitar dividir por zero?
int a = 10, b = 0;
if (b != 0 && a / b > 5) {
  printf("OK\n");
} else {
  printf("skip\n");
}

O que acontece?

"OK" é impresso
"skip" é impresso (não ocorre divisão por zero)
Trava com erro de divisão por zero
Erro de compilação
Explicação: && usa avaliação em curto-circuito. Assim que o lado esquerdo b != 0 é falso, o lado direito a / b nem é avaliado.
Nenhuma divisão por zero acontece, então o ramo else imprime "skip".
Padrão: Escrever "verificação de segurança && condição principal" cria uma proteção que evita o erro.
Obs.: se você inverter a ordem para a / b > 5 && b != 0, a divisão acontece primeiro e você cai no erro de divisão por zero. Sempre coloque a verificação de segurança primeiro.

Questão 9 — E se nenhum ramo combinar e não houver else?

Com apenas if / else if (sem else final), o que acontece quando nenhuma condição é verdadeira?
int x = 100;
if (x < 0) {
  printf("negative\n");
} else if (x < 10) {
  printf("small\n");
} else if (x < 50) {
  printf("medium\n");
}
printf("done\n");

O que isso imprime?

medium
done
done
(nada)
Erro de compilação
Explicação: x=100 não satisfaz nenhuma das condições (<0, <10, <50). Sem else, o bloco if simplesmente não faz nada e segue adiante.
O printf("done"); seguinte fica fora do if, então sempre é executado — só "done" é impresso.
Lição: Se você precisa de um caso "nenhum dos anteriores", escreva um else. Deixar de fora significa "não fazer nada quando nada combina".

Questão 10 — ifs independentes vs else if

Esses dois padrões parecem similares, mas se comportam de forma diferente. Compare os dois trechos abaixo.
// Padrão A: ligados com else if
int n = 50;
if (n > 0) {
  printf("positive\n");
} else if (n > 30) {
  printf("large\n");
}

// Padrão B: dois ifs independentes
if (n > 0) {
  printf("positive\n");
}
if (n > 30) {
  printf("large\n");
}

O que cada um imprime quando n=50?

A: positive / B: positive
A: positive / B: positive
large
A: positive
large / B: positive
large
A: positive
large / B: positive
Explicação: Essa é a diferença principal entre else if e ifs independentes.
Padrão A (else if): Só o primeiro ramo verdadeiro é executado. n=50 faz n>0 ser verdadeiro → imprime "positive" e para (n>30 nunca é verificado).
Padrão B (dois ifs independentes): Cada um é avaliado independentemente. n>0 é verdadeiro → "positive"; depois n>30 também é verdadeiro → "large". Ambas as linhas são impressas.
Qual usar? "Rodar exatamente um" → else if. "Verificar os dois de forma independente" → ifs separados.

Questão 11 — O else final é um "pega-tudo"

O else final em uma escada else-if é executado sempre que todas as condições anteriores forem falsas.
int grade = -5;
if (grade >= 90) {
  printf("Excellent\n");
} else if (grade >= 70) {
  printf("Good\n");
} else if (grade >= 50) {
  printf("Pass\n");
} else {
  printf("Fail\n");
}

O que imprime quando grade=-5 (valor negativo)?

Excellent
Pass
(nada)
Fail
Explicação: -5 falha em >=90, >=70 e >=50, então o else final é executado e "Fail" é impresso.
O else final captura tudo que não combinou com nenhuma condição anterior — é o pega-tudo.
Lição: Adicionar um else te dá tranquilidade de que valores inesperados (como -5 ou 999) ainda serão tratados em algum lugar.

Questão 12 — dangling else (a qual if pertence o else?)

Quando as chaves são omitidas, a qual if o else realmente pertence?
int a = 5, b = 10;
if (a > 0)
  if (b > 20)
    printf("both big\n");
  else
    printf("b is small\n");

O que isso imprime? (a indentação é irrelevante)

both big
b is small
(nada)
Erro de compilação
Explicação: A regra é que o else se liga ao if mais próximo (regra do dangling else).
A indentação faz parecer que o else pertence ao if externo, mas na verdade é o else do if (b > 20) interno.
a=5 (então a > 0 é verdadeiro) → entra no if interno → b=10 faz b > 20 ser falso → o ramo else imprime "b is small".
Lição: Com ifs aninhados, use chaves sempre. Elas eliminam completamente a ambiguidade.

Questão 13 — Um bug de classificação de notas (múltiplos ifs vs else if)

Queremos classificar uma pontuação como A / B / C. Aqui está um bug clássico.
// Código com bug: três ifs independentes
int score = 85;
if (score >= 90) {
  printf("A\n");
}
if (score >= 70) {
  printf("B\n");
}
if (score >= 50) {
  printf("C\n");
}

O que imprime quando score=85?

A
B
B
C
A
B
C
Explicação: Como os ifs são independentes, cada bloco cuja condição é verdadeira é executado.
Com score=85: ≥90 é falso → pulado / ≥70 é verdadeiro → "B" / ≥50 também é verdadeiro → "C". Resultado: B e C são impressos.

Forma correta (use else if):
if (score >= 90) {
  printf("A\n");
} else if (score >= 70) {
  printf("B\n");
} else if (score >= 50) {
  printf("C\n");
}
Agora a cadeia else-if executa apenas o primeiro ramo que combina, então score=85 imprime só "B".

Como escolher:
  • Condições mutuamente exclusivas (só uma deve se aplicar) → use else if.
  • Condições independentes (ambas podem ser verdadeiras e ambas devem rodar) → use ifs separados.

Aulas relacionadas

Condicionais
Comando if
Como funcionam os comandos if em C, visualizado com fluxogramas.
Operadores
Operadores de comparação e lógicos
Operadores de comparação (==, !=, <, >) e lógicos (&&, ||, !) em C.
← Aula anterior
Aula 13: Comando if
Próxima aula →
Aula 15: switch