Оператор switch — различия между версиями

Материал из Вики ИТ мехмата ЮФУ
Перейти к: навигация, поиск
(Новая страница: «Оператор выбора switch в C/C++ похож на оператор выбора case в Паскале. Например, выбор можно осущ…»)
 
Строка 1: Строка 1:
 
Оператор выбора switch в C/C++ похож на оператор выбора case в Паскале. Например, выбор можно осуществлять по выражению «интегрального» типа (целые типы, символьный тип). Однако имеется, по меньшей мере, два важных отличия. Первое состоит в том, что в качестве меток используются только константы или константные выражения. То есть не могут, например, использоваться диапазоны, как в Паскале, нельзя также перечислять значения через запятую. Второе отличие — более тонкое, поясним его на примере.
 
Оператор выбора switch в C/C++ похож на оператор выбора case в Паскале. Например, выбор можно осуществлять по выражению «интегрального» типа (целые типы, символьный тип). Однако имеется, по меньшей мере, два важных отличия. Первое состоит в том, что в качестве меток используются только константы или константные выражения. То есть не могут, например, использоваться диапазоны, как в Паскале, нельзя также перечислять значения через запятую. Второе отличие — более тонкое, поясним его на примере.
 
<source lang="Pascal">case i of
 
<source lang="Pascal">case i of
   1 : f(i);
+
   1 : f;
   2 : g(i);
+
   2 : g;
   else : h(i);
+
   else : h;
 
end; // case
 
end; // case
 
</source>
 
</source>
 
Если попытаться дословно перевести его на C, получится:
 
Если попытаться дословно перевести его на C, получится:
 
<source lang="cpp">switch (i) {
 
<source lang="cpp">switch (i) {
   case 1 : f(i);
+
   case 1 : f();
   case 2 : g(i);
+
   case 2 : g();
   default : h(i);
+
   default : h();
 
}
 
}
 
</source>
 
</source>
 
И это будет неверным. Потому что в случае i = 1 будут вызваны все три функции f, g, h. Дело в том, что switch ищет первую константу, значение которой совпадает с i и просто передаёт управление в это место (к вызову f в случае i = 1). Далее весь код исполняется подряд. Если мы хотим добиться поведения, аналогичного Паскалю, необходимо использовать оператор break для принудительного выхода из тела switch. Правильный перевод на C исходного примера на Паскаль такое:
 
И это будет неверным. Потому что в случае i = 1 будут вызваны все три функции f, g, h. Дело в том, что switch ищет первую константу, значение которой совпадает с i и просто передаёт управление в это место (к вызову f в случае i = 1). Далее весь код исполняется подряд. Если мы хотим добиться поведения, аналогичного Паскалю, необходимо использовать оператор break для принудительного выхода из тела switch. Правильный перевод на C исходного примера на Паскаль такое:
 
<source lang="cpp">switch (i) {
 
<source lang="cpp">switch (i) {
   case 1 : f(i); break;
+
   case 1 : f(); break;
   case 2 : g(i); break;
+
   case 2 : g(); break;
   default : h(i);
+
   default : h();
 
}
 
}
 
</source>
 
</source>
Строка 24: Строка 24:
 
Используя описанную особенность поведения switch, можно смоделировать перечисление констант, как в Паскале:
 
Используя описанную особенность поведения switch, можно смоделировать перечисление констант, как в Паскале:
 
<source lang="Pascal">case i of
 
<source lang="Pascal">case i of
   1 : f(i);
+
   1 : f;
   2, 3 : g(i);
+
   2, 3 : g;
   else : h(i);
+
   else : h;
 
end; // case
 
end; // case
 
</source>
 
</source>
 
эквивалентно:
 
эквивалентно:
 
<source lang="cpp">switch (i) {
 
<source lang="cpp">switch (i) {
   case 1 : f(i); break;
+
   case 1 : f(); break;
   case 2 : case 3 : g(i); break;
+
   case 2 : case 3 : g(); break;
   default : h(i);
+
   default : h();
 
}
 
}
 
</source>
 
</source>
  
 
[[Категория:C++]]
 
[[Категория:C++]]

Версия 00:22, 22 сентября 2010

Оператор выбора switch в C/C++ похож на оператор выбора case в Паскале. Например, выбор можно осуществлять по выражению «интегрального» типа (целые типы, символьный тип). Однако имеется, по меньшей мере, два важных отличия. Первое состоит в том, что в качестве меток используются только константы или константные выражения. То есть не могут, например, использоваться диапазоны, как в Паскале, нельзя также перечислять значения через запятую. Второе отличие — более тонкое, поясним его на примере.

case i of
  1 : f;
  2 : g;
  else : h;
end; // case

Если попытаться дословно перевести его на C, получится:

switch (i) {
  case 1 : f();
  case 2 : g();
  default : h();
}

И это будет неверным. Потому что в случае i = 1 будут вызваны все три функции f, g, h. Дело в том, что switch ищет первую константу, значение которой совпадает с i и просто передаёт управление в это место (к вызову f в случае i = 1). Далее весь код исполняется подряд. Если мы хотим добиться поведения, аналогичного Паскалю, необходимо использовать оператор break для принудительного выхода из тела switch. Правильный перевод на C исходного примера на Паскаль такое:

switch (i) {
  case 1 : f(); break;
  case 2 : g(); break;
  default : h();
}


Используя описанную особенность поведения switch, можно смоделировать перечисление констант, как в Паскале:

case i of
  1 : f;
  2, 3 : g;
  else : h;
end; // case

эквивалентно:

switch (i) {
  case 1 : f(); break;
  case 2 : case 3 : g(); break;
  default : h();
}