스위치 스테이트먼트

Switch statement

컴퓨터 프로그래밍 언어에서 switch 문은 변수 또는 식 값이 검색 및 맵을 통해 프로그램 실행의 제어 흐름을 변경할 수 있도록 하는 데 사용되는 선택 제어 메커니즘의 한 종류입니다.

switch 문은 다음과 같이 기능합니다.ifC/C++, C#, Visual Basic 등의 프로그래밍 언어에서 사용되는 문.NET, Java 및 Pascal, Ada, C/C++, C#, Visual Basic 등 대부분의 고급 명령형 프로그래밍 언어로 존재합니다.NET, Java기타 많은 유형의 언어로 다음과 같은 키워드를 사용합니다.switch,case,select또는inspect.

스위치 문에는 크게 두 가지 종류가 있습니다.Pascal에서는 정확히 1개의 브랜치를 사용하는 구조화 스위치와 C에서는 goto의 일종으로 기능하는 비구조화 스위치입니다.스위치를 사용하는 주된 이유로는 명확성 향상, 반복 부호화 감소, 그리고 (휴리스틱에 의해 허용된 경우) 많은 경우 컴파일러 최적화를 보다 쉽게 으로써 보다 빠른 실행 가능성을 제공하는 것이 있습니다.

C의 스위치문
전환하다 (나이) {   사례. 1:  인쇄물("넌 하나야");            브레이크.;   사례. 2:  인쇄물("너희 둘이야");            브레이크.;   사례. 3:  인쇄물("너희들은 세 살이야.");   사례. 4:  인쇄물("넌 서너 살이야");  브레이크.;   체납: 인쇄물("1,2,3,4 아니야!"); } 

역사

스티븐 클린은 1952년 메타수학 입문서에서 CASE 함수(IF-THEN-ELSE 함수가 가장 단순한 형태)가 원시 재귀 함수라는 것을 공식적으로 증명했고, 여기서 그는 개념을 정의했다.definition by cases다음과 같은 방법으로 합니다.

"#F. 함수는 다음과 같이 정의됩니다.
φ1 ( x , ... , xn ) =
  • Q111(x, ..., xnn)의1 경우 (x , ... , x ) 。
  • . . . . . . . . . . . .
  • Qm11(x, ..., xnn)의m 경우 (x , ... , x ) 。
  • (x1, ..., xn ) 이외의 경우m+1
여기서1 Q, ..., Q는m 상호 배타적인 술어이다(또는 (x, ..., xn)는1 적용되는 첫 번째 절에 의해 주어진 값을 가져야 한다).는1 ,, ..., ,, Qm+11, ..., [1]Q의m+1 원시 재귀이다.

클린은 부울과 같은 재귀 함수 "sign-of" sg( )와 "not sign of" ~sg( )(Kleene 1952:222-223)의 관점에서 이에 대한 증거를 제공한다.첫 번째는 입력이 양이면 1을 반환하고 입력이 음이면 -1을 반환한다.

Boulos-Burgess-Jeffrey는 "사례에 의한 정의"는 상호 배타적이고 집단적으로 포괄적이어야 한다는 추가적인 관찰을 한다.그들은 또한 이 함수의 원시적 재귀성의 증거를 제공한다(Boolos-Burgess-Jeffrey 2002:74-75).

IF-THEN-ELSE는 McCarthy 형식주의의 기초입니다: 그것의 사용은 원시 재귀와 mu-operator를 모두 대체합니다.

표준 구문

대부분의 언어에서 프로그래머는 1개 또는2개의 키워드를 사용하여 여러 줄에 걸쳐 스위치문을 작성합니다.일반적인 구문은 다음과 같습니다.

  • 첫 번째select그 뒤에 종종 스위치스테이트먼트제어식 또는 제어변수라고 불리는 표현식이 계속됩니다.
  • 실제 케이스(값)를 정의하는 후속 행으로, 일치가 발생했을 때 실행할 수 있는 문장의 시퀀스를 포함한다.
  • 폴스루 동작이 있는 언어에서는break보통 뒤에 있는 스테이트먼트case해당 스테이트먼트를 종료하는 스테이트먼트.[글쎄요]
  • 예를 들어 PL/I와 같은 일부 언어에서 제어식은 옵션입니다. 제어식이 없는 경우 각 대안은 다음 문자로 시작합니다.WHEN부울식과 일치가 포함된 절은 해당 표현이 true로 평가되는 첫 번째 경우에 대해 발생합니다.이 사용법은 Perl 등 일부 다른 언어의 if/then/elseif/else 구조와 유사합니다.
  • 일부 언어(: Rexx)에서는 제어 표현은 허용되지 않으며 각 대안은 다음과 같이 시작됩니다.WHEN부울식과 일치가 포함된 절은 해당 표현이 true로 평가되는 첫 번째 경우에 대해 발생합니다.

각 대안은 제어 변수가 일치할 수 있는 특정 값 또는 값 목록(아래 참조)에서 시작되며, 제어가 해당 문장의 시퀀스를 가져오게 됩니다.값(또는 값의 목록/범위)은 일반적으로 콜론 또는 암시 화살표로 해당 문장과 구분됩니다.많은 언어에서 모든 경우 앞에 다음과 같은 키워드가 있어야 합니다.case또는when.

옵션 디폴트 케이스도 일반적으로 허용되며,default,otherwise, 또는else키워드를 지정합니다.이것은 다른 케이스가 모두 제어식과 일치하지 않을 때 실행됩니다.C와 같은 일부 언어에서는 대소문자가 일치하지 않으면default생략되어 있습니다.switch문은 단순히 종료됩니다.PL/I와 같은 다른 경우에는 오류가 발생합니다.

의미론

의미론적으로 switch 문에는 크게 두 가지 형식이 있습니다.

첫 번째 형태는 Pascal에서와 같이 구조화된 스위치로, 정확히 하나의 분기가 사용되며 케이스는 별도의 배타적 블록으로 취급됩니다.이는 2개뿐 아니라 임의의 수의 분기를 가진 일반화된 if-else 조건으로서 기능합니다.

두 번째 형태는 C와 같이 구조화되지 않은 스위치로 케이스는 단일 블록 내의 라벨로 처리되며 스위치는 일반화된 goto로 기능합니다.이 구별은 폴스루 처리라고 불리며, 아래에 자세히 설명되어 있습니다.

폴스루

많은 언어에서 일치하는 블록만 실행되며 스위치 문의 마지막에 실행이 계속됩니다.여기에는 파스칼 어족(오브젝트 파스칼, 모듈라, 오베론, 아다 등)만 아니라 PL/I, 파스칼의 영향을 받은 현대식 Fortran BASIC 방언, 대부분의 기능적 언어 등이 포함됩니다.여러 값이 동일한 코드를 실행할 수 있도록(및 코드 중복을 피할 필요가 없도록) Pascal 유형 언어에서는 쉼표로 구분된 목록, 범위 또는 조합으로 지정된 대소문자당 임의의 수의 값을 허용합니다.

C 언어에서 파생된 언어 및 Fortran의 계산된 GOTO에 의해 영향을 받은 언어는 대신 fall through 기능을 갖추고 제어가 일치하는 대소문자로 이동한 후 소스 텍스트의 다음 대소문자와 관련된 문장으로 계속 실행됩니다("fall through").또한 특별한 구문 없이 여러 개의 값이 동일한 점과 일치할 수 있습니다. 즉, 빈 본문으로 나열될 뿐입니다.케이스 본문의 코드를 사용하여 값을 특수하게 조정할 수 있습니다.실제로 폴스루(fallthrough)는 보통 다음과 같은 방법으로 예방됩니다.break스위치 블록의 실행을 종료하는 일치 본문 끝에 있는 키워드입니다.단, 프로그래머가 이 명령어를 삽입하는 것을 잊으면 의도하지 않은 폴스루로 인해 버그가 발생할 수 있습니다.break진술.따라서 많은 사람들이[2] 이를 언어 사마귀로 보고 일부 보풀 도구에서 경고합니다.통사적으로 케이스는 블록이 아닌 라벨로 해석되며 스위치 및 브레이크스테이트먼트에 의해 컨트롤 플로우가 명시적으로 변경됩니다.JavaScript와 같이 C의 영향을 받는 언어 중에는 기본 폴스루를 유지하는 것도 있고 폴스루를 제거하거나 특수한 경우에만 허용하는 것도 있습니다.C 패밀리에서 이에 대한 주목할 만한 변형으로는 C#있습니다.C#에서는 모든 블록은 다음과 같이 끝납니다.break또는return블록이 비어 있지 않은 경우(즉, 폴스루(fallthrough)가 여러 값을 지정하는 방법으로 사용됨).

경우에 따라서는 언어가 옵션 폴스루를 제공합니다.예를 들어 Perl은 디폴트로는 실패하지 않지만 다음 명령어를 사용하여 명시적으로 실패할 수 있습니다.continue키워드를 지정합니다.이렇게 하면 의도하지 않은 폴스루를 방지할 수 있지만 필요할 때 폴스루를 수행할 수 있습니다.마찬가지로 Bash는 디폴트로 다음과 같이 종료되면 falling through 하지 않습니다.;;, 단, 의 폴스루[3](fall through는;&또는;;&대신.

폴스루(fall through)에 의존하는 스위치 스테이트먼트의 예로는 Duff의 디바이스가 있습니다.

컴파일

GCCClang 등의 컴파일러를 최적화하면 스위치 문을 브랜치테이블 또는 바이너리 검색으로 컴파일 할 수 있습니다.[4]브랜치 테이블을 사용하면 스위치스테이트먼트는 비교 목록을 거치지 않고 실행할 브랜치를 소수의 일정한 명령으로 결정할 수 있습니다.또한 바이너리 검색에서는 스위치스테이트먼트의 케이스 수로 측정되는 비교의 로그 수 밖에 없습니다.

일반적으로 이 최적화가 발생했는지 여부를 확인하는 유일한 방법은 컴파일러에 의해 생성된 어셈블리 또는 머신 코드 출력을 실제로 보는 것입니다.

장점과 단점

언어 및 프로그래밍 환경에 따라서는case또는switch스테이트먼트는 다음과 같은 이유로 if 스테이트먼트의 동등한 시리즈보다 우수한 으로 간주됩니다.

  • 디버깅이 용이함(예를 들어 디버거에 조건부 브레이크포인트 기능이 없는 경우 코드와 콜테이블의 브레이크포인트 설정)
  • 사람이 읽기 쉽다
  • 이해하기 쉽고, 결과적으로 유지보수가 용이함
  • 고정 깊이: 일련의 "if other if" 스테이트먼트가 깊은 중첩을 일으켜 컴파일을 더욱 어렵게 할 수 있습니다(특히 자동으로 생성되는 코드).
  • 모든 값이 처리되었는지 확인하기 쉽습니다.컴파일러는 일부 열거값이 처리되지 않으면 경고를 발행할 수 있습니다.

또한 최적화된 구현은 색인화된 분기 테이블을 [5]사용하여 구현되는 경우가 많기 때문에 다른 구현보다 훨씬 빠르게 실행될 수 있습니다.예를 들어, 한 문자의 값을 기반으로 프로그램 흐름을 결정하는 것이 올바르게 구현되어 있는 경우 대체 문자보다 훨씬 더 효율적이며, 명령 경로 길이를 상당히 줄일 수 있습니다.이와 같이 실장되어 있는 경우, switch 문은 기본적으로 완전한 해시가 됩니다.

제어 흐름 그래프에 관해 스위치문은 2개의 노드(입구와 출구)와 옵션별로 이들 노드 사이에1개의 엣지로 구성됩니다.반면, 일련의 "if...else if...else if...else if" 문에는 첫 번째와 마지막 이외의 모든 경우에 대응하는 에지와 함께 추가 노드가 있습니다.따라서 "if" 시퀀스에 대한 결과적인 제어 흐름 그래프에는 더 많은 노드와 거의 두 배의 에지가 있으며, 이러한 그래프에는 유용한 정보가 추가되지 않습니다.단, if 스테이트먼트의 단순한 브랜치는 스위치스테이트먼트의 복잡한 브랜치보다 개념적으로 간단합니다.사이클로매틱 복잡성의 관점에서, 이 두 가지 옵션은 k개의 사례가 주어진 경우 k-1만큼 증가시킨다.

스위치식

스위치식은 Java SE 12, 2019년 3월 19일 프리뷰 기능으로 도입되었습니다.여기서는 스위치식 전체를 사용하여 값을 반환할 수 있습니다.케이스 라벨의 새로운 형태도 있습니다.case L->여기서 오른쪽은 하나의 표현입니다.이것은 또한 추락을 방지하고 케이스가 철저해야 합니다.Java SE 13에서는yield스테이트먼트가 도입되어 Java SE 14에서는 스위치 표현이 표준 언어 [6][7][8]기능이 됩니다.예를 들어 다음과 같습니다.

인트 ndays = 전환하다() {     사례. , 마아, 그럴지도 모른다, , 8월, OCT, DEC -> 31;     사례. APR, , SEP, 11월 -> 30;     사례. 2월 -> {         한다면 (연도 % 400 == 0) 산출하다 29;         또 다른 한다면 (연도 % 100 == 0) 산출하다 28;         또 다른 한다면 (연도 % 4 == 0) 산출하다 29;         또 다른 산출하다 28; } }; 

대체 용도

많은 언어가 내부 표현을 평가합니다.switch블록은 런타임에 실행되므로, 시공에 대해 명확하지 않은 여러 가지 용도가 높습니다.이는 특정 컴파일러 최적화를 금지하기 때문에 성능 오버헤드보다 향상된 유연성이 더 중요한 동적 언어 및 스크립트 언어에서 더 일반적입니다.

PHP

예를 들어, PHP에서는 상수를 체크할 "변수"로 사용할 수 있으며, 이 상수에 대해 평가되는 첫 번째 케이스 스테이트먼트가 실행됩니다.

전환하다 (진실의) {     사례. (x달러 == '안녕하세요'):         후우();         브레이크.;     사례. (z달러 == '안녕'): 브레이크.; } 전환하다 (5) {     사례. x달러: 브레이크.;     사례. $y: 브레이크.; } 

또한 이 기능은 하나의 변수와 여러 값을 비교하는 것이 아니라 하나의 값을 기준으로 여러 변수를 확인하는 데도 유용합니다.COBOL은 또한 이 형식(및 기타 형식)을 지원합니다.EVALUATE진술.PL/I의 대체 형식은 다음과 같습니다.SELECT제어식이 모두 생략되어 첫 번째 문WHENtrue로 평가된 값이 실행됩니다.

루비

루비에서는, 그 취급에 의해===equality. 명령문은 변수의 클래스를 검정하는 데 사용할 수 있습니다.

사례. 입력 언제 어레이 그리고나서 놓다 'input is 」 언제 해시 그리고나서 놓다 입력은 해시입니다! 끝. 

Ruby는 변수에 할당할 수 있는 값도 반환하며, 실제로 이 값은 필요하지 않습니다.case(어느 정도) 매개 변수가 있다else if스테이트먼트):

캣푸드 =   사례.   언제 고양이.나이 <=> 1     부하의   언제 고양이.나이 > 10     선배   또 다른     보통의   끝. 

어셈블러

어셈블리 언어로 된 스위치 문:

스위치:   cmp 아., 00h    a   cmp 아., 01h    b   jmp 스텐드   ; 여기에 일치하는 대소문자가 없거나 "기본" 코드가 없습니다. a:   밀다 아.   움직이다 , 'a'   움직이다 아., 0에   움직이다 bh, 00h   인트 10시간    아.   jmp 스텐드   ; "break"에 상당한다. b:   밀다 아.   움직이다 , 'b'   움직이다 아., 0에   움직이다 bh, 00h   인트 10시간    아.   jmp 스텐드   ; "break"에 상당한다.   ... 소프트웨어: 

예외 처리

많은 언어가 예외 처리에서 스위치문 형식을 구현하고 있으며, 블록 내에서 예외가 발생하면 예외에 따라 별도의 분기가 선택됩니다.예외가 발생하지 않는 경우 기본 분기도 있습니다.초기 예는 Modula-3로, 이 예에서는TRY...EXCEPT구문, 각각EXCEPT에 대소문자를 정의합니다.이는 Dellphi, Scala Visual Basic에서도 확인할 수 있습니다.네트워크

대체 수단

switch 문의 대체 방법으로는 다음과 같은 것이 있습니다.

  • 목표값을 한 번에 하나씩 검사하는 일련의 if-else 조건입니다.폴스루 동작은 oth 절이 없는 if 조건의 시퀀스를 사용하여 실행할 수 있습니다.
  • 룩업 테이블: 키로서case값 및 값으로서 아래 부분case진술.
(일부 언어에서는 룩업테이블의 값으로 사용할 수 있는 것은 실제 데이터 타입뿐입니다.다른 언어에서도 룩업 테이블 값으로 함수를 할당할 수 있으므로 실제와 동일한 유연성을 얻을 수 있습니다.switch진술.자세한 내용은 제어 테이블 문서를 참조하십시오.)
Lua는 대소문자/[9]스위치 문을 지원하지 않습니다.이 룩업 기법은 구현의 한 가지 방법입니다.switch빌트인 없는 루아어로 된 문장switch를 클릭합니다.[9]
경우에 따라 룩업 테이블이 최적화되지 않은 보다 효율적입니다. switch많은 언어가 테이블룩업을 최적화할 수 있기 때문에 스테이트먼트는 최적화할 수 있지만 switch 스테이트먼트는 값의 범위가 작고 공백이 적은 경우가 아니면 최적화되지 않습니다.그러나 최적화되지 않은 비바이너리 검색 검색은 최적화되지 않은 스위치 또는 동등한 여러 if-else [citation needed]문보다 속도가 느려지는 것은 거의 확실합니다.
  • 제어 테이블(단순 룩업 테이블로 구현 가능)은 필요에 따라 여러 입력에 대한 여러 조건을 수용하도록 커스터마이즈할 수 있으며, 일반적으로 등가 스위치(많은 문을 점유할 수 있음)보다 더 큰 '시각적 콤팩트성'을 나타낸다.
  • 패턴 매칭: 많은 기능 언어로 스위치와 같은 기능을 구현하기 위해 사용됩니다.

「 」를 참조해 주세요.

레퍼런스

  1. ^ "케이스에 의한 정의", Kleene 1952:229
  2. ^ 판 데르 린든, 피터(1994년).전문가 C 프로그래밍: Deep C Secrets, 38페이지프렌티스 홀, 이글우드 절벽. ISBN0131774298.
  3. ^ 버전 4.0 이후 2009년에 출시되었습니다.
  4. ^ 블라드 라자렌코Switch 스테이트먼트 다운에서 머신코드로
  5. ^ Guntheroth, Kurt (April 27, 2016). Optimized C++. O'Reilly Media. p. 182. ISBN 9781491922033.
  6. ^ "JEP 325: Switch Expressions (Preview)". openjdk.java.net. Retrieved 2021-04-28.
  7. ^ "JEP 354: Switch Expressions (Second Preview)". openjdk.java.net. Retrieved 2021-04-28.
  8. ^ "JEP 361: Switch Expressions". openjdk.java.net. Retrieved 2021-04-28.
  9. ^ a b Lua에서의 스위치문

추가 정보