Jump to content
 







Main menu
   


Navigation  



Main page
Contents
Current events
Random article
About Wikipedia
Contact us
Donate
 




Contribute  



Help
Learn to edit
Community portal
Recent changes
Upload file
 








Search  

































Create account

Log in
 









Create account
 Log in
 




Pages for logged out editors learn more  



Contributions
Talk
 



















Contents

   



(Top)
 


1 History  





2 Typical syntax  





3 Semantics  



3.1  Fallthrough  







4 Compilation  





5 Advantages and disadvantages  





6 Switch expressions  





7 Alternative uses  



7.1  PHP  





7.2  Ruby  





7.3  Assembler  





7.4  Python  





7.5  Exception handling  







8 Alternatives  





9 See also  





10 References  





11 Further reading  














Switch statement






العربية
Català
Dansk
Deutsch
Español
Esperanto
Français

Hrvatski
Íslenska
Italiano
Lombard

Norsk bokmål
Polski
Русский
Українська
Tiếng Vit

 

Edit links
 









Article
Talk
 

















Read
Edit
View history
 








Tools
   


Actions  



Read
Edit
View history
 




General  



What links here
Related changes
Upload file
Special pages
Permanent link
Page information
Cite this page
Get shortened URL
Download QR code
Wikidata item
 




Print/export  



Download as PDF
Printable version
 
















Appearance
   

 






From Wikipedia, the free encyclopedia
 


Incomputer programming languages, a switch statement is a type of selection control mechanism used to allow the value of a variable or expression to change the control flow of program execution via search and map.

Switch statements function somewhat similarly to the if statement used in programming languages like C/C++, C#, Visual Basic .NET, Java and exist in most high-level imperative programming languages such as Pascal, Ada, C/C++, C#,[1]: 374–375  Visual Basic .NET, Java,[2]: 157–167  and in many other types of language, using such keywordsasswitch, case, selectorinspect.

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.

Switch statement in C
switch (age) {
  case 1:  printf("You're one.");            break;
  case 2:  printf("You're two.");            break;
  case 3:  printf("You're three.");
  case 4:  printf("You're three or four.");  break;
  default: printf("You're not 1, 2, 3 or 4!");
}

History[edit]

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 notion "definition 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.

— Stephen Kleene, [3]

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.

The earliest Fortran compilers supported the computed GOTO statement for multi-way branching. Early ALGOL compilers supported a SWITCH data type which contains a list of "designational expressions". A GOTO statement could reference a switch variable and, by providing an index, branch to the desired destination. With experience it was realized that a more formal multi-way construct, with single point of entrance and exit, was needed. Languages such as BCPL, ALGOL-W, and ALGOL-68 introduced forms of this construct which have survived through modern languages.

Typical syntax[edit]

In most languages, programmers write a switch statement across many individual lines using one or two keywords. A typical syntax involves:

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 caseorwhen.

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 does nothing. In others, like PL/I, an error is raised.

Semantics[edit]

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–else conditional, here with any number of branches, not just two.

The second form are unstructured switches, as in C, where the cases are treated as labels within a single block, and the switch functions as a generalized goto. This distinction is referred to as the treatment of fallthrough, which is elaborated below.

Fallthrough[edit]

In many languages, only the matching block is executed, and then execution continues at the end of the switch statement. These include the Pascal family (Object Pascal, Modula, Oberon, Ada, etc.) as well as PL/I, modern forms of Fortran and BASIC dialects influenced by Pascal, most functional languages, and many others. To allow multiple values to execute the same code (and avoid needing to duplicate code), Pascal-type languages permit any number of values per case, given as a comma-separated list, as a range, or as a combination.

Languages derived from C language, and more generally those influenced by Fortran's computed GOTO, instead feature fallthrough, where control moves to the matching case, and then execution continues ("falls through") to the statements associated with the next case in the source text. This also allows multiple values to match the same point without any special syntax: they are just listed with empty bodies. Values can be special conditioned with code in the case body. In practice, fallthrough is usually prevented with a break 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[4] 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 JavaScript, retain default fallthrough, while others remove fallthrough, or only allow it in special circumstances. Notable variations on this in the C-family include C#, in which all blocks must be terminated with a breakorreturn 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, Bash defaults to not falling through when terminated with ;;, but allows fallthrough[5] with ;∨;& instead.

An example of a switch statement that relies on fallthrough is Duff's device.

Compilation[edit]

Optimizing compilers such as GCCorClang may compile a switch statement into either a branch table or a binary search through the values in the cases.[6] A branch table allows the switch statement to determine with a small, constant number of instructions which branch to execute without having to go through a list of comparisons, while a binary search takes only a logarithmic number of comparisons, measured in the number of cases in the switch statement.

Normally, the only method of finding out if this optimization has occurred is by actually looking at the resultant assemblyormachine code output that has been generated by the compiler.

Advantages and disadvantages[edit]

In some languages and programming environments, the use of a caseorswitch statement is considered superior to an equivalent series of ifelse if statements because it is:

Additionally, an optimized implementation may execute much faster than the alternative, because it is often implemented by using an indexed branch table.[7] For example, deciding program flow based on a single character's value, if correctly implemented, is vastly more efficient than the alternative, reducing instruction path lengths considerably. When implemented as such, a switch statement essentially becomes a perfect hash.

In terms of the control-flow graph, a switch statement consists of two nodes (entrance and exit), plus one edge between them for each option. By contrast, a sequence of "if...else if...else if" statements has an additional node for every case other than the first and last, together with a corresponding edge. The resulting control-flow graph for the sequences of "if"s thus has many more nodes and almost twice as many edges, with these not adding any useful information. However, the simple branches in the if statements are individually conceptually easier than the complex branch of a switch statement. In terms of cyclomatic complexity, both of these options increase it by k−1 if given k cases.

Switch expressions[edit]

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, case L-> where the right-hand-side is a single expression. This also prevents fall though and requires that cases are exhaustive. In Java SE 13 the yield statement is introduced, and in Java SE 14 switch expressions become a standard language feature.[8][9][10] For example:

int ndays = switch (month) {
    case JAN, MAR, MAY, JUL, AUG, OCT, DEC -> 31;
    case APR, JUN, SEP, NOV -> 30;
    case FEB -> {
        if (year % 400 == 0) yield 29;
        else if (year % 100 == 0) yield 28;
        else if (year % 4 == 0) yield 29;
        else yield 28; }
};

Alternative uses[edit]

Many languages evaluate expressions inside switch 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[edit]

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:

switch (true) {
    case ($x == 'hello'):
        foo();
        break;
    case ($z == 'howdy'): break;
}
switch (5) {
    case $x: break;
    case $y: break;
}

This feature is also useful for checking multiple variables against one value rather than one variable against many values. COBOL also supports this form (and others forms) in the 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[edit]

InRuby, due to its handling of === equality, the statement can be used to test for variable’s class:

case input
when Array then puts 'input is an Array!'
when Hash then puts 'input is a Hash!'
end

Ruby also returns a value that can be assigned to a variable, and doesn’t actually require the case to have any parameters (acting a bit like an else if statement):

catfood =
  case
  when cat.age <= 1
    junior
  when cat.age > 10
    senior
  else
    normal
  end

Assembler[edit]

A switch statement in assembly language:

switch:
  cmp ah, 00h
  je a
  cmp ah, 01h
  je b
  jmp swtend   ; No cases match or "default" code here
a:
  push ah
  mov al, 'a'
  mov ah, 0Eh
  mov bh, 00h
  int 10h
  pop ah
  jmp swtend   ; Equivalent to "break"
b:
  push ah
  mov al, 'b'
  mov ah, 0Eh
  mov bh, 00h
  int 10h
  pop ah
  jmp swtend   ; Equivalent to "break"
  ...
swtend:

Python[edit]

For Python 3.10.6, PEPs 634-636 were accepted, which added match and case keywords.[11][12][13][14] Unlike other languages, Python notably doesn't exhibit fallthrough behavior.

