Кіріспе
Компьютерлік бағдарламалау тілдеріндегі таңдауды басқару механизмінің түрі
Компьютерлік бағдарламалау тілдеріндегі `switch` операторы – айнымалы немесе өрнектің мәнін іздеу және салыстыру арқылы бағдарламаның орындалу бағытын өзгертуге мүмкіндік беретін таңдауды басқару механизмінің түрі. `Switch` операторлары C/C++, C#, Visual Basic NET, Java сияқты бағдарламалау тілдерінде қолданылатын `if` операторына ұқсас жұмыс істейді және Pascal, Ada, C/C++, C#, Visual Basic NET, Java және көптеген басқа да жоғары деңгейлі императивті бағдарламалау тілдерінде `switch`, `case`, `select` немесе `inspect` сияқты кілт сөздерді қолданады. `Switch` операторлары екі негізгі түрінде кездеседі: Pascal-дағы сияқты бір тармақ орындалатын құрылымды `switch` және C-дегі сияқты `goto` түрінде жұмыс істейтін құрылымсыз `switch`. `Switch` операторын пайдаланудың басты себептері – түсініктілікті арттыру, әсіресе қайталанатын кодты азайту арқылы, сондай-ақ (егер эвристика рұқсат етсе) компилятордың оңтайландыру мүмкіндіктері арқасында орындалу жылдамдығын арттыру. +Cswitch (age) { case 1: printf("Сіз бір жастасыз. "); break; case 2: printf("Сіз екі жастасыз. "); break; case 3: printf("Сіз үш жастасыз. "); break; case 4: printf("Сіз үш немесе төрт жастасыз. "); break; default: printf("Сіз 1, 2, 3 немесе 4 жаста емессіз! "); }
case 1: printf("You're one. "); break;
case 2: printf("You're two. "); break;
case 3: printf("You're three. "); break;
case 4: printf("You're three or four. "); break;
default: printf("You're not 1, 2, 3 or 4! ");
}
Семантика
Семантикалық тұрғыдан, ауысу операторларының екі негізгі түрі бар. Бірінші түрі – Паскальдегідей құрылымдалған ауысулар, онда дәл бір тармақ орындалады, ал жағдайлар бөлек, өзара байланыссыз блоктар ретінде қарастырылады. Бұл жалпыланған егер-әйтпесе шартты оператор ретінде жұмыс істейді, тек екі ғана емес, кез келген саны тармақтармен. Екінші түрі – C-дегідей құрылымдалмаған ауысулар, онда жағдайлар бір блок ішіндегі белгілер ретінде қарастырылады, ал ауысу жалпыланған goto операторы ретінде жұмыс істейді. Бұл айырмашылық түсірілім арқылы өту деп аталады, оның мәні төменде егжей-тегжейлі сипатталады.
Құлап өту
Көптеген тілдерде тек сәйкес келетін блок орындалады, содан кейін орындау `switch` операторының соңында жалғасады. Бұларға Паскаль отбасы (Object Pascal, Modula, Oberon, Ada және т.б.) кіреді, сондай-ақ PL/I, Фортранның қазіргі заманғы түрлері және Паскальдың ықпалындағы BASIC диалектілері, көптеген функционалдық тілдер және тағы басқалары. Бір кодты бірнеше мәнмен орындауға мүмкіндік беру үшін (және кодты қайталаудан аулақ болу үшін) Паскаль типтес тілдер әр жағдайда кез келген сандағы мәндерге рұқсат береді, олар үтірмен бөлінген тізім түрінде, диапазон түрінде немесе олардың комбинациясы ретінде беріледі. C тілінен туындаған тілдер және жалпы алғанда Фортранның есептелген `GOTO` операторының ықпалындағы тілдер керісінше, басқару сәйкес келетін жағдайға ауысады, содан кейін орындау жалғасады ("түсіп кетеді") бастапқы мәтіндегі келесі жағдаймен байланысты операторларға. Бұл сонымен қатар бірнеше мәнді арнайы синтаксиссіз бір нүктеге сәйкес келтіруге мүмкіндік береді: олар жай ғана бос денелерімен тізімделеді. Мәндер жағдайдың денесіндегі кодпен шартты түрде байланыстырылуы мүмкін. Іс жүзінде, түсіп кету әдетте сәйкес келетін блоктың соңында `break` операторын қолдану арқылы болдырмайды, бұл `switch` блогының орындалуын тоқтатады, бірақ егер бағдарламашы `break` операторын қосуды ұмытса, бұл қасақана түсіп кетуден туындаған қателерге әкелуі мүмкін. Сондықтан көптеген адамдар мұны тілдің кемшілігі деп санайды және кейбір линтерлер ескертеді. Синтаксистік тұрғыдан, жағдайлар блок емес, белгілер ретінде қарастырылады, ал `switch` және `break` операторлары басқару ағынын нақты өзгертеді. C тілінің ықпалындағы кейбір тілдер, мысалы JavaScript, әдепкі түсіп кетуді сақтайды, ал басқалары түсіп кетуді алып тастайды немесе оған тек ерекше жағдайларда ғана рұқсат береді. C отбасындағы осыған байланысты ерекшеліктердің бірі – C#, онда барлық блоктар бос болмаса, `break` немесе `return` операторымен аяқталуы керек (яғни, түсіп кету бірнеше мәнді көрсету тәсілі ретінде қолданылады). Кейбір жағдайларда тілдер түсіп кетуге қосымша опцияны ұсынады. Мысалы, Perl әдепкі бойынша түсіп кетпейді, бірақ жағдай `continue` операторын қолдану арқылы оны анық түрде іске қосуға болады. Бұл кездейсоқ түсіп кетуді болдырмайды, бірақ қалаған жағдайда оған рұқсат береді. Сол сияқты, Bash әдепкі бойынша `;;` арқылы аяқталғанда түсіп кетпейді, бірақ оның орнына `;&` немесе `;&&` арқылы түсіп кетуге рұқсат береді. Түсіп кетуге сүйенетін `switch` операторының мысалы – Даффтың құрылғысы.
Жинақтау
GCC немесе Clang сияқты оңтайландырушы компиляторлар switch операторын тармақ кестесіне немесе жағдайлардағы мәндер бойынша екілік іздеуге түрлендіре алады. Тармақ кестесі switch операторына салыстырулар тізімін қарастырмай, тұрақты, шағын көлемдегі нұсқаулар арқылы қай тармақты орындау керектігін анықтауға мүмкіндік береді, ал екілік іздеу switch операторындағы жағдайлар санымен өлшенетін логарифмдік мөлшерде салыстыруларды ғана қажет етеді. Көбінесе, компилятор жасаған жиналым тілі немесе машиналық кодты қарап шығу арқылы ғана осы оңтайландырудың қолданылғанын анықтауға болады.
Баламалы пайдалану
Көптеген тілдер коммутатор блоктарындағы өрнектерді орындалу барысында бағалайды, бұл құрылымды күтпеген түрде пайдалануға мүмкіндік береді. Бұл компилятордың кейбір оңтайландыруларын шектеуге себеп болады, сондықтан динамикалық және сценарийлік тілдерде осы құрылым жиі кездеседі, себебі ондағы икемділіктің артуы өнімділік шығындарынан гөрі маңыздырақ.
Ерекшеліктерді өңдеу
Көптеген тілдер қателерді өңдеуде тармақтағыш оператордың бір түрін қолданады, егер блок ішінде қате туындаса, сол қатеге байланысты жеке тармақ таңдалады. Кейбір жағдайларда, егер қате туындамаса, әдепкі тармақ та болуы мүмкін. Алғашқы мысалдардың бірі – TRY EXCEPT синтаксисін пайдаланатын Modula 3 тілі, онда әр EXCEPT жеке жағдайды анықтайды. Бұл Delphi, Scala және Visual Basic NET тілдерінде де кездеседі.