Управляющие структуры и основные конструкции языков программирования. Управляющие операторы Управляющие структуры. Общие сведения о циклах

Управляющими операторами (control statement) называются исполняемые операторы, меняющие последовательность выполнения инструкций программы. Из всех операторов, использующихся в языках программирования, операторы управления вызвали больше всего споров. Основным предметом дискуссий является самый простой оператор управления goto. Он позволяет изменить порядок выполнения программы и перейти к выполнению программы, начиная с определенного места, которое обозначено именем или числом. Следовательно, этот оператор является не чем иным, как непосредственным применением команды перехода машинного языка. Наличие такого оператора в языке высокого уровня позволяет программистам писать такие бессистемные программы1:

goto 40 20 Применить процедуру Evade

goto 70 40 if (KryptoniteLevel < LethalDose) then goto 60

60 Применить процедуру RescueDamsel 70 ...

тогда как все эти действия можно записать с помощью одной структуры:

if (KryptoniteLevel < LethalDose)

then (применить процедуру RescueDamsel) else (применить процедуру Evade)

Для того чтобы избежать таких сложностей, современные языки программирования содержат такие операторы управления, которые позволяют записывать ветвящиеся структуры с помощью одного выражения. Некоторые общепринятые ветвящиеся структуры и соответствующие им в разных языках программирования операторы управления изображены на рис. 5.7. Обратите внимание на го, что с первыми двумя структурами мы уже встречались в главе 4. В нашем псевдокоде они представлены операторами if-then-else и while. Третью структуру, которая называется выбором, можно рассматривать как расширение структуры i f-then-el se. Различие между ними состоит в том, что оператор if-then-else позволяет выбирать из двух вариантов, а оператор case - из нескольких.

Другой распространенной структурой является оператор цикла for (рис. 5.8), подобный оператору while нашего псевдокода. Различие между ними заключается в том, что инициализация, модификация и проверка условия завершения цикла объединены в одном операторе. Такой оператор удобно использовать, когда тело цикла нужно выполнить определенное количество раз - один раз для каждого значения переменной-счетчика в заданном интервале. В частности, оператор, изображенный на рис. 5.8, предписывает, чтобы тело цикла было выполнено несколько раз: когда значение переменной Count равно 1, затем когда ее значение равно 2 и последний раз, когда ее значение равно 3.

Из приведенных примеров можно сделать вывод, что ветвящиеся структуры с незначительными вариациями присутствуют и в императивных, и в объектно-ориентированных языках программирования. В теоретической вычислительной технике существует предположение, что решение любой задачи, имеющей алгоритмическое решение, можно записать с помощью ограниченного количества структур. Мы обсудим это утверждение в главе 11. А пока следует заметить, что изучение языка программирования - это не бесконечное изучение различных операторов управления. На самом деле большинство структур управления, используемых в современных языках программирования, являются разновидностью структур, описанных в этой главе.


Выбор того, какие структуры включить в язык программирования, дело вкуса. Перед создателем языка стоит цель разработать язык, который не только позволяет записывать алгоритмы в удобном для чтения виде, но также помогает программисту в этом. Эта цель достигается с помощью ограничения использования тех элементов, которые исторически привели к неаккуратному программированию, и введения хорошо продуманных элементов. В результате мы имеем структурное программирование (structured programming), которое объединяет в себе методы написания программ и правильное использование операторов управления. Цель состоит в том, чтобы создать программу, легкую для понимания и выполняющую поставленные перед ней задачи.

Комментарии

Опыт показывает, что когда человек пытается понять программу большого размера, не столь важно, насколько хорошо продуман язык программирования и как используются его свойства, сколь полезна или даже обязательна дополнительная информация, представленная на нормальном человеческом языке. Поэтому в языках программирования предусмотрена возможность размещения в программе поясняющих комментариев (comments). Транслятор игнорирует комментарии, поэтому их присутствие или отсутствие никак не отражается на программе с точки зрения машины. Версия программы на машинном языке, порождаемая транслятором, остается неизменной, с комментариями или без них. Но информация, которую они содержат, является важной для человека. Без нее невозможно было бы понять большие и сложные программы.

Visual Basic является объектно-ориентированным языком программирования. Он был разработан компанией Microsoft как инструмент, с помощью которого пользователи операционной системы Microsoft Windows могли бы разрабатывать свой собственный графический пользовательский интерфейс. На самом деле Visual Basic - это больше, чем просто язык программирования. Он представляет собой полный пакет для разработки программного обеспечения, который позволяет программисту создавать пользовательский интерфейс из определенных компонентов (таких как кнопки, флажки, текстовые поля, полосы прокрутки и т. д.) и переделывать эти компоненты согласно своим потребностям, описывая, как они должны реагировать на определенные события. Например, в случае с кнопкой программист может описать, что должно происходить, если щелкнуть на ней мышью. Этот метод создания программного обеспечения из заранее определенных компонентов является современной тенденцией в разработке программного обеспечения.

Благодаря популярности операционной системы Windows и удобству использования пакета Visual Basic, язык Visual Basic стал сегодня одним из самых распространенных языков программирования. С другой стороны, из-за того что Visual Basic совместим только с программными средствами компании Microsoft, он не признается языком программирования общего назначения.

Существует два основных способа отделения комментариев от текста программы. Один из них - заключить комментарий в специальные скобки. Другой способ - обозначить начало комментария, который может занимать оставшуюся часть строки справа от знака. В языках C++, С# и Java возможны оба способа записи комментариев. В них комментарий можно поместить между знаками /* и */ или начать его с //. Таким образом, в C++, С# и Java допустимы обе записи:

/* Это комментарий. */

// Это комментарий.

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

ApproachAngle - SlipAngle - HyperSpacelncine:

добавляют комментарий «Вычесть HyperSpacelncine из SlipAngle и присвоить значение переменной ApproachAngle». Такие комментарии не делают программу более понятной, а только удлиняют ее. Запомните, что цель комментария - пояснить программу, а не повторить ее. В данном примере лучше объяснить, почему вычисляется значение переменной ApproachAngl e (если это не ясно из программы). Например, комментарий: «Переменная ApproachAngle используется позже для вычисления значения переменной ForceFiel dJetti sonVel ocity», намного полезнее, чем предыдущий.

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

Процедурные единицы

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

Процедуры

Процедура (procedure) - это набор команд для выполнения некоторой задачи, который другие программные единицы могут использовать в качестве абстрактного инструмента. Управление передается процедуре (с помощью команды перехода машинного языка), когда ее действия необходимы, а затем, после завершения выполнения процедуры, снова возвращается исходной программной единице (рис. 5.9). Процесс передачи управления процедуре называется вызовом процедуры. Программную единицу, которая запрашивает выполнение процедуры, мы будем называть вызывающей программой или вызывающим модулем (calling unit).

Во многих отношениях процедура представляет собой небольшую программу, состоящую из операторов описания, за которыми следуют исполняемые операторы, определяющие выполняемые процедурой действия. Как правило, переменная, объявленная в процедуре, является локальной переменной (local variable), то есть ее можно использовать только в данной процедуре. Такой подход исключает путаницу, которая может возникнуть, если две независимые друг от друга про-дуры используют переменные с одинаковыми именами. Переменные, действие которых не ограничивается какой-либо одной частью программы, называются глобальными переменными (global variable), они доступны в любом месте программы. В большинстве языков программирования используются и локальные, и глобальные переменные.

В рассматриваемых нами языках программирования описание процедуры почти такое же, как в нашем псевдокоде (см. главу 4). Оно начинается с выражения, которое называется заголовком процедуры и которое помимо всего прочего содержит имя процедуры. За заголовком следуют операторы, определяющие процедуру более детально.

Однако в отличие от нашего нестрогого псевдокода, в котором мы запрашивали выполнение процедуры с помощью такого выражения, как «Применить процедуру Deacti vateCrypton», большинство современных языков программирования позволяют вызывать процедуру, просто указав ее имя. Например, если GetNames, SortNames и WriteNames являются именами процедур для получения, сортировки и вывода на печать списка имен, то программу, получающую список, сортирующую его и выводящую на печать, можно записать как

Применить процедуру GetNames. Применить процедуру SortNames. Применить процедуру WriteNames.

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

Операции и операторы языка программирования Си. Примеры программ.

Управляющие структуры и основные конструкции языков программирования

Размещенная в памяти компьютера программа в момент выполнения занимает определенную область памяти. В каждый момент времени состояние программы характеризуется двумя типами сведений:

Состоянием некоторых ячеек памяти, понимаемых нами как переменные;

Активной точкой программы, то есть той командой программы, которая выполняется данный момент.

Следовательно, можно выделить и два основных класса действий, которые может выполнять вычислительная система:

Действия, выделяющие область памяти под переменные программы (описания).

Действия, меняющие точку выполнения программы (операторы, инструкции, конструкции).

