select case
When a decision is really one value with several possibilities, select case says so: a list of cases, ranges of cases, and one default for everything left over.
One expression, a list of answers
select case (value) takes a single integer or character expression, and the case blocks below it list the values it might have. Exactly one block runs, the first whose list contains the value, and case default catches the rest. The block closes with end select.
There is no fallthrough: a matched case runs its statements and leaves the construct. That one difference from C makes a select case read like a table of outcomes rather than a sequence of traps, and it removes the forgotten break from the list of things to worry about.
The selector must be a scalar, so an array cannot be selected on directly. A common pattern is to compute a small code from the array first — the count of failures, or the index of the first match — and select on that integer. The cases then describe the outcomes, and the array work stays outside the construct.
Lists and ranges
A case can name several values (case (1, 7)), a range with both ends included (case (2:6)), or a mix of the two. The values are constants, not expressions, and they must be of the same type as the selector — integer cases for an integer, character literals for a character.
A single case list can mix the two forms, as in case (1, 3:5), which is often shorter than several separate cases. The compiler still checks each entry against the selector type, so a character literal in an integer list is an error rather than a case that never runs.
Because only one block runs, the order of the cases does not change the answer, which is a real advantage over an if chain where a badly ordered test silently takes the wrong branch. Cases that overlap are a mistake the compiler can often point at, since the later one could never run.
Case values are constants, which means a variable cannot appear in a case list even when its value never changes. integer, parameter :: limit = 10 is a constant and may be used; an ordinary integer may not. That rule is what lets the compiler compare the cases and warn about an overlap before the program runs.
When to use it, and when not to
select case is the right tool when the program is choosing between named outcomes of one value: a day number, a menu letter, a status code, a grade letter. It reads as a list, and a list is easy to check against a specification.
It is the wrong tool when the conditions are different questions — score >= 90 .and. attendance > 80 is not one value with cases, and forcing it into a select case produces something no one wants to read. Reach for if then, and keep select case for the flat decisions it was made for.
A weekday, from a number
select case (day)
case (1, 7)
kind = 'weekend'
case (2:6)
kind = 'weekday'
case default
kind = 'not a day'
end select
select case (trim(kind))
case ('weekend')
print *, 'no alarm today'
case default
print *, 'alarm at seven'
end selectThe selector is evaluated once
select case (expr) evaluates its selector once, at the top, and then compares that single value with each case list in order. The selector can be any integer or character expression, so select case (trim(command)) is legal and is the usual way to compare a fixed-length string without its padding. It cannot be a real or a logical.
Case ranges may be open at either end. case (:-1) matches every value at or below -1, case (1:) every value at or above 1, and the two together leave exactly zero for its own case. That is often clearer than listing numbers, and it keeps working when the input grows. Overlapping ranges are a mistake — a value that matches an earlier case never reaches the later one.
The default does not have to be last, though writing it last is the convention because it reads as "everything else".
Three errors defeat a select case: a case value of the wrong type, such as case ('1') for an integer selector; two cases that overlap so the second can never run; and a missing case default that leaves unexpected input with no branch at all. The first is a compile error, the second may be only a warning, and the third is silent: the construct simply does nothing.
Try these next
- Rewrite the grade chain from the decisions chapter as a
select caseonscore / 10. - Add open-ended cases for negative values and very large ones.
- Use a character selector with
trimand two commands of different lengths.
Eight days, three answers
Run it and follow the day numbers. Then change the range 2:6 to 2:5 and see which day falls through to the default, and add a case for the value 9.
A menu, and a range open at both ends
Run it and follow both selections. Then change `choice` to `'x'` and `level` to `0`, and add a case that catches the letters `a` and `b` together.
Always write the case default, even when you think every value is covered. It costs one line, and it is where the program says what it does with the input you did not expect.
Check what you learned
One question at a time. A wrong answer explains itself — take another go.
Part 1 of 5
How many case blocks run for one pass through a select case?
