Главная arrow С++ (часть 3) arrow Цикл foreach

Цикл foreach

Современные разработки языка программирования включают в язык этот цикл. Например, цикл foreach — часть языка С#, цикл вида "for each" д0. бавлен в язык Java. Более того, принцип "for each" включен в один из новейших разделов С++, так как в библиотеке STL (Standard Template Library, Стандартная библиотека шаблонов) определен алгоритм for_each(), который применяет функцию к каждому элементу в контейнере. Однако в языке С++ до сих пор не определен цикл foreach общего назначения.
Этот цикл был придуман для обработки ситуации, довольно часто возникающей в программировании, а именно — для обработки в цикле элементов массива (или другой разновидности коллекции объектов) в строгой последовательности от начала к концу. Рассмотрим пример, в котором вычисляется среднее арифметическое элементов массива.
int n[] = {1, 7, 3, 11, 5}; double avg = 0.0;
for(int i=0; I < 5; i++) avg += n[i];
cout « "Average: " « avg/5 « endl;
Для вычисления среднего арифметического массива п считывается каждый элемент от начального до конечного. Конечно, это только один пример, иллюстрирующий основную идею. Такой же тип цикла применяется для поиска максимального и минимального значений в массиве, суммирования элементов массива, вычисления наименьшего общего знаменателя и для сотни других задач. Более того, цикл подобной конструкции применяется везде, где необходим доступ к содержимому массива. Цикл foreach создан для упрощения и рационализации подобных вычислений.
Заслуга цикла foreach состоит в том, что он исключает необходимость индексирования массива вручную. Вместо этого цикл foreach автоматически обрабатывает целый массив, последовательно получая каждый элемент. Далее показан приводившийся ранее фрагмент, но с применением цикла foreach.
int n[] = {1, 7,  3,  11,  5};. double avg=0.0;
foreach(int x in n)
avg += x; •
cout « "Average:  " « avg/5 « endl;
R каждом новом проходе цикла переменной х автоматически присваивается значение следующего элемента массива. Таким образом, в первом проходе х с0держит 1, во втором — 7 и т. д. Этот цикл не только предлагает усовершенствованный синтаксис, но и препятствует возникновению ошибок вычисления.
Далее приведена синтаксическая запись для цикла foreach. foreach (type varname in arrayname)
Здесь type — это тип переменной цикла, ее имя задается параметром varname, а массив, который будет обрабатываться, определяется параметром arrayname. Переменная varname — локальная переменная, и она не известна за пределами цикла (этот синтаксис позаимствован у языка С#). Помните, при каждом проходе цикла varname содержит значение следующего элемента (строго в порядке следования) заданного массива.
Транслятор преобразует цикл foreach в эквивалент языка С++ — цикл for.
Оператор cases
Оператор cases позволяет задать ряд значений, которые будут соответствовать switch-выражению. Обычно, если вы хотите, чтобы один и тот же фрагмент кода использовался двумя или несколькими case-операторами, следует применять "стопочные" (stacked1) case-операторы, как показано в следующем примере, switch(i) {
case 1:
case 2:
case 3:
case 4:
// делать что-нибудь для case-операторов от 1 до 4 break; case 5:
// делать что-нибудь еще break; // ...
)
^топочные case-операторы, такие как 1—4 в приведенном фрагменте кода, °°Ь1чны в программировании. Они выглядят громоздкими. Было бы гораздо Удобнее задавать диапазон значений в одном операторе. Именно это и позволяет вам сделать транслятор.
вариант перевода "этажерочный" тоже подходит. — Пер.
Он обрабатывает оператор cases, предоставляющий возможность указать диапазон значений, которые будут обрабатываться одним и тем же фрагмент том кода. С помощью оператора cases можно записать предыдущий пример следующим образом.
switch(i)   { cases 1 to 4:
// делать что-нибудь для case-операторов от 1 до 4
break; case 5:
// делать что-нибудь еще
break; //  ...
}
Таким образом, когда переменная i находится в диапазоне от 1 до 4 включительно, ее значения будут соответствовать оператору cases.
Синтаксическая запись оператора cases выглядит следующим образом:
Cases start to end;
В данном случае start — первое значение для сопоставления, a end — последнее.
Транслятор преобразует оператор cases в серию стопочных case-операторов.
Оператор typeof
Идентификация типа во время выполнения становится важной составной частью современного программирования. Несмотря на то, что встроенные в язык С++ средства идентификации замечательны, мы, программисты, неутомимый народ, и иногда стараемся улучшить и без того хорошую вешь! Экспериментальный оператор typeof — как раз тот самый случай. Он просто формирует альтернативную синтаксическую конструкцию для операции, которая уже поддерживается в языке С++, — сравнение двух типов. Таким образом, оператор typeof не добавляет новую функциональную возможность, а предлагает другой взгляд на процесс.
Как правило, оператор typeid используется для сравнения типов. Рассмотрим следующий фрагмент, в котором определяется, указывают ли указатели ptn и ptr2 на объекты одного и того же типа: If (typeid(*ptrl) == typeid(*ptr2))
cout « "ptrl points to same type as ptr2\n"
В приведенном примере оператор typeid позволяет получить типы объектов, на которые указывают переменные ptn и ptr2. Если эти типы один*1' ковы, выполняется оператор if. Подобный оператор может быть использован при работе, например, с полиморфными классами. В этом случае тип объекта, на который ссылается указатель базового класса, не всегда известен При компиляции и нуждается в проверке во время выполнения приложения. Хотя в операторе typeid, как и во всем предыдущем фрагменте, не содержится ошибки, в следующем фрагменте предложена занятная альтернативная синтаксическая конструкция: If (typeof *ptrl same as *ptr2) cout « "ptrl points to same type as ptr2\n"
В приведенном условном операторе для сравнения типов используется оператор typeof. Результат равен true, если два типа одинаковы, и false — в противном случае. Предложенная версия выполняет ту же операцию, что первоначальная, но сама операция выражена по-другому, что позволяет взглянуть на нее с иной точки зрения.
Далее приведена синтаксическая запись оператора typeof.
Typeof ppl same as pp2
opi и op2 задают как идентификатор типа (такой как int или MyClass), так и имя объекта. Таким образом, оператор typeof можно использовать для сравнения типов двух объектов, типа объекта с известным типом данных или двух типов данных.
Транслятор преобразует оператор typeof в соответствующее выражение
С оператором typeid.