If / Else if / Else
If we have several mutually exclusive conditions (meaning it’s impossible for more than one to be true at the same time) and we want to run different blocks of code for each, we use if / else if blocks.
In this case, an additional else block is still optional: using if / else if doesn’t mean we’re required to add an else, but we can include one if we want to handle the case where none of the conditions were met.
if (Boolean expression 1){
The code inside this block runs only if Boolean Expression 1 returns true
} else if (Boolean expression 2){
The code inside this block runs only if Boolean Expression 2 returns true and the previous one returns false
} …
else if (Boolean expression N){
This runs only if Boolean Expression N returns true and all the previous ones return false
} else {
runs only if all previous expressions return false
}
|
|
fig. If else if else
Building on the previous example, we can now check the following: even if the user didn’t beat the time record, maybe they beat the total score. If neither condition is true, we’ll display an encouraging message:
better_time_score.zig |
|
const std = @import("std"); const print = std.debug.print; pub fn main() void { const n_time_record = 10.0; const n_time = 11.0; const n_record = 1200; const n_score = 3000; if (n_time < n_time_record) { print("Congratulations! With your time: {} you’ve beaten the previous record ({}).\n", .{ n_time, n_time_record }); } else if (n_score > n_record) { print("Even though your time wasn’t better, you scored more points ({}) than before ({})\n", .{ n_score, n_record }); } else { print("Keep trying to improve neither your time nor your score beat the previous record.\n", .{}); }
} |
|
$ zig run better_time_score.zig |
|
Even though your time wasn’t better, you scored more points (3000) than before (1200). |
We can add as many else if blocks as we want. Just keep in mind that for any of them to run, their conditions must be mutually exclusive and written in the correct order.
An example of a poorly written condition would be the following:
better_score_error.zig |
|
const std = @import("std"); const print = std.debug.print; pub fn main() void { const n_record = 1200; const n_score = 5000; if (n_record < n_score) { print("Your score {} is higher than the record ( {} )\n", .{ n_score, n_record }); } else if (n_score > 4000) { print("Your score {} is impossible.\nYou cheated!\n", .{ n_score }); } } |
|
$ zig run better_score_error.zig |
|
Your score 5000 is higher than the record (1200) |
We can see that the supposed cheater gets away with it, all because the condition that checks for an impossible score was placed after the one that checks if the record was beaten. Remember: an else if block only runs if all the previous conditions returned false. So that block will never be executed. Do you see the possible solution now?
By changing the order of the conditions:
|
if (n_score > 4000) { print("Your score {} is impossible.\nYou cheated!\n", .{ n_score }); } else if (n_record < n_score){ print("Your score {} is higher than the record ( {} )\n", .{ n_score, n_record }); } |
Now we first check whether the score is impossible, and then whether the record was beaten. Only one of the messages will be shown.
