Movatterモバイル変換


[0]ホーム

URL:


Jump to content
WikipediaThe Free Encyclopedia
Search

Switch statement

From Wikipedia, the free encyclopedia
Programming statement for branching control based on a value
icon
This articleneeds additional citations forverification. Please helpimprove this article byadding citations to reliable sources. Unsourced material may be challenged and removed.
Find sources: "Switch statement" – news ·newspapers ·books ·scholar ·JSTOR
(April 2013) (Learn how and when to remove this message)

Incomputer programming, aswitch statement is a selectioncontrol flow mechanism that changes execution control based on the value of anexpression (i.e. evaluation of avariable). A switch statement is similar to anif statement but instead of branching only on true or false, it branches on any number of values. Although the syntax varies byprogramming language, mostimperative languages provide a statement with thesemantics described here as the switch statement. Often denoted with thekeywordswitch, some languages use variations such ascase,select, orinspect.

Value

[edit]

Sometimes, use of a switch statement is considered superior to an equivalent series of if-then-else statements because it is:

Easier to understand
And consequently easier to maintain: at least partially since it's fixed depth.
Easier to debug
For example, setting breakpoints on code vs. a call table, if the debugger has no conditional breakpoint capability.
Easier to verify
that all values are handled since a compiler can warn if a value is not handled.
Can execute faster
Anoptimized implementation may execute much faster because it is often implemented as abranch table.[1] When implemented as such, a switch statement embodies aperfect hash.
Anoptimizing compiler such asGCC orClang may compile a switch statement into either abranch table or abinary search.[2] A branch table allows the program to determine which branch to execute with a single calculation instead of comparing values in a sequence. A binary search takes only a logarithmic number of comparisons, measured in the number of cases in the switch statement. Generally, the only way to determine whether the code was optimized in this way, is by analyzing the compiler output such asassembly ormachine code.
Less complex
In terms of acontrol-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-then-else 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, without adding useful information.

Elements

[edit]

Typically, a switch statement involves:

Verb
Starts with a control verb such asselect which is followed by an expression which is often a variable name; thecontrol expression orcontrol variable.
Cases
Subsequent branch alternative sections each start with a keyword (i.e.case) plus a value (or multiple values) along with code to execute for the value(s). In some languages, i.e.PL/I andRexx, if the control expression is omitted then each alternative begins with awhen clause containing a Boolean expression and a match occurs for the first case for which that expression evaluates true; similar to an if-then-else structure.
In a language with fall through behavior, such as C, each section ends with a keyword (such asbreak) if that section shouldnot fall through.
Default
An optional default case is typically allowed; often via a keyword such asdefault,otherwise, orelse. Control branches to this section when none of the other cases match the control expression. In some languages, such as C, if no case matches and the default section is omitted, the statement does nothing, but in others, like PL/I, an error occurs.

Fall through

[edit]

Two main variations of the switch statement includeunstructured which supportsfall through andstructured which does not.

For a structured switch, as inPascal-like languages, control jumps from the start of the switch statement to the selected case and at the end of the case, control jumps to the end of the switch statement. This behaves like an if–then–elseconditional but supports branching on more than just true and false values. To allow multiple values to execute the same code (avoidingduplicate code), the syntax permits multiple values per case.

An unstructured switch, as inC (and more generally languages influenced by Fortran'scomputed goto), acts likegoto. Control branches from the start of the switch to a case section and then control continues until either a block exit statement or the end of the switch statement. When control branches to one case, but continues into the subsequent branch, the control flow is calledfall through, and allows branching to the same code for multiple values.

Fall through is prevented by ending a case with a keyword (i.e.break), but a common mistake is to accidentally omit the keyword; causing unintentional fall through and often abug. Therefore, many consider this language feature to be dangerous,[3] and often fall through code results in a warning from a code quality tool such aslint.

Some languages, such asJavaScript, retain fall through semantics, while others exclude or restrict it. Notably, in C# all blocks must be terminated withbreak orreturn unless the block is empty which limits fall through only for branching from multiple values.

In some cases, languages provide optional fall through. For example,Perl does not fall through by default, but a case may explicitly do so using acontinue keyword; preventing unintentional fall through. Similarly,Bash defaults to not falling through when terminated with;;, but allows fall through[4] with;& or;;& instead.

An example of a switch statement that relies on fall through isDuff's device.

Case expression evaluation

[edit]

Some languages allow for a complex case expression (not just a static value); allowing for more dynamic branching behavior. This prohibits certain compiler optimizations, so is more common in dynamic languages where flexibility is prioritized over performance.

For example, inPHP andRuby, a constant can be used as the control expression, and the first case statement that evaluates to match that constant is executed. In the following PHP code, the switch expression is simply the true value, so the first case expression that is true is the one selected.

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

This feature is also useful for checking multiple variables against one value rather than one variable against many values.

switch(5){case$x:break;case$y:break;}

COBOL also supports this form via itsEVALUATE statement. PL/I supports similar behavior by omitting the control expression, and the firstWHEN expression that evaluates as true is executed.

In Ruby, due to its handling of=== equality, the case expression can be used to test a variable’s class. For example:

caseinputwhenArraythenputs'input is an Array!'whenHashthenputs'input is a Hash!'end

Result value

[edit]

Some languages support evaluating a switch statement to a value.

Case expression

[edit]

Thecase expression is supported by languages dating at least as far back asALGOL-W.[5] In ALGOL-W, an integer expression was evaluated, which then evaluated the desired expression from a list of expressions:

J:=caseIof(3.14,2.78,448.9);A:=caseDECODE(C)-128of("A","B","C","D","E","F");

Other languages supporting the case expression includeSQL,Standard ML,Haskell,Common LISP, andOxygene.

Switch expression

[edit]

Theswitch expression (introduced inJava SE 12) evaluates to 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 through and requires that cases are exhaustive. In Java SE 13 theyield statement is introduced, and in Java SE 14 switch expressions become a standard language feature.[6][7][8] For example:

intndays=switch(month){caseJAN,MAR,MAY,JUL,AUG,OCT,DEC->31;caseAPR,JUN,SEP,NOV->30;caseFEB->{if(year%400==0)yield29;elseif(year%100==0)yield28;elseif(year%4==0)yield29;elseyield28;}};

Ruby also supports these semantics. For example:

catfood=casewhencat.age<=1juniorwhencat.age>10seniorelsenormalend

Exception handling

[edit]

A number of languages implement a form of switch statement inexception 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 isModula-3, which use theTRY...EXCEPT syntax, where eachEXCEPT defines a case. This is also found inDelphi,Scala, andVisual Basic .NET.

Examples

[edit]

C

[edit]

The following code is a switch statement in C. Ifage is 1, it outputs "You're one.". Ifage is 3, it outputs "You're three. You're three or four.".

switch(age){case1:printf("You're one.");break;case2:printf("You're two.");break;case3:printf("You're three.");case4:printf("You're three or four.");break;default:printf("You're not 1, 2, 3 or 4!");}

Python

[edit]

Python (starting with 3.10.6) supports thematch andcase keywords.[9][10][11][12] It doesn't allow fall through. Unlike if statement conditions, theor keyword cannot be used to differentiate between cases.case _ is equivalent todefault in C.

letter=input("Enter a letter: ").strip()[0].casefold()matchletter:case"a"|"e"|"i"|"o"|"u":print(f"Letter{letter} is a vowel!")case"y":print(f"Letter{letter} may be a vowel.")case_:print(f"Letter{letter} is not a vowel!")

Pascal

[edit]

The following is an example inPascal:

casesomeCharof'a':actionOnA;'x':actionOnX;'y','z':actionOnYandZ;elseactionOnNoMatch;end;

In theOxygene dialect of Pascal, a switch statement can be used as an expression:

vari:Integer:=casesomeCharof'a':10;'x':20;'y':30;else-1;end;

Shell script

[edit]

The following is an example inShell script:

case$someCharina)actionOnA;;;x)actionOnX;;;[yz])actionOnYandZ;;;*)actionOnNoMatch;;esac

Assembler

[edit]

A switch statement inassembly language:

switch:cmpah,00hjeacmpah,01hjebjmpswtend; No cases match or "default" code herea:pushahmoval,'a'movah,0Ehmovbh,00hint10hpopahjmpswtend; Equivalent to "break"b:pushahmoval,'b'movah,0Ehmovbh,00hint10hpopahjmpswtend; Equivalent to "break"...swtend:

Alternatives

[edit]

Some alternatives to using a switch statement include:

if-then-else
A series of if-then-elseconditionals can test for each case value; one at a time. Fall through can be achieved with a sequence of if conditionals each without the else clause.
Control table
The logic of a switch statement can be encoded as acontrol table (a form oflookup table) that is keyed by the case values and each value encodes what is otherwise in the case section – as afunction pointer oranonymous function or similar mechanism.
In a language that does not provide a switch statement, such asLua,[13] a control table provides a way to implement switch statement semantics while enabling runtime efficiency that if-then-else does not.
Pattern matching
Pattern matching is switch-like functionality used in manyfunctional programming languages.

History

[edit]

In his 1952 textIntroduction to Metamathematics,Stephen Kleene formally proves that the case function (the if-then-else function being its simplest form) is aprimitive 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,[14]

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 bothmutually exclusive andcollectively 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 theMcCarthy formalism: its usage replaces both primitive recursion and themu-operator.

The earliestFortran compilers supported thecomputed goto statement for multi-way branching. EarlyALGOL 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 asBCPL,ALGOL-W, andALGOL-68 introduced forms of this construct which have survived through modern languages.

See also

[edit]

References

[edit]
  1. ^Guntheroth, Kurt (April 27, 2016).Optimized C++. O'Reilly Media. p. 182.ISBN 9781491922033.
  2. ^Vlad Lazarenko.From Switch Statement Down to Machine Code
  3. ^van der Linden, Peter (1994).Expert C Programming: Deep C Secrets, p. 38. Prentice Hall, Eaglewood Cliffs.ISBN 0131774298.
  4. ^sinceversion 4.0, released in 2009.
  5. ^Wirth, Niklaus;Hoare, C. A. R. (June 1966)."A contribution to the development of ALGOL".Communications of the ACM.9 (6):413–432.doi:10.1145/365696.365702.S2CID 11901135. Retrieved2020-10-07 – viaAssociation for Computing Machinery.
  6. ^"JEP 325: Switch Expressions (Preview)".openjdk.java.net. Retrieved2021-04-28.
  7. ^"JEP 354: Switch Expressions (Second Preview)".openjdk.java.net. Retrieved2021-04-28.
  8. ^"JEP 361: Switch Expressions".openjdk.java.net. Retrieved2021-04-28.
  9. ^Galindo Salgado, Pablo."What's New In Python 3.10".Python 3.10.6 documentation. Retrieved2022-08-19.
  10. ^Bucher, Brandt;van Rossum, Guido (2020-09-12)."PEP 634 – Structural Pattern Matching: Specification".Python Enhancement Proposals. Retrieved2022-08-19.
  11. ^Kohn, Tobias; van Rossum, Guido (2020-09-12)."PEP 635 – Structural Pattern Matching: Motivation and Rationale".Python Enhancement Proposals. Retrieved2022-08-19.
  12. ^Moisset, Daniel F."PEP 636 – Structural Pattern Matching: Tutorial".Python Enhancement Proposals. Retrieved2022-08-19.
  13. ^Switch statement in Lua
  14. ^"Definition by cases", Kleene 1952:229

Further reading

[edit]
Retrieved from "https://en.wikipedia.org/w/index.php?title=Switch_statement&oldid=1324253206"
Category:
Hidden categories:

[8]ページ先頭

©2009-2025 Movatter.jp