letter = input("Put in a single letter: ").strip()[0].casefold() # first non-whitespace character of the input, lowercase
match letter:
    case 'a' | 'e' | 'i' | 'o' | 'u': # Unlike conditions in if statements, the `or` keyword cannot be used here to differentiate between cases
        print(f"Letter {letter} is a vowel!")
    case 'y':
        print(f"Letter {letter} may be a vowel.")
    case _: # `case _` is equivalent to `default` from C and others
        print(f"Letter {letter} is not a vowel!")

Exception handling[edit]

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 the TRY...EXCEPT syntax, where each EXCEPT defines a case. This is also found in Delphi, Scala, and Visual Basic .NET.

Alternatives[edit]

Some alternatives to switch statements can be:

(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 Control table article for more detail on this).
Lua does not support case/switch statements.[15] This lookup technique is one way to implement switch statements in the Lua language, which has no built-in switch.[15]
In some cases, lookup tables are more efficient than non-optimized switch 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.[citation needed]

See also[edit]

References[edit]

  1. ^ Skeet, Jon (23 March 2019). C# in Depth. Manning. ISBN 978-1617294532.
  • ^ Bloch, Joshua (2018). "Effective Java: Programming Language Guide" (third ed.). Addison-Wesley. ISBN 978-0134685991.
  • ^ "Definition by cases", Kleene 1952:229
  • ^ van der Linden, Peter (1994). Expert C Programming: Deep C Secrets, p. 38. Prentice Hall, Eaglewood Cliffs. ISBN 0131774298.
  • ^ since version 4.0, released in 2009.
  • ^ Vlad Lazarenko. From Switch Statement Down to Machine Code
  • ^ Guntheroth, Kurt (April 27, 2016). Optimized C++. O'Reilly Media. p. 182. ISBN 9781491922033.
  • ^ "JEP 325: Switch Expressions (Preview)". openjdk.java.net. Retrieved 2021-04-28.
  • ^ "JEP 354: Switch Expressions (Second Preview)". openjdk.java.net. Retrieved 2021-04-28.
  • ^ "JEP 361: Switch Expressions". openjdk.java.net. Retrieved 2021-04-28.
  • ^ Galindo Salgado, Pablo. "What's New In Python 3.10". Python 3.10.6 documentation. Retrieved 2022-08-19.
  • ^ Bucher, Brandt; van Rossum, Guido (2020-09-12). "PEP 634 – Structural Pattern Matching: Specification". Python Enhancement Proposals. Retrieved 2022-08-19.
  • ^ Kohn, Tobias; van Rossum, Guido (2020-09-12). "PEP 635 – Structural Pattern Matching: Motivation and Rationale". Python Enhancement Proposals. Retrieved 2022-08-19.
  • ^ Moisset, Daniel F. "PEP 636 – Structural Pattern Matching: Tutorial". Python Enhancement Proposals. Retrieved 2022-08-19.
  • ^ a b Switch statement in Lua
  • Further reading[edit]


    Retrieved from "https://en.wikipedia.org/w/index.php?title=Switch_statement&oldid=1228734799"

    Category: 
    Conditional constructs
    Hidden categories: 
    Articles with short description
    Short description is different from Wikidata
    Articles needing additional references from April 2013
    All articles needing additional references
    Articles needing additional references from January 2017
    All articles with unsourced statements
    Articles with unsourced statements from October 2011
     



    This page was last edited on 12 June 2024, at 21:52 (UTC).

    Text is available under the Creative Commons Attribution-ShareAlike License 4.0; additional terms may apply. By using this site, you agree to the Terms of Use and Privacy Policy. Wikipedia® is a registered trademark of the Wikimedia Foundation, Inc., a non-profit organization.



    Privacy policy

    About Wikipedia

    Disclaimers

    Contact Wikipedia

    Code of Conduct

    Developers

    Statistics

    Cookie statement

    Mobile view



    Wikimedia Foundation
    Powered by MediaWiki