Шаг 69.
Оператор выбора case

    На этом шаге мы рассмотрим оператор варианта (выбора).

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

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

    Общую структуру оператора выбора в полной форме можно представить таким образом:

  case <Переключатель> of
    <СписокКонстант1>: <Оператор1>; 
    <СписокКонстант2>: <Оператор2>;
                   .   .   .   .
    <СписокКонстантN>: <ОператорN>
    else <ОператорM>
  end;

    Одной фразой логику работы оператора выбора можно описать так: вычисленное значение Переключателя определяет, какой из Операторов должен быть выполнен. Если Переключатель принимает одно из значений СпискаКонстант1, то выполняется Оператор1, а остальные Операторы пропускаются. Если Переключатель принимает одно из значений СпискаКонстант2, то выполняется Оператор2. Аналогично будут выполняться операторы от Оператора3 до ОператораN. ОператорМ будет выполняться в том случае, если значение Переключателя не совпало ни с одним из значений СписковКонстант от 1-го до N-гo.

    В неполной форме оператора case альтернативная всем предыдущим вариантам выбора ветвь else отсутствует. В этом случае, если значение Переключателя не совпадает ни с одним из значений констант выбора, не выполняется ни один из Операторов, описанных в case, управление передается оператору, стоящему непосредственно после ключевого слова end, замыкающего оператор case.

    Ниже показаны примеры, демонстрирующие наиболее характерные способы использования оператора case.


    Пример 1.
var Symbol : Char;
   .   .   .   .
begin				
   .   .   .   .
   case  Symbol of			
       '0'..'9'    :  writeln ('Это цифра');
       'a'..'z'    :  writeln ('Это строчная буква');
       'A'..'Z'    :  writeln ('Это прописная буква');
       #10,#13,#26 : writeln ('Это управляющий символ')
      else writeln ('Это другой символ')
    end;
end.		


    Пример 2.
var  Year :	Integer;			
   .   .   .   .
begin				
   .   .   .   .
  case Year of			
    -500. .-400  : writeln ('Древнегреческий абак');
    180.. 500    : begin			
                     writeln('Первые записи в десятичной ');
                     writeln('системе счисления, которые ');
                     writeln('были сделаны в Индии.')
                   end;			
    1642         : writeln('Суммирующая машина Б. Паскаля.');
    else writeln('И прочее, прочее, прочее...')
  end;				
end.				


    По сравнению с версией Borland (Turbo) Pascal в Object Pascal сделаны два изменения в семантике оператора case, которые позволяют выполнить дополнительную оптимизацию на этапе компиляции и получить более эффективный выходной код для этого оператора:

    Первое требование является обязательным, вследствие чего программы, написанные на Borland (Turbo) Pascal, в которых использовались пересекающиеся диапазоны констант в операторах case, компилироваться не будут. Например следующий оператор будет ошибочным:

var			
  Switch : Integer;	
begin			
  case Switch of		
    100..200 : <Оператор>;	
    1..20    : <Оператор1>;	
    10..15   : <Оператор2>; //Ошибка! 
  end;			
end.			

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

    Приведем примеры, демонстрирующие оптимально и не оптимально записанные операторы case.


    Пример 1. Оператор case, для которого будет скомпилирован оптимальный код.
var		
  Switch : Integer;
  .   .   .   . 
begin		
  .   .   .   . 
  case Switch of	
    1..5     : <Оператор>;
    10..15   : <Оператор1>;
    100..200 : <Оператор2>;
  end;		
end.		


    Пример 2. Оператор case, для которого не будет скомпилирован оптимальный код.
var		
  Switch : Integer;
  .   .   .   . 
begin		
  .   .   .   . 
  case Switch of	
    100..200 : <Оператор2>;
    1..5     : <Оператор>;
    10..15   : <Оператор1>;
  end;		
end.		

    На следующем шаге мы рассмотрим цикл с предусловием while.




Предыдущий шаг Содержание Следующий шаг