Различные совокупности действий второго класса также называют управляющими структурами.

Обычно операторы в программе выполняются один за другим в порядке их записи. Это называется последовательным выполнением. Различные операторы языка С, которые мы скоро будем обсуждать, дают программисту возможность указать, что следующий оператор, подлежащий выполнению, может отличаться от очередного в последовательности. Это называется передачей управления.

В 60-е годы стало ясно, что в основе большинства трудностей, испытываемых группами разработки программного обеспечения, лежало бесконтрольное использование передачи управления. Вина была возложена на оператор goto, который позволяет программисту передавать управление в программе по одному из возможных адресов в очень широком диапазоне. Понятие так называемого структурного программирования стало почти синонимичным «исключению оператора goto».

Исследование Бома и Якопини показало, что программирование возможно и при полном отсутствии операторов goto. Смена стиля программирования на «программирование без goto» стала для программистов эпохальным девизом. Но только в 70-е годы широкие круги профессиональных программистов начали принимать структурное программирование всерьез. Результаты оказались впечатляющими, поскольку группы разработки программного обеспечения сообщали об уменьшении времени разработки, более частой поставке систем в срок и завершении проектов в рамках бюджета. Ключом к успеху является попросту то, что программы, созданные на основе методов структурного программирования, более понятны, их проще отлаживать и модифицировать и, самое главное, более вероятно, что они написаны без ошибок.
Работа Бома и Якопини в 1966 году показала, что все программы могут быть написаны с использованием всего трех управляющих структур, а именно: последовательной структуры, структуры выбора и структуры повторения. Этот результат установлен Бомом и Якопини в 1966 г. путем доказательства того, что любую программу можно преобразовать в эквивалентную, состоящую только из этих структур и их комбинаций. При этом последовательная структура, по существу, является встроенной в язык С. Если не указано иначе, компьютер автоматически выполняет операторы С один за другим в порядке их записи.

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

К управляющим структурам относятся:

· структура следования;

· структура ветвления;

>> Управляющие структуры. Общие сведения о циклах

Обучающие курсы:

Управляющие структуры. Общие сведения о циклах

Управляющие структуры

Общие сведения о циклах

Циклы - это повторение операций до тех пор, пока верно некое логическое условие. Например, зададим условием цикла, что некая переменная а меньше 10.

Цикл будет выполняться до тех пор (т.е. заключенные в него операторы будут выполняться столько раз), пока это условие не станет верным.

Имеется три вида циклов: for, do...while, while. Рассмотрим, например, конструкцию цикла for.

for (Инициализация переменной; Условие; Изменение переменной после каждого выполнения блока операторов цикла)
{
тело цикла
}

Рассмотрим пример использования цикла for (листинг 3.1).

Листинг 3.1.
Пример использования цикла for

Эта программа выведет на экран десять звездочек на одной строке. Необязательно инициализировать переменную-счетчик в цикле (переменной-счетчиком называется такая переменная, от которой зависит количество выполнений тела цикла). Рассмотрим пример программы без объявления переменной-счетчика в цикле (листинг 3.2).

Листинг 3.2.
Пример программы без объявления переменной-счетчика в цикле

Можно использовать не одну переменную-счетчик, а несколько. Рассмотрим пример подобной программы, представленный в листинге 3.3.

Листинг 3.3.
Пример использования нескольких переменных-счетчиков

Рассмотрим цикл while. В этом цикле в качестве параметра указывается какое-либо условие. Условие проверяется перед выполнением цикла. Схема цикла while имеет следующий вид.

while (условие)
{
тело цикла
}

Рассмотрим пример программы, использующей цикл while (листинг 3.4).

Листинг 3.4.
Пример использования цикла while

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

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

Пример ошибочной программы.

Рассмотрим теперь цикл do...while.
Он очень схож с циклом while и отличается только тем, что проверяет условие не до очередного выполнения цикла, а после его выполнения. Схема цикла do...while приведена ниже.

В простейшей программе операторы выполняются последовательно, т.е. ровно один раз и в том порядке, как они встречаются в тексте программы. Однако в реальных программах операторы могут повторяться или выполняться только при определенном условии. Для создания программ нелинейной структуры используются управляющие операторы.

К управляющим операторам относятся следующие операторы:

    Операторы ветвления:

    условный оператор – if else – реализует алгоритмические структуры АЛЬТЕРНАТИВА и ВЫБОР (см. Приложение 1);

    оператор выбора – switch – частично реализует алгоритмическую структуру ВЫБОР (см. Приложение 1);

    Операторы цикла:

      • цикл с предусловием – while – реализует алгоритмическую структуру ЦИКЛ С ПРЕДУСЛОВИЕМ (см. Приложение 1);

        цикл с постусловием – do while – реализует алгоритмическую структуру ЦИКЛ С ПОСТУСЛОВИЕМ (см. Приложение 1);

        цикл с параметром – for – реализует алгоритмическую структуру ПАРАМЕТРИЧЕСКИЙ ЦИКЛ (см. Приложение 1).

Условный оператор (if else )

Условный оператор if используется для разветвления процесса вычислений на два направления, соответственно он реализует алгоритмическую структуру АЛЬТЕРНАТИВА, блок-схема которой выглядит следующим образом:

Если <Условие> истинно, то выполняется <Оператор 1>, иначе выполняется <Оператор 2>.

Пример использования условного оператора для разветвления процесса вычислений на два направления:

// Вычисление модуля y= |x|

if(x < 0) { y= -x; }

Оператор if также используется для реализации алгоритмической структуры ВЫБОР (см. блок-схему ниже), когда невозможно использовать оператор выбора switch (об этом далее).

Использование уловного оператора для реализации алгоритмической структуры ВЫБОР:

Пример использования условного оператора для реализации алгоритмической структуры ВЫБОР:

// Вычисление y= sign(x) – более простой способ реализации

if(x < 0) { y= -1; }

if(x == 0) { y= 0; }

if(x > 0) { y= 1; }

// Вычисление y= sign(x) – более эффективный способ реализации

if (x < 0) { y= -1; }

else if(x == 0) { y= 0; }

else if(x > 0) { y= 1; }

Оператор выбора (switch ) + оператор прерывания (break )

Оператор switch (выбор) предназначен для разветвления процесса вычислений на несколько направлений. Данный оператор реализует алгоритмическую структуру ВЫБОР. Однако он имеет ограниченное применение, т.к. в нем нельзя задавать произвольные условия. Условия в операторе switch имеют следующую структуру <Выражение> == <Константа>.

Формат оператора:

switch(<Выражение>)

case <Константа 1>:

<Оператор 1>

case <Константа 2>:

<Оператор 2>

case <Константа M>:

<Оператор M>

<Оператор M+1>

Если <Выражение> принимает значение равное <Константа 1>, то выполняется <Оператор 1>; если <Выражение> принимает значение равное <Константа 2>, то выполняется <Оператор 2> и т.д. Если <Выражение> принимает значение отличное от указанных констант, то выполняется <Оператор M+1>.

Пример использования оператора выбора:

// Анализ ответа пользователя

scanf(“%с”, &Answer);

printf(“\nВы нажали 1”);

printf(“\nВы нажали 2”);

Оператор break прерывает выполнение оператора switch. Если бы его не было, то все операторы внутри switch выполнялись бы последовательно друг за другом. Например, так:

// Анализ ответа пользователя

scanf(“%с”, &Answer);

printf(“\nВы нажали 1”);

printf(“\nВы нажали 2”);

printf(“\nВы нажали что-то не то”);

При вводе пользователем символа ‘2’ на экране появятся два сообщения:

“Вы нажали 2”

“Вы нажали что-то не то”

Оператор цикла с предусловием (while )

Оператор используется для организации многократно повторяющихся вычислений, которые могут не выполниться ни разу. Оператор while реализует алгоритмическую структуру ЦИКЛ С ПРЕДУСЛОВИЕМ, блок-схема которой приведена ниже. Данная алгоритмическая структура используется, когда заранее неизвестно количество итераций (повторений), и возможно отсутствие повторений.

Формат оператора:

while(<Условие>)

<Оператор>

Сначала проверяется <Условие>. Если <Условие> истинно, то выполняется <Оператор> до тех пор, пока <Условие> не станет ложным. Если <Условие> стало ложным, то управление передается оператору, следующему за циклом. <Условие> – это условие продолжения цикла, <Оператор> – это тело цикла (повторяющееся действие + действие для выхода из цикла).

Замечание. <Оператор> может не выполниться ни разу, если <Условие> изначально ложно.

Пример использования оператора с предусловием:

char String= “Это пример”;

Count = 0; // подготовка

while(String !=‘\0’) // условие продолжения

{ Count++; } // тело цикла (повторяющееся действие +

В данном примере цикл не выполнится ни разу, если строка String будет пустой.

Рассмотрим еще один пример, в котором используется оператор while, но правильнее использовать оператор do while:

// Ввод русской буквы

char RussianLetter;

scanf(“%c”, &RussianLetter); // подготовка

while((RussianLetter < ‘A’) ||

(RussianLetter > ‘я’)) // условие продолжения

{ scanf(“%c”, &RussianLetter); } // тело цикла (повторяющееся действие + // действие для выхода из цикла)

Оператор цикла с постусловием (do while )

Оператор используется для организации многократно повторяющихся вычислений, которые выполняются хотя бы один раз. Оператор do while реализует алгоритмическую структуру ЦИКЛ С ПОСТУСЛОВИЕМ, блок-схема которой приведена ниже. Данная алгоритмическая структура используется, когда заранее неизвестно количество итераций, но хотя бы одна итерация выполняется всегда (например, если в цикле производится ввод данных).

Формат оператора:

<Оператор>

while(<Условие>);

Сначала выполняется <Оператор>, затем проверяется <Условие>. Если <Условие> истинно, то снова выполняется <Оператор>. Это продолжается до тех пор, пока <Условие> не станет ложным.

Замечание. <Оператор> всегда выполняется хотя бы один раз.

Пример использования цикла с постусловием:

// Запрашиваем у пользователя число от 0 до 10

// подготовка отсутствует

{ scanf(“%d”, &Number); } // тело цикла (повторяющееся действие +

// действие для выхода из цикла)

while((Number < 0)||(Number > 10)); // условие продолжения

В примере используется цикл do while, т.к. число сначала вводится, а затем осуществляется его проверка.

Обратите внимание, что после оператора while ставится точка с запятой;.

Оператор цикла с параметром (for )

Оператор используется для организации многократно повторяющихся вычислений и по своей сути аналогичен циклу while, но имеет более компактную запись. Оператор for реализует алгоритмическую структуру ПАРАМЕТРИЧЕСКИЙ ЦИКЛ, блок-схемы которой приведены ниже. Данная алгоритмическая структура используется, когда заранее известно количество итераций.

Формат оператора:

for(<Оператор инициализации>; <Условие>; <Оператор модификации>)

<Оператор>

Сначала выполняется <Оператор инициализации> и проверяется <Условие>. Если <Условие> истинно, то выполняется <Оператор>. Затем выполняется <Оператор модификации> и снова проверяется <Условие>. Если <Условие> истинно, то выполняется <Оператор> и т.д. Цикл завершается, когда <Условие> становится ложным.

Замечание. Цикл for как и цикл while может не выполниться ни разу.

Пример использования цикла с параметром:

y = 1; // подготовка

for(i= 1; i <= n; i++) // оператор инициал.; условие; оператор модификации

{ y= y*i; } // тело цикла (повторяющееся действие)

В данном примере еще до выполнения цикла известно, что переменная i должна изменяться в диапазоне от 1 до n.

А теперь рассмотрим, как та же задача решается с использованием цикла while:

// Вычисление факториала y = n!

y = 1; // подготовка

i= 1; // подготовка (оператор инициализации)

while(i <= n) // условие продолжения

y= y*i; // повторяющееся действие

i++; // действие для выхода из цикла (оператор модификации)

Данный пример показывает, что использование цикла while усложняет код программы, а потому предпочтительнее использовать цикл for, когда заранее известно количество выполняемых итераций.

^ Программирование операторов условного перехода if-еlsе Программирование операторов выбора switch i»- Программирование операторов цикла while, do-while и for Язык ассемблера - язык машинных команд. Он поддерживает лишь базовые ме- ханизмы организации программ. В нем отсутствуют управляющие конструкции, естественные для языков высокого уровня. Речь идет о поддержке конструкций типа операторов выбора, организации циклов и т. п. В прошлой главе мы положи- ли начало обсуждению этих вопросов, рассмотрев принципы организации циклов в программах на ассемблере. Цель данной главы - разработать шаблоны управля- ющих конструкций на ассемблере, аналогичные типовым операторам языка высо- кого уровня. Поступим просто - откроем любой учебник по языку С или C++, составим спи- сок приведенных в нем управляющих операторов и покажем способы их реализа- ции на ассемблере. Типовой список будет следующим: операторы выбора: ? условный оператор if-else; ? переключатель switch; Ш операторы цикла: П цикл с предусловием while; П цикл с постусловием do-while; П итерационный цикл for; ^ операторы continue и break.

Еще по теме Глава 11 Программирование типовых управляющих структур:

  1. Глава 2 Отрицательное и положительное программирование