Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.
Показано с 1 по 1 из 1
  1. #1
    Аватар для Tracker1
    Проверенный

    Статус
    Оффлайн
    Регистрация
    30.07.2013
    Сообщений
    54
    Репутация:
    84 ±

    [Цикл уроков программиста] 7. Циклы и ветвления

    Циклы

    До сих пор наши программы выполнялись последовательно и каждый оператор выполнялся только один раз. Циклы предназначены для многократного выполнения какого-либо блока.

    В С++ существуют три вида циклов: for, while, do...while. Все они имеют сходную структуру и характерные особенности: инициализация счётчика цикла, проверка условия цикла, увеличение счётчика цикла.

    Начнём с цикла for. Откройте проект fahrenheit to celsius. Полный исходный текст можно найти в конце предыдущего урока.

    Блок кода в теле функции main и директиву #define закомментируйте чтобы они нам не мешали:

    PHP код:
    // #define....

    ...

    /*
    const int.....
    Остальная часть кода
    cout << "Температура.....
    */ 
    Представим ситуацию, что нам нужно ввести три значения температур и подсчитать среднее значение. Можно три раза использовать cin. Но если, значений нужно ввести не три, а сто? Лучше использовать циклы.

    Следующий код находится в теле функции main():
    PHP код:
    float c// переменная хранящая ввод пользователя
    float average 0// переменная для хранения среднего значения

    for (int i 03i++)
    {
      
    cin >> c;
      
    average += c;
    }

    cout << "Среднее значение температуры за три дня равно " << average/<< "\n"
    В скобках после ключевого слова for находятся три выражения:

    • Инициализирующее. Оно предназначено для инициалицаии счётчика цикла. В нашем случае нулём.

    • Условие проверки цикла. Здесь находится операция отношения. Если она возвращает единицу, то выполняется тело цикла, если возвращает ноль, то выполняется первый оператор стоящий за закрывающей фигурной скобкой.
      В начале цикла переменная i равна нулю, происходит проверка во втором выражении и т.к. выражение возвращает единицу (i действительно меньше трёх), то выполняется тело цикла. после того как выполнилось тело цикла, выполняется третье выражение.
    • Выражение инкрементирования (увеличения) счётчика цикла. В этом выражении мы можем изменить значение счётчика. Здесь мы видим новую операцию:
      PHP код:
       i++ // i = i + 1 
      Операция обозначаемая двойным плюсом называется операцией инкремента и просто увеличивает значение переменной на единицу. От этой операции и происходит название языка C++.
      После того как выполнилось выражение инкремента счётчика, снова выполняется второе выражение. На этот раз i равна единице. И выражение снова вернёт единицу, а значит тело цикла выполнится снова.

    Эти шаги повторяются до тех пор, пока условие проверки не вернёт ноль и программа продолжит работу начиная со следующего оператора стоящего после тела цикла.

    Сейчас самое важное - понять как работает цикл:
    1. Инициализация счётчика
    2. Проверка счётчика
    3. Выполнение тела цикла
    4. Инкремент счётчика
    5. Проверка счётчика
    6. Выполнение тела цикла

    И так, до тех пор пока условное выражение не вернёт ноль.

    В теле цикла находится всего два оператора. Первый позволяет пользователю ввести значение температуры, которое сохраняется в переменной c.

    Второй оператор может быть записан ещё одним способом:
    PHP код:
    average average c
    Каждый раз когда выполняется тело цикла, значение переменной average увеличивается на значение переменной c, которую вводит пользователь.

    В последнем операторе в примере, мы при выводе среднего значения на экран делим average на три.

    Теперь перейдём к циклу while. По структуре он точно такой же ка и цикл for, только выражения инициализации и инкрементирования расположены в разных местах.
    PHP код:
    int i 0// инициализация счётчика
    while (3)
    {
      
    // тело цикла

      
    i++; // операция инкремента

    Инициализирующее выражение расположено за пределами цикла. Инкрементирующее выражение находится в конце тела цикла.

    Сейчас можно было бы дать пример программы в подробностях раскрывающий работу тела цикла. Но надеюсь Вы и так поймёте, что while отличается от for только размещением счётчика.

    Вместо этого мы создадим новый проект. Назовите его pseudo_game. Мы будем работать с этим проектом до окончания изучения C++. Закончим этот проект хоть и псевдо-, но всё же игрой.

    Добавьте в проект файл. Затем добавьте заголовочные файлы и напишите функцию main(): с поддержкой русского языка, задержкой перед оператором return.

    Сейчас мы рассмотрим другое более интересное на мой взгляд применение цикла while. Давайте попробуем смоделировать игру и псевдо-походовый режим для этой игры с помощью цикла while. Конец каждого хода будет отмечаться нажатием клавиши клавиатуры.

    Итак, вот тело функции main():
    PHP код:
    char act;
    int ch;

    while (
    1)
    {
      
    act _getch();

    Здесь мы видим переменную act типа char. Тип char используется для хранения символов, например букв. В цикле мы не используем счётчик, поэтому у нас нет ни инициализации ни его инкремента. Вместо этого в скобках после while стоит единичка. Это значит, что условие цикла всегда истинно, он будет выполняться всегда, т.е. этот цикл - бесконечно.

    Внутри цикла, каждый раз переменной act присваивается символ, возвращаемый функцией _getch().

    Я не буду подробно останавливаться на цикле do...while, лишь приведу его синтаксис. Единственное его отличие от while - условие проверки выполняется после тела цикла, а не до. Поэтому, тело цикла всегда будет выполняться хотя бы один раз, даже если условие изначально ложное.'
    PHP код:
    do
    {
      
    // тело цикла
    }
    while (
    условие проверки цикла
    Важно понимать, что циклы взаимозаменяемы. Если Вы выполняете какую-либо задачу с помощью одного вида цикла, Вы можете выполнить её и с помощью двух других. Просто иногда определённый цикл может сделать вашу программу более понятной.

    Ветвления

    Если циклы предназначены для многократного повторения какого-то фрагмента кода, то ветвления позволяют выполнить какой-то один фрогмент кода из нескольких, в зависимости от условия.

    Продолжаем работать с программой pseudo_game.

    Наш цикл будет выполняться вечно и мы никак не можем выйти из него "внутри" программы. Считаю, это немедленно должно быть исправлено. Для выхода из программы мы будем использовать клавишу Esc. когда пользователь нажимает клавишу, то символ этой клавиши с помощью функции _getch() сохраняется в act. У каждого символа есть свой числовой код. для клавиши esc он равен 27. Но переменная act - символьного типа, в ней хранится символ а не число. Нам нужно использовать приведение типов (type cast). Нам надо нашу переменную символьного типа привести к целому типу:

    PHP код:
    char act;
    int ch;

    while (
    1)
    {
      
    act _getch();
      
    ch static_cast<int>(act);
      if ( 
    ch == 27)
      {
        break;
      }

    Для этого мы используем функцию static_cast<>(). В уговых скобках указывается тип к которому мы хотим привести переменную находящуюся в круглых скобках. Приведённое к целому типу значение мы сравниваем с 27 - кодом клавиши esc. Если они совпадают то выполяется тело ветвления if, если нет, то выполняется следующий оператор после ветвления.

    В теле ветвления у нас стоит оператор break. Он просто выходит из цикла в котором находится, поэтому если Вы после цикла while вызываете _getch(), то программа будет ждать, когда Вы введёте символ с клавиатуры.

    Для выхода из программы мы могли использовать ещё два способа:
    PHP код:
    return 0// первый
     
    exit(0); // второй 
    Первый - это выход из функции в который мы сейчас находимся. Так как мы используем пока только функцию main(), то оператор return приведёт к выходу из этой функции, а соответственно и из программы.
    Второй - использование функции exit(). В какой-бы функции мы не находились, данный вызов всегда приведёт к завершению программы.

    Теперь мы будем улучшать нашу программу. Что если пользователь введёт какую-нибудь другую клавишу, кроме esc. Что будет тогда? Ничего не будет. Просто начнётся следующая итерация цикла. Это нужно исправить!

    PHP код:
    act _getch();
    ch static_cast<int>(act);

    if (
    ch == 27)
    {
      break;
    }
    else
    {
    cout << "Вы нажали неверную клавишу!\n";

    Ключевое слово else и блок кода под ним относятся к оператору if и без него не используются.

    Если была введена любая клавиша кроме esc, то будет выведено сообщение.

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

    PHP код:
    act _getch();
    ch static_cast<int>(act);
    if (
    ch == -32)
    {}
    else if (
    ch == 27)
    {
      break;
    }
    else if (
    ch == 75)
    {
      
    // код для передвижения персонажа влево

    }
    else if (
    ch == 77)
    {
      
    // код для передвижения персонажа вправо

    }
    else
    {
      
    cout << "Вы нажали неверную клавишу!\n";

    Мы добавили три блока else if в которых тоже есть проверка условия.

    Выполнения оператора if происходит сверху вниз. Если выполняется условие в одном из четырёх первых блоков, то выполняется соответствующий код, после этого все остальные условия не проверяются, а сразу выполняется оператор идущий после закрывающей скобки для else.

    Мы добавили проверку ch на -32. Это нужно для правильной обработки клавиш стрелочек. Функцию _getch() нужно вызвать два раза. Первый она вернёт код -32, а во второй - код соответствующей стрелочки. Мы оставили соответствуюий блок кода пустым - просто фигурные скобки. В нём ничего не происходит. Если бы не было проверки этого условия, то строка "Вы нажали неверную клвишу!" появлялась бы два раза.

    Switch

    В С++ есть ещё один тип ветвления - switch. По синтаксису оно сильно отличается от if. Напишем предыдущий код используя switch.
    PHP код:
    ct _getch();
    ch static_cast<int>(act);
    switch (
    ch)
    {
    case -
    32:
    break;

    case 
    27:
      exit(
    0);
    break;

    case 
    75:
      
    // код для передвижения влево
    break;

    case 
    77:
      
    // код для передвижения вправо
    break;

    default:
      
    cout << "Вы нажали неверную клавишу!\n";


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

    Тело switch состоит из нескольких блоков case. Если значение какого-либо из case-блоков совпадает со значением переменной, то выполняется тело этого блока. Стоит заметить что тело блока case не выделяется фигурными скобками. Оно начинается с двоеточия и заканчивается оператором break, который выходит из ветвления switch. Из-за этого мы не можем здесь использовать оператор break - он всего-лишь выведет нас из ветвления, а не из функции while. Поэтому я использовал функцию exit(), в скобках которой обязательно должно стоятьь целое число.

    Упражнения:

    • Доработайте программу pseudo_game. Добавьте в switch и в if код для движения вверх (код 72) и вниз (код 80). Когда тестируете switch закомментируйте if и наоборот.
    • Добавьте две целые переменные x и y. Пусть в них хранятся координаты перемещений игрока. Инициализируйте их нулями. В блоки switch и if добавьте код для изменения x и y. Например, пользователь нажал правую стрелочку, в соответствующем фрагменте кода увеличьте x на единицу.
    • В конце программы перед вызовом функции _getch(). Выведите координаты игрока. У вас могут возникнуть проблемы с блоком switch т.к. он использует функцию exit(). Чтобы исправить эту ошибку добавьте переменную типа bool, инициализируйте её единицей. В цикле while используйте проверку этой переменной. Чтобы выйти из программы в соответствующем case-блоке вместо exit(), присвойте новой переменной ноль.

  2. 2 пользователя(ей) сказали cпасибо:
    vovandolg (16.10.2016) [ForD] (26.12.2013)
 

 

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •