if
statement used in programming languages like C/ C++, C#, Visual Basic .NET, Java and exists in most high-level imperative programming languages such as switch
, case
, select
or inspect
.
Switch statements come in two main variants: a structured switch, as in Pascal, which takes exactly one branch, and an unstructured switch, as in C, which functions as a type of goto. The main reasons for using a switch include improving clarity, by reducing otherwise repetitive coding, and (if the heuristics permit) also offering the potential for faster execution through easier compiler optimization in many cases.
History
In his 1952 text ''Introduction to Metamathematics'', Stephen Kleene formally proved that the CASE function (the IF-THEN-ELSE function being its simplest form) is a primitive recursive function, where he defines the notiondefinition by cases
in the following manner:
:"#F. The function φ defined thus
:: φ(x1 , ... , xn ) =
:::*φ1(x1 , ... , xn ) if Q1(x1 , ... , xn ),
:::* . . . . . . . . . . . .
:::*φm(x1 , ... , xn ) if Qm(x1 , ... , xn ),
:::*φm+1(x1 , ... , xn ) otherwise,
:where Q1 , ... , Qm are mutually exclusive predicates (or φ(x1 , ... , xn) shall have the value given by the first clause which applies) is primitive recursive in φ1, ..., φm+1, Q1, ..., Qm+1.
Kleene provides a proof of this in terms of the Boolean-like recursive functions "sign-of" sg( ) and "not sign of" ~sg( ) (Kleene 1952:222-223); the first returns 1 if its input is positive and −1 if its input is negative.
Boolos-Burgess-Jeffrey make the additional observation that "definition by cases" must be both mutually exclusive and collectively exhaustive. They too offer a proof of the primitive recursiveness of this function (Boolos-Burgess-Jeffrey 2002:74-75).
The IF-THEN-ELSE is the basis of the McCarthy formalism: its usage replaces both primitive recursion and the mu-operator.
Typical syntax
In most languages, programmers write a switch statement across many individual lines using one or two keywords. A typical syntax involves: * the firstselect
, followed by an expression which is often referred to as the ''control expression'' or ''control variable'' of the switch statement
* subsequent lines defining the actual cases (the values), with corresponding sequences of statements for execution when a match occurs
* In languages with fallthrough behaviour, a break
statement typically follows a case
statement to end said statement. ells* In some languages, e.g., PL/I, the control expression is optional; if there is no control expression then each alternative begins with a WHEN
clause containing a boolean expression and a match occurs for the first case for which that expression evaluates to true. This usage is similar to the if/then/elseif/else structures in some other languages, e.g., Perl.
* In some languages, e.g., Rexx, no control expression is allowed and each alternative begins with a WHEN
clause containing a boolean expression and a match occurs for the first case for which that expression evaluates to true.
Each alternative begins with the particular value, or list of values (see below), that the control variable may match and which will cause the control to goto the corresponding sequence of statements. The value (or list/range of values) is usually separated from the corresponding statement sequence by a colon or by an implication arrow. In many languages, every case must also be preceded by a keyword such as case
or when
.
An optional default case is typically also allowed, specified by a default
, otherwise
, or else
keyword. This executes when none of the other cases match the control expression. In some languages, such as C, if no case matches and the default
is omitted the switch
statement simply exits. In others, like PL/I, an error is raised.
Semantics
Semantically, there are two main forms of switch statements. The first form are structured switches, as in Pascal, where exactly one branch is taken, and the cases are treated as separate, exclusive blocks. This functions as a generalized if–then–elseFallthrough
In many languages, only the matching block is executed, and then execution continues at the end of the switch statement. These include thebreak
keyword at the end of the matching body, which exits execution of the switch block, but this can cause bugs due to unintentional fallthrough if the programmer forgets to insert the break
statement. This is thus seen by many as a language wart, and warned against in some lint tools. Syntactically, the cases are interpreted as labels, not blocks, and the switch and break statements explicitly change control flow. Some languages influenced by C, such as break
or return
unless the block is empty (i.e. fallthrough is used as a way to specify multiple values).
In some cases languages provide optional fallthrough. For example, Perl does not fall through by default, but a case may explicitly do so using a continue
keyword. This prevents unintentional fallthrough but allows it when desired. Similarly, ;;
, but allow fallthrough with ;&
or ;;&
instead.
An example of a switch statement that relies on fallthrough is Duff's device.
Compilation
Optimizing compilers such as GCC or Clang may compile a switch statement into either aAdvantages and disadvantages
In some languages and programming environments, the use of acase
or switch
statement is considered superior to an equivalent series of ''if else if'' statements because it is:
* Easier to debug (e.g. setting breakpoints on code vs. a call table, if the debugger has no conditional breakpoint capability)
* Easier for a person to read
* Easier to understand, and consequently easier to maintain
* Fixed depth: a sequence of "if else if" statements may yield deep nesting, making compilation more difficult (especially in automatically generated code)
* Easier to verify that all values are handled. Compilers can issue a warning if some enum values are not handled.
Additionally, an optimized implementation may execute much faster than the alternative, because it is often implemented by using an indexed Switch expressions
''Switch expressions'' are introduced in Java SE 12, 19 March 2019, as a preview feature. Here a whole switch expression can be used to return a value. There is also a new form of case label, where the right-hand-side is a single expression. This also prevents fall though and requires that cases are exhaustive. In Java SE 13 theyield
statement is introduced, and in Java SE 14 switch expressions becomes a standard language feature. For example:
Alternative uses
Many languages evaluate expressions insideswitch
blocks at runtime, allowing a number of less obvious uses for the construction. This prohibits certain compiler optimizations, so is more common in dynamic and scripting languages where the enhanced flexibility is more important than the performance overhead.
PHP
For example, in PHP, a constant can be used as the "variable" to check against, and the first case statement which evaluates to that constant will be executed:EVALUATE
statement. PL/I has an alternative form of the SELECT
statement where the control expression is omitted altogether and the first WHEN
that evaluates to ''true'' is executed.
Ruby
In Ruby, due to its handling of
equality, the statement can be used to test for variable’s class:
case
to have any parameters (acting a bit like an else if
statement):
Assembler
A switch statement in assembly language:Python
For Python 3.10.6,Exception handling
A number of languages implement a form of switch statement in exception handling, where if an exception is raised in a block, a separate branch is chosen, depending on the exception. In some cases a default branch, if no exception is raised, is also present. An early example is Modula-3, which use theTRY
...EXCEPT
syntax, where each EXCEPT
defines a case. This is also found in Delphi, Scala, and Visual Basic .NET.
Alternatives
Some alternatives to switch statements can be: * A series of ''if-else''case
values and, as values, the part under the case
statement.
::(In some languages, only actual data types are allowed as values in the lookup table. In other languages, it is also possible to assign functions as lookup table values, gaining the same flexibility as a real switch
statement. See switch
statements in the Lua language, which has no built-in switch
.Switch statement in Luaswitch
statements since many languages can optimize table lookups, whereas switch statements are not optimized unless the range of values is small with few gaps. A non-optimized, non- binary search lookup, however, will almost certainly be slower than either a non-optimized switch or the equivalent multiple ''if-else'' statements.
* A See also
* Algorithmic efficiency *References
Further reading
* Stephen Kleene, 1952 (10th reprint 1991), ''Introduction to Metamathematics'', North-Holland Publishing Company, Amsterdam NL, * George Boolos, John Burgess, and Richard Jeffrey, 2002, ''Computability and Logic: Fourth Edition'', Cambridge University Press, Cambridge UK, {{ISBN, 0-521-00758-5 paperback. cf page 74-75. Conditional constructs ru:Оператор ветвления#Переключатель (оператор множественного выбора)