Шаг 47.
Microsoft Visual C++ 2010. Язык С/С++.
Переключатель switch

    На этом шаге мы рассмотрим особенности использования указанной конструкции.

    При большом многовариантном выборе использование комбинации if...else дает довольно запутанную картину. В таких ситуациях удобнее использовать специальную конструкцию switch, которая реализует выбор одного из многих вариантов. Его называют также переключателем.

    Поясним ее работу на примере программы подсчета количеств встречающихся символов а, b, с, d во введенной с клавиатуры строке. Текст программы:

// Switch.cpp: главный файл проекта.

#include "stdafx.h"
#include <clocale>     //обязательно для функции setlocale()

#include <stdio.h>     //for getchar(),...
#include <conio.h> 

#define eof -1	
#define M 5

using namespace System;

//---- Функция подсчета символов
// char с - входной символ, подсчет которого ведется (сколько раз встретится)
// int v[] - с помощью элементов этого массива организованы счетчики 
// char s[] - сюда помещаются символы, которые подсчитываются (для их
// последующей распечатки) 
void CountSimb(char c, int v[], char s[])
{
	switch (c) 
	{ 
	case 'a':
		v[0]++;
		s[0] = c; 
		break; 
	case 'b': 
		v[1]++;
		s[1] = c;
		break; 
	case 'c':
		v[2]++;
		s[2] = c;
		break; 
	case 'd':
		v[3]++;
		s[3] = c;
		break; 
	case '\012':    // чтобы не учитывался символ <Enter>
		break; 
	default:        // все прочие введенные символы попадают в этот блок
		v[4]++;
		s[4] = '!'; // признак "прочие символы" (введен для печати: чтобы 
			    // было понятно, что счетчик относится к "прочим")
		break; 
	}

}

int main()
{
	setlocale(LC_ALL,"Russian"); //функция setlocale() с аргументами
	                             //для корректного вывода кириллицы

	int c, i, a[M];
	char s[M]; 
	
	for(i=0; i < M; i++) a[i]=0; 
	
	printf("Задайте символы, <Enter>, <Ctrl+z>, <Enter> >");
	i=0;
	while((c=getchar()) != eof)
	{
		CountSimb(c, a, s);
		i++;
	}
	
	for(i=0; i < M; i++)
		printf("Символ = %c, количество = %d\n",s[i],a[i]);

	_getch();
        return 0;
}
Архив проекта можно взять здесь.

    Использование переключателя switch демонстрируется с помощью его включения в функцию CountSimb (char с, int v[], char s[]), параметры которой описаны перед ее определением.

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


   Примечание. В заголовочной части переключателяа может быть расположено не только имя переменной, но и выражение целого типа, но никак не типа float или типа строки символов.

    Участки блока определяются ключевым словом case (случай), после которого через пробел стоит конкретное значение анализируемой переменной. В нашем случае переменная описана как символ, поэтому конкретное ее значение, определяющее начало участка блока, написано в соответствии с правилами записи символьных констант: например, 'd'. Если бы переменная была типа int, то надо было бы писать, например, 5.

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

    Работа внутри тела переключателя switch организована так:

  1. Анализируется выражение заголовочной части.
  2. Управление передается на выполнение того участка тела, значение которого в метке совпадает со значением выражения в заголовочной части.
  3. На участке могут находиться обычные операторы. Они должны быть завершены оператором break (прервать), который прервет выполнение switch и передаст управление следующему за телом switch оператору.

    Оператор break прерывает не только выполнение переключателя switch, но и циклических конструкций while и for. Если в конце участка не поставить break, то программа перейдет к следующему участку, потом к следующему и т. д. В конце концов, она дойдет до конца тела переключателя switch и выйдет из него.

    Этим свойством часто пользуются. Например, если надо обработать какие-то значения переменной в заголовочной части, но для символов a и b требуется выполнить общий алгоритм. В этом случае в теле switch можно записать:

{
  case 'а':
  case 'b':
    операторы 
    break;
  .   .   .   .
}

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

    Но в теле switch мы видим еще одно ключевое слово: default. Это "метка" участка "прочие": все значения заголовочного выражения, которые отличаются от значений, указанных в элементе case, будут приводить на этот участок, где можно располагать свои операторы, в т. ч. и оперетор break.

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

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

    Результат работы приложения приведен на рисунке 1.


Рис.1. Результат работы приложения

    На следующем шаге мы вернемся к циклу for.




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