|
|
|
| |
Главная С++ (часть 3) Цикл 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.
|
|
|
|
|