~~~~~~~~~~~~~~~~~~~~ Arc.Ask3.Ru ~~~~~~~~~~~~~~~~~~~~~ 
Номер скриншота №:
✰ 1C6F3A0BF25331D36ED8EB6609FF073E__1718218320 ✰
Заголовок документа оригинал.:
✰ Switch statement - Wikipedia ✰
Заголовок документа перевод.:
✰ Оператор Switch — Википедия ✰
Снимок документа находящегося по адресу (URL):
✰ https://en.wikipedia.org/wiki/Case_statement ✰
Адрес хранения снимка оригинал (URL):
✰ https://arc.ask3.ru/arc/aa/1c/3e/1c6f3a0bf25331d36ed8eb6609ff073e.html ✰
Адрес хранения снимка перевод (URL):
✰ https://arc.ask3.ru/arc/aa/1c/3e/1c6f3a0bf25331d36ed8eb6609ff073e__translat.html ✰
Дата и время сохранения документа:
✰ 21.06.2024 10:08:37 (GMT+3, MSK) ✰
Дата и время изменения документа (по данным источника):
✰ 12 June 2024, at 21:52 (UTC). ✰ 

~~~~~~~~~~~~~~~~~~~~~~ Ask3.Ru ~~~~~~~~~~~~~~~~~~~~~~ 
Сервисы Ask3.ru: 
 Архив документов (Снимки документов, в формате HTML, PDF, PNG - подписанные ЭЦП, доказывающие существование документа в момент подписи. Перевод сохраненных документов на русский язык.)https://arc.ask3.ruОтветы на вопросы (Сервис ответов на вопросы, в основном, научной направленности)https://ask3.ru/answer2questionТоварный сопоставитель (Сервис сравнения и выбора товаров) ✰✰
✰ https://ask3.ru/product2collationПартнерыhttps://comrades.ask3.ru


Совет. Чтобы искать на странице, нажмите Ctrl+F или ⌘-F (для MacOS) и введите запрос в поле поиска.
Arc.Ask3.ru: далее начало оригинального документа

Оператор Switch — Википедия Jump to content

Оператор переключения

Из Википедии, бесплатной энциклопедии
(Перенаправлено из заявления Case )

В языках компьютерного программирования оператор переключения это тип механизма управления выбором, который позволяет значению переменной или выражения изменять поток управления выполнением программы посредством поиска и отображения.

Операторы Switch функционируют примерно так же, как и операторы Switch. if оператор, используемый в таких языках программирования, как C / C++ , C# , Visual Basic .NET , Java высокого уровня, , и существует в большинстве императивных языков программирования таких как Pascal , Ada , C / C++ , C# , [1] : 374–375  Visual Basic.NET , Java , [2] : 157–167  и во многих других типах языка, используя такие ключевые слова , как switch, case, select или inspect.

Операторы переключения существуют в двух основных вариантах: структурированный переключатель, как в Паскале, который принимает ровно одну ветвь, и неструктурированный переключатель, как в C, который функционирует как тип goto . Основные причины использования переключателя включают повышение ясности за счет сокращения повторяющегося кодирования, а также (если эвристика позволяет ) также предоставление возможности более быстрого выполнения за счет более простой оптимизации компилятора во многих случаях .

Оператор переключения в C
switch   (  age  )   { 
   case   1  :    printf  (  «Ты один.»  );               перерыв  ; 
    случай   2  :    printf  (  «Вас двое.»  );               перерыв  ; 
    случай   3  :    printf  (  «Тебя трое»  ); 
    случай   4  :    printf  (  «Тебе три или четыре.»  );     перерыв  ; 
    по умолчанию  :   printf  (  «Тебе не 1, 2, 3 или 4!»  ); 
  } 

История [ править ]

В своем тексте 1952 года «Введение в метаматематику» Стивен Клини формально доказал, что функция CASE (функция IF-THEN-ELSE является ее простейшей формой) является примитивно-рекурсивной функцией , где он определяет понятие «определение по случаям» следующим образом:

«#F. Функция φ, определенная таким образом

φ(x 1 , ... , x n ) =
  • φ 1 (x 1 , ... , x n ), если Q 1 (x 1 , ... , x n ),
  • . . . . . . . . . . . .
  • φ m (x 1 , ... , x n ), если Q m (x 1 , ... , x n ),
  • φ m+1 (x 1 , ... , x n ) в противном случае,

где Q 1 , ... , Q m являются взаимоисключающими предикатами (или φ(x 1 , ... , x n ) должно иметь значение, заданное первым применимым пунктом) является примитивно-рекурсивным в φ 1 , ... , φ m+1 , Q 1 , ..., Q m+1 .

