A structured lesson workspace with readable content, hands-on examples, and a clean path to completion.
An if statement in C does not evaluate a boolean. C did not have a boolean type until C99, and even now, _Bool is just an integer that holds 0 or 1. What if actually checks is whether the expression is nonzero. Any nonzero value is true. Zero is false. This means if (x) is valid, if (ptr) is valid, and if (x = 5) compiles without error and is always true. That last one is not a typo in your code. It is an assignment, not a comparison, and it has caused more bugs than I can count.
#include <stdio.h>int main(void) {int temperature = 35;if (temperature > 30) {printf("It is hot outside.\n");} else if (temperature > 20) {printf("Pleasant weather.\n");} else {printf("Bring a jacket.\n");}return 0;}
The braces are technically optional for single-statement bodies. Technically. In practice, omitting them is how the goto fail bug happened in Apple's SSL stack in 2014. A second line that looked like it was inside the if was not. Always use braces. The two extra characters cost nothing and eliminate an entire category of bug.
When you nest ifs without braces, an else binds to the nearest unmatched if. Not the one you intended visually. The compiler does not care about your indentation.
#include <stdio.h>int main(void) {int a = 1;int b = 0;if (a)if (b)printf("Both true\n");elseprintf("This else belongs to the INNER if, not the outer one.\n");return 0;}
Read that output again. a is 1 (true), b is 0 (false), so the inner if fails and the else fires. But visually, the indentation suggests the else pairs with the outer if. Braces eliminate this ambiguity entirely. There is no performance cost. There is no style argument that justifies the risk.
#include <stdio.h>int main(void) {int x = 0;if (x = 5) {printf("This always prints. x is now %d\n", x);}return 0;}
GCC warns you, but only if -Wall is active. The assignment x = 5 evaluates to 5, which is nonzero, so the condition is always true. If you genuinely intend assignment in a condition (it happens in while loops reading input), wrap it in extra parentheses: if ((x = compute())) to silence the warning and signal intent to readers.
Conditionals are straightforward until they are not. The edge cases live in operator precedence, short-circuit evaluation, and the type system. We tackle logical operators next, where && and || interact with truthiness in ways that matter for both correctness and performance.
Finish the lesson once you have worked through the material. This awards ★ 20 XP.