Стивен Клини, [3]

Клини предоставляет доказательство этого в терминах булевых рекурсивных функций «знак» sg( ) и «не знак» ~sg( ) (Kleene 1952:222-223); первый возвращает 1, если его входной сигнал положителен, и -1, если его входной сигнал отрицательный.

Булос-Берджесс-Джеффри делают дополнительное наблюдение, что «определение по случаям» должно быть как взаимоисключающим, так и коллективно исчерпывающим . Они также предлагают доказательство примитивной рекурсивности этой функции (Boolos-Burgess-Jeffrey 2002:74-75).

IF-THEN-ELSE является основой формализма Маккарти : его использование заменяет как примитивную рекурсию, так и mu-оператор .

Самые ранние компиляторы Фортрана поддерживали вычисляемый оператор GOTO для многопутевого ветвления. Ранние компиляторы АЛГОЛА поддерживали тип данных SWITCH, который содержит список «выражений обозначения». Оператор GOTO может ссылаться на переменную переключения и, предоставляя индекс, переходить к желаемому месту назначения. С опытом стало понятно, что необходима более формальная многоходовая конструкция с единой точкой входа и выхода. Такие языки, как BCPL , ALGOL-W и ALGOL-68, представили формы этой конструкции, которые сохранились в современных языках.

Типичный синтаксис [ править ]

В большинстве языков программисты пишут оператор переключения во многих отдельных строках, используя одно или два ключевых слова. Типичный синтаксис включает в себя:

  • первый select, за которым следует выражение, которое часто называют управляющим выражением или управляющей переменной оператора переключения.
  • последующие строки, определяющие фактические случаи (значения), с соответствующими последовательностями операторов для выполнения при возникновении совпадения.
  • В языках с провальным поведением break заявление обычно следует за caseзаявление о завершении указанного заявления. [Уэллс]
  • В некоторых языках, например, PL/I , управляющее выражение является необязательным; если управляющего выражения нет, то каждая альтернатива начинается с WHENпредложение, содержащее логическое выражение, и совпадение происходит для первого случая, для которого это выражение имеет значение true. Такое использование аналогично структурам if/then/elseif/else в некоторых других языках, например Perl .
  • В некоторых языках, например, Rexx , управляющие выражения не допускаются, и каждая альтернатива начинается с символа. WHEN предложение, содержащее логическое выражение, и совпадение происходит для первого случая, для которого это выражение имеет значение true.

Каждая альтернатива начинается с определенного значения или списка значений (см. ниже), которому может соответствовать управляющая переменная и которые заставят элемент управления перейти к соответствующей последовательности операторов. Значение (или список/диапазон значений) обычно отделяется от соответствующей последовательности операторов двоеточием или импликационной стрелкой. Во многих языках каждому регистру также должно предшествовать ключевое слово, например case или when.

Обычно также допускается необязательный случай по умолчанию, заданный параметром default, otherwise, или elseключевое слово. Это выполняется, когда ни один из других случаев не соответствует управляющему выражению. В некоторых языках, например C, если ни один регистр не соответствует и default опущено switchутверждение просто ничего не делает. В других, например PL/I, выдается ошибка.

Семантика [ править ]

Семантически существуют две основные формы операторов переключения.

Первая форма — это структурированные переключатели, как в Паскале, где берется ровно одна ветвь, а случаи рассматриваются как отдельные исключительные блоки. Это действует как обобщенный условный оператор if-then-else , здесь с любым количеством ветвей, а не только с двумя.

Вторая форма — это неструктурированные переключатели, как в C, где случаи рассматриваются как метки внутри одного блока, а переключатель функционирует как обобщенный переход. Это различие называется лечением провала, которое подробно описано ниже.

Провал [ править ]

Во многих языках выполняется только соответствующий блок, а затем выполнение продолжается в конце оператора переключения. К ним относятся семейство Паскаль (Object Pascal, Modula, Oberon, Ada и т. д.), а также PL/I , современные формы диалектов Fortran и BASIC , на которые повлиял Паскаль, большинство функциональных языков и многие другие. Чтобы позволить нескольким значениям выполнять один и тот же код (и избежать необходимости дублировать код ), языки типа Паскаль допускают любое количество значений для каждого случая, заданное в виде списка, разделенного запятыми, диапазона или комбинации.

Фортрана Языки, производные от языка C, и, в более общем смысле, те, на которые влияет вычисленный GOTO , вместо этого имеют провал, когда управление переходит к соответствующему регистру, а затем выполнение продолжается («проваливается») до операторов, связанных со следующим регистром в исходном тексте. . Это также позволяет нескольким значениям соответствовать одной и той же точке без какого-либо специального синтаксиса: они просто перечисляются с пустыми телами. Значения могут быть специально обусловлены кодом в теле дела. На практике провал обычно предотвращается с помощью break ключевое слово в конце соответствующего тела, которое завершает выполнение блока переключателя, но это может вызвать ошибки из-за непреднамеренного сбоя, если программист забудет вставить ключевое слово breakзаявление. Так видят многие [4] как языковая бородавка, и некоторые инструменты для ворса предупреждают об этом. Синтаксически случаи интерпретируются как метки, а не блоки, а операторы переключения и прерывания явно изменяют поток управления. Некоторые языки, находящиеся под влиянием C, такие как JavaScript , сохраняют провал по умолчанию, в то время как другие удаляют провал или допускают его только в особых обстоятельствах. Заметные варианты этого в семействе C включают C# , в котором все блоки должны заканчиваться символом break или return если только блок не пуст (т. е. проходной режим используется как способ указания нескольких значений).

В некоторых случаях языки предусматривают необязательный отказ. Например, Perl по умолчанию не проваливается, но в некоторых случаях это можно сделать явно с помощью continueключевое слово. Это предотвращает непреднамеренный провал, но допускает его при желании. Аналогично, Bash по умолчанию не проваливается при завершении с помощью ;;, но допускает провал [5] с ;& или ;;& вместо.

Примером оператора переключения, основанного на провале, является устройство Даффа .

Сборник [ править ]

Оптимизирующие компиляторы , такие как GCC или Clang, могут скомпилировать оператор переключения либо в таблицу ветвей , либо выполнить двоичный поиск по значениям в вариантах. [6] Таблица ветвей позволяет оператору переключения с помощью небольшого постоянного числа инструкций определить, какую ветвь выполнять, без необходимости проходить через список сравнений, в то время как двоичный поиск требует только логарифмического числа сравнений, измеряемого количеством случаев в оператор переключения.

Обычно единственный способ узнать, произошла ли эта оптимизация, — это фактически просмотреть результирующий вывод сборки или машинного кода , сгенерированный компилятором.

Преимущества и недостатки [ править ]

В некоторых языках и средах программирования использование case или switch Оператор считается превосходящим эквивалентную серию операторов if else if, поскольку он:

  • Легче отлаживать (например, устанавливать точки останова в коде, а не в таблице вызовов, если отладчик не поддерживает условные точки останова).
  • Человеку легче читать
  • Легче понять и, следовательно, легче поддерживать.
  • Фиксированная глубина: последовательность операторов «if else if» может привести к глубокой вложенности, что затрудняет компиляцию (особенно в автоматически сгенерированном коде).
  • Легче проверить, что все значения обработаны. Компиляторы могут выдать предупреждение, если некоторые значения перечисления не обрабатываются.

Кроме того, оптимизированная реализация может выполняться намного быстрее, чем альтернативная, поскольку она часто реализуется с использованием индексированной таблицы ветвей . [7] Например, решение о ходе выполнения программы на основе значения одного символа, если оно правильно реализовано, значительно более эффективно, чем альтернативный вариант, что значительно сокращает длину пути инструкции . При такой реализации оператор переключения по сути становится идеальным хешем .

С точки зрения графа потока управления , оператор переключения состоит из двух узлов (вход и выход) плюс одно ребро между ними для каждого варианта. Напротив, последовательность операторов «if...else if...else if» имеет дополнительный узел для каждого случая, кроме первого и последнего, вместе с соответствующим ребром. Таким образом, результирующий граф потока управления для последовательностей «если» имеет гораздо больше узлов и почти вдвое больше ребер, причем они не добавляют никакой полезной информации. Однако простые ветви оператора if по отдельности концептуально проще, чем сложная ветвь оператора переключателя. С точки зрения цикломатической сложности оба этих варианта увеличивают ее на k −1, если дано k случаев.

Переключение выражений [ править ]

Выражения переключения представлены в Java SE 12 от 19 марта 2019 г. в качестве предварительной функции. Здесь для возврата значения можно использовать целое выражение переключателя. Также имеется новая форма этикетки корпуса, case L->где правая часть представляет собой одно выражение. Однако это также предотвращает падение и требует, чтобы случаи были исчерпывающими. В Java SE 13 yield введен оператор, и в Java SE 14 выражения переключения становятся стандартной функцией языка. [8] [9] [10] Например:

int   ndays   =   переключатель   (  месяц  )   { 
     случай   ЯНВАРЬ  ,   МАРТ  ,   МАЙ  ,   АВГУГ  ,   ОКТЯБРЬ  ,   ДЕКАБРЬ  ,   ИЮЛЬ   ->   31  ; 
      случай   АПР  ,   ИЮНЬ  ,   СЕНТ  ,   НОЯ   ->   30  ; 
      случай   FEB   ->   { 
         if   (  год   %   400   ==   0  )   выход   29  ; 
          иначе   , если   (  год   %   100   ==   0  )   доходность   28  ; 
          иначе   , если   (  год   %   4   ==   0  )   выход   29  ; 
          иначе   получим   28  ;    } 
 }; 

Альтернативное использование [ править ]

Многие языки оценивают выражения внутри switchблоков во время выполнения, что позволяет использовать конструкцию в ряде менее очевидных случаев. Это запрещает определенные оптимизации компилятора, поэтому чаще встречается в динамических языках и языках сценариев, где повышенная гибкость более важна, чем накладные расходы на производительность.

PHP [ править ]

Например, в PHP константа может использоваться в качестве «переменной» для проверки, и будет выполнен первый оператор case, который вычисляет эту константу:

переключатель   (  истина  )   { 
     case   (  $x   ==   'привет'  )  : 
         foo  (); 
          перерыв  ; 
      случай   (  $z   ==   'привет'  )  :   перерыв  ; 
  } 
 Switch   (  5  )   { 
     case   $x  :   перерыв  ; 
      случай   $y  :   перерыв  ; 
  } 

Эта функция также полезна для проверки нескольких переменных по одному значению, а не по одной переменной по множеству значений. COBOL также поддерживает эту форму (и другие формы) в EVALUATEзаявление. PL/I имеет альтернативную форму SELECT оператор, в котором управляющее выражение вообще опущено, а первое WHEN который имеет значение true , выполняется.

Руби [ править ]

В Ruby из-за обработки === равенства, этот оператор можно использовать для проверки класса переменной:

 регистра  ввод 
 , когда   Array   затем   помещает   «ввод - это массив!» 
  когда   Хэш   затем   вводит   «ввод - это Хэш!» 
  конец 

Ruby также возвращает значение, которое можно присвоить переменной, и фактически не требует case иметь какие-либо параметры (действуя немного как else if заявление):

catfood   = 
   случай 
   , когда   cat  .   возраст   <=   1 
     младший 
   , когда   кот  .   возраст   >   10 
     лет 
   , иначе 
     нормальный 
   конец 

Собрать [ править ]

Оператор переключения на языке ассемблера :

переключатель: 
   cmp   ah  ,   00h 
   je   a 
   cmp   ah  ,   01h 
   je   b 
   jmp   swtend     ;   Здесь нет соответствия регистров или кода «по умолчанию» 
 a: 
   push   ah 
   mov   al  ,   'a' 
   mov   ah  ,   0Eh 
   mov   bh  ,   00h 
   int   10h 
   pop   ah 
   jmp   swtend     ;   Эквивалент «break» 
 b: 
   push   ah 
   mov   al  ,   'b' 
   mov   ah  ,   0Eh 
   mov   bh  ,   00h 
   int   10h 
   pop   ah 
   jmp   swtend     ;   Эквивалентно «брейку» 
  
 swtend: 

Питон [ править ]

Для Python 3.10.6 были приняты PEP 634-636, что добавило match и case ключевые слова. [11] [12] [13] [14] В отличие от других языков, Python не демонстрирует провалов.

Letter   =   input  (  "Введите одну букву: "  )  .   полоса  ()[  0  ]  .   casefold  ()   # первый непробельный символ ввода, строчная 
 соответствия   буква  : 
     case   'a'   |    'е'   |    'я'   |    'о'   |    'u'  :   # В отличие от условий в операторах if, здесь нельзя использовать ключевое слово `or` для различения регистров 
         print  (  f  "Буква  {  буква  }  является гласной!"  ) 
     case   'y'  : 
         print  (  f  "Буква  {  буква }  }  может быть гласной."  ) 
     case   _  :   # `case _` эквивалентен `default` из C и других 
         print  (  f  "Буква  {  буква  }  не является гласной!"  ) 

Обработка исключений [ править ]

реализована форма оператора переключения В ряде языков при обработке исключений , где, если исключение возникает в блоке, в зависимости от исключения выбирается отдельная ветвь. В некоторых случаях также присутствует ветвь по умолчанию, если не возникает исключение. Ранним примером является Modula-3 , в которой используется TRY... EXCEPT синтаксис, где каждый EXCEPTопределяет случай. Это также встречается в Delphi , Scala и Visual Basic .NET .

Альтернативы [ править ]

Некоторыми альтернативами операторам переключения могут быть:

  • Ряд if-else условных операторов , которые проверяют целевое значение по одному. Поведение Fallthrough может быть достигнуто с помощью последовательности условных операторов if без предложения else .
  • Таблица поиска , которая в качестве ключей содержит case значения и, как значения, часть под case заявление.
(В некоторых языках в качестве значений в таблице поиска разрешены только фактические типы данных. В других языках также можно назначать функции в качестве значений таблицы поиска, получая ту же гибкость, что и реальные типы данных. switchзаявление. см. в статье «Таблица управления» ). Более подробную информацию об этом
Lua не поддерживает операторы case/switch. [15] Этот метод поиска является одним из способов реализации switch операторы на языке Lua, который не имеет встроенных switch. [15]
В некоторых случаях таблицы поиска более эффективны, чем неоптимизированные . switchоператоры, поскольку многие языки могут оптимизировать поиск в таблицах, тогда как операторы переключения не оптимизируются, если диапазон значений не мал с небольшим количеством пробелов. Однако неоптимизированный, недвоичный поиск почти наверняка будет медленнее, чем неоптимизированный переключатель или эквивалентные несколько операторов if-else . [ нужна цитата ]
  • Таблица управления (которая может быть реализована как простая таблица поиска) также может быть настроена для учета нескольких условий на нескольких входах, если это необходимо, и обычно демонстрирует большую «визуальную компактность», чем эквивалентный переключатель (который может занимать много операторов).
  • Сопоставление с образцом , которое используется для реализации функциональности, подобной переключателю, во многих функциональных языках.

См. также [ править ]

Ссылки [ править ]

  1. ^ Скит, Джон (23 марта 2019 г.). C# в глубине . Мэннинг. ISBN  978-1617294532 .
  2. ^ Блох, Джошуа (2018). «Эффективная Java: Руководство по языку программирования» (третье изд.). Аддисон-Уэсли. ISBN  978-0134685991 .
  3. ^ «Определение по случаям», Клини 1952: 229.
  4. ^ ван дер Линден, Питер (1994). Экспертное программирование на языке C: глубокие секреты C , с. 38. Прентис Холл, Иглвуд Клиффс. ISBN   0131774298 .
  5. ^ начиная с версии 4.0 , выпущенной в 2009 году.
  6. ^ Влад Лазаренко. От оператора Switch до машинного кода
  7. ^ Гюнтерот, Курт (27 апреля 2016 г.). Оптимизированный С++ . О'Рейли Медиа. п. 182. ИСБН  9781491922033 .
  8. ^ «JEP 325: Переключение выражений (предварительная версия)» . openjdk.java.net . Проверено 28 апреля 2021 г.
  9. ^ «JEP 354: Переключение выражений (вторая предварительная версия)» . openjdk.java.net . Проверено 28 апреля 2021 г.
  10. ^ «JEP 361: Переключение выражений» . openjdk.java.net . Проверено 28 апреля 2021 г.
  11. ^ Галиндо Сальгадо, Пабло. «Что нового в Python 3.10» . Документация Python 3.10.6 . Проверено 19 августа 2022 г.
  12. ^ Бухер, Брандт; ван Россум, Гвидо (12 сентября 2020 г.). «PEP 634 – Соответствие структурному шаблону: Спецификация» . Предложения по улучшению Python . Проверено 19 августа 2022 г.
  13. ^ Кон, Тобиас ; ван Россум, Гвидо (12 сентября 2020 г.). «PEP 635 – Сопоставление структурных шаблонов: мотивация и обоснование» . Предложения по улучшению Python . Проверено 19 августа 2022 г.
  14. ^ Муассе, Дэниел Ф. «PEP 636 – Сопоставление структурных шаблонов: Учебное пособие» . Предложения по улучшению Python . Проверено 19 августа 2022 г.
  15. ^ Перейти обратно: а б Оператор Switch в Lua

Дальнейшее чтение [ править ]

Arc.Ask3.Ru: конец оригинального документа.
Arc.Ask3.Ru
Номер скриншота №: 1C6F3A0BF25331D36ED8EB6609FF073E__1718218320
URL1:https://en.wikipedia.org/wiki/Case_statement
Заголовок, (Title) документа по адресу, URL1:
Switch statement - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть, любые претензии не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, денежную единицу можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)