Структурная конструкция ветвление предполагает что
§ 8.7. Программирование разветвляющихся алгоритмов
Содержание
Алгоритмическая конструкция “ветвление”
Условная инструкция
Блок-схема
Задача 1 может быть реализована следующим образом
Задача 4. Составьте программу в которой черепаха рисует красный круг по часовой стрелке, а любого другого цвета (заданным в виде строки) – против часовой.
Задача 5. Даны три переменных целого типа a, b и c. Определить и вывести максимальное из трех значений.
Блок-схема
Идея алгоритма заключается в следующем. Предположим, что переменная a содержит максимальное значение, тогда остается сравнить max со значениями других переменных. В итоге, переменная max будет содержать максимальное значение.
Заметим, что в python разработано очень много стандартных функций, поэтому “изобретать велосипед не стоит”, а данная программа приведена лишь в демонстрационных целях. Для поиска максимального (или минимального) воспользуйтесь стандартной функцией max() (или min() ). К тому же, эта функция может содержать более чем два аргумента.
Но если вам все таки нужно зарезервировать имя заранее, вне блока, то вы можете использовать служебное слово None :
Вложенные инструкции if
Блок-схема
Обратите внимание, что блок вложенной инструкции if (англ. – nested conditional) содержит дополнительный отступ. Эту программу можно оформить иначе, с помощью логической операции and и служебного слова elif (сокращение от “иначе если“).
Задача 5 могла быть реализована подобным образом, но, в таком случае, код станет очень громоздким и будет восприниматься плохо. Глубина вложенности одной условной инструкции в другую не имеет границ. Но, не взирая на то, что наличие отступов делает программный код понятным, слишком большая глубина вложенности значительно усложняет его чтение, поэтому ее величина редко бывает более 4. Большую глубину вложенности можно избежать использованием логических операций или разбиением вложенной структуры на несколько последовательных условных инструкций, как в задании ниже.
Задача 7. Даны три целых числа. Найти количество положительных чисел в исходном наборе.
Переключатель. elif
При проектировании графических интерфейсов переключатель идеально соответствует элементу “радиокнопка” (от англ. radio button).
Тернарная операция
Условная инструкция не единственный способ реализации ветвлений в python. Во многих языках, в том числе, и в python, существует единственная операция, которая называется – тернарная (или условное выражение). Такое название она имеет потому, что в этой операции участвуют три операнда. Синтаксис тернарной операции таков:
Тернарная операция может сделать код очень лаконичным, но нужно быть внимательным, чтобы не допустить ошибки. Если тернарная операция входит в более сложное выражение, то, ввиду старшинства арифметических операций, её следует заключать в круглые скобки. Например, в этом коде:
Базовые конструкции структурного программирования в C++
В теории программирования доказано, что программу для решения задачи любой сложности можно составить только из трех структур, называемых следованием, ветвлением и циклом. Этот результат установлен Боймом и Якопини еще в 1966 году путем доказательства того, что любую программу можно преобразовать в эквивалентную, состоящую только из этих структур и их комбинаций.
Следование, ветвление и цикл называют базовыми конструкциями структурного программирования.
Идея структурного программирования
Как уже было отмечено выше, любую программу можно составить только из структур трех типов: следования, ветвления и цикла (это базовые конструкции).
Базовые конструкции структурного программирования
Особенностью базовых конструкций является то, что любая из них имеет только один вход и один выход, поэтому конструкции могут вкладываться друг в друга произвольным образом, например, цикл может содержать следование из двух ветвлений, каждое из которых включает вложенные циклы.
Вложение базовых конструкций
Идеей использования базовых конструкций является получение программы простой структуры. Такую программу легко читать (а программы чаще приходится читать, чем писать), отлаживать и при необходимости вносить в нее изменения. Структурное профаммирование часто называли «программированием без goto», и в этом есть большая доля правды: частое использование операторов передачи управления в произвольные точки программы затрудняет прослеживание логики ее работы. С другой стороны, никакие принципы нельзя возводить в абсолют, и есть ситуации, в которых использование goto оправдано и приводит, напротив, к упрощению структуры программы.
В большинстве языков высокого уровня существует несколько реализаций базовых конструкций; в C++ есть три вида циклов и два вида ветвлений (на два и на произвольное количество направлений). Они введены для удобства программирования, и в каждом случае надо выбирать наиболее подходящие средства. Главное, о чем нужно помнить даже при написании самых простых программ, — что они должны состоять из четкой последовательности блоков строго определенной конфигурации. «Кто ясно мыслит, тот ясно излагает» — практика давно показала, что программы в стиле «поток сознания» нежизнеспособны, не говоря о том, что они просто некрасивы.
Рассмотрим операторы языка, реализующие базовые конструкции структурного программирования в C++.
Оператор «выражение»
Любое выражение, завершающееся точкой с запятой, рассматривается как оператор, выполнение которого заключается в вычислении выражения. Частным случаем выражения является пустой оператор ; (он используется, когда по синтаксису оператор требуется, а по смыслу — нет). Примеры:
i++; // выполняется операция инкремента
а* = b + с; // выполняется умножение с присваиванием
fun(i, к); // выполняется вызов функции
Операторы ветвления
Условный оператор if
Условный оператор if используется для разветвления процесса вычислений на два направления. Формат оператора:
if ( выражение ) оператор_1; [else оператор_2;]
Сначала вычисляется выражение, которое может иметь арифметический тип или тип указателя. Если оно не равно нулю (имеет значение true), выполняется первый оператор, иначе — второй. После этого управление передается на оператор, следующий за условным.
Одна из ветвей может отсутствовать, логичнее опускать вторую ветвь вместе с ключевым словом else. Если в какой-либо ветви требуется выполнить несколько операторов, их необходимо заключить в блок, иначе компилятор не сможет понять, где заканчивается ветвление. Блок может содержать любые операторы, в том числе описания и другие условные операторы (но не может состоять из одних описаний). Необходимо учитывать, что переменная, описанная в блоке, вне блока не существует.
Структурная схема условного оператора
Примеры:
if (а d || a==0)) b++; else //2
if (a a) max = b; else max = a; //5
В примере 1 отсутствует ветвь else. Подобная конструкция называется «пропуск оператора», поскольку присваивание либо выполняется, либо пропускается в зависимости от выполнения условия.
Пример. Производится выстрел по мишени, изображенной на рис. ниже. Определить количество очков.
Оператор switch (переключатель) предназначен для разветвления процесса вычислений на несколько направлений. Структурная схема оператора приведена на рис. ниже. Формат оператора:
switch ( выражение ) <
case константное_выражение_1: [список_операторов_1]
case константное_выражение_2: [список_операторов_2]
…
case константное_выражение_n: [список_операторов_n]
[default: операторы ]
>
Выход из переключателя обычно выполняется с помощью операторов break или return. Оператор break выполняет выход из самого внутреннего из объемлющих его операторов switch, for, while и do. Оператор return выполняет выход из функции, в теле которой он записан.
Все константные выражения должны иметь разные значения, но быть одного и того же целочисленного типа. Несколько меток могут следовать подряд. Если совпадения не произошло, выполняются операторы, расположенные после слова default (а при его отсутствии управление передается следующему за switch оператору).
Пример (программа реализует простейший калькулятор на 4 действия):
#include
int main() <
int a, b, res;
char op;
cout > a;
cout > op;
cout > b;
bool f = true;
switch (op) <
case ‘+’: res = a + b; break;
case ‘-‘: res = a — b; break;
case ‘*’: res = a * b; break;
case ‘/’: res = a / b; break;
default : «nНеизвестная операция»; f = false;
>
if (f) cout Операторы цикла
Операторы цикла используются для организации многократно повторяющихся вычислений. Любой цикл состоит из тела цикла, то есть тех операторов, которые выполняются несколько раз, начальных установок, модификации параметра цикла и проверки условия продолжения выполнения цикла.
Переменные, изменяющиеся в теле цикла и используемые при проверке условия продолжения, называются параметрами цикла. Целочисленные параметры цикла, изменяющиеся с постоянным шагом на каждой итерации, называются счетчиками цикла.
Начальные установки могут явно не присутствовать в программе, их смысл состоит в том, чтобы до входа в цикл задать значения переменным, которые в нем используются.
Цикл завершается, если условие его продолжения не выполняется. Возможно принудительное завершение как текущей итерации, так и цикла в целом. Для этого служат операторы break, continue, return и goto. Передавать управление извне внутрь цикла не рекомендуется.
Для удобства, а не по необходимости, в C++ есть три разных оператора цикла — while, do while и for.
Цикл с предусловием (while)
Цикл с предусловием реализует структурную схему, приведенную на рис. выше, и имеет вид:
Выражение определяет условие повторения тела цикла, представленного простым или составным оператором. Выполнение оператора начинается с вычисления выражения. Если оно истинно (не равно false), выполняется оператор цикла. Если при первой проверке выражение равно false, цикл не выполнится ни разу. Тип выражения должен быть арифметическим или приводимым к нему. Выражение вычисляется перед каждой итерацией цикла.
Пример (программа печатает таблицу значений функции y = х2+1 во введенном диапазоне):
#include
int main() <
float Xn, Xk, Dx;
printf(«Введите диапазон и шаг изменения аргумента: » );
scanf(«%f%f%f», &Хn, &Хк, &Dx);
printf(» | X | Y |n»); // шапка таблицы
float X = Xn; // установка параметра цикла
while (X printf(«| %5.2f | %5.2f |n», X, X*X + 1 ); // тело цикла
X += Dx; // модификация параметра
>
return 0;
>
Распространенный прием программирования — организация бесконечного цикла с заголовком while (true) либо while (1) и принудительным выходом из тела цикла по выполнению какого-либо условия.
В круглых скобках после ключевого слова while можно вводить описание переменной. Областью ее действия является цикл:
Цикл с постусловием (do while)
Цикл с постусловием реализует структурную схему, приведенную на рис. выше, б, и имеет вид:
Сначала выполняется простой или составной оператор, составляющий тело цикла, а затем вычисляется выражение. Если оно истинно (не равно f а! se), тело цикла выполняется еще раз. Цикл завершается, когда выражение станет равным false или в теле цикла будет выполнен какой-либо оператор передачи управления. Тип выражения должен быть арифметическим или приводимым к нему.
Пример (программа осуществляет проверку ввода):
Цикл с параметром (for)
Цикл с параметром имеет следующий формат:
for (инициализация; выражение; модификации) оператор;
Инициализация используется для объявления и присвоения начальных значений величинам, используемым в цикле. В этой части можно записать несколько операторов, разделенных запятой (операцией «последовательное выполнение»), например, так:
for (int 1 = 0, j = 2; …
int к. m;
for (k = 1, m = 0; …
Областью действия переменных, объявленных в части инициализации цикла, является цикл. Инициализация выполняется один раз в начале исполнения цикла.
Выражение определяет условие выполнения цикла: если его результат, приведенный к типу bool, равен true, цикл выполняется. Цикл с параметром реализован как цикл с предусловием.
Модификации выполняются после каждой итерации цикла и служат обычно для изменения параметров цикла. В части модификаций можно записать несколько операторов через запятую. Простой или составной оператор представляет собой тело цикла. Любая из частей оператора for может быть опущена (но точки с запятой надо оставить на своих местах!).
Пример (оператор, вычисляющий сумму чисел от 1 до 100):
for (int 1 = 1, s = 0; 1 Операторы передачи управления
В C++ есть четыре оператора, изменяющих естественный порядок выполнения вычислений:
Оператор goto
Оператор безусловного перехода goto имеет формат:
В теле той же функции должна присутствовать ровно одна конструкция вида:
Оператор goto передает управление на помеченный оператор. Метка — это обычный идентификатор, областью видимости которого является функция, в теле которой он задан.
Использование оператора безусловного перехода оправдано в двух случаях:
В остальных случаях для записи любого алгоритма существуют более подходящие средства, а использование goto приводит только к усложнению структуры программы и затруднению отладки (Даже в приведенных случаях допустимо применять goto только в случае, если в этих фрагментах кода не создаются локальные объекты. В противном случае возможно применение деструктора при пропущенгюм конструкторе, что приводит к серьезным ошибкам в программе). Применение goto нарушает принципы структурного и модульного программирования, по которым все блоки, из которых состоит программа, должны иметь только один вход и один выход.
В любом случае не следует передавать управление внутрь операторов if, switch и циклов. Нельзя переходить внутрь блоков, содержащих инициализацию переменных, на операторы, расположенные после нее, поскольку в этом случае инициализация не будет выполнена:
int к; …
goto metka; …
metka: int m = к + 1; …
>
После выполнения этого фрагмента программы значение переменной m не определено.
Оператор break
Оператор break используется внутри операторов цикла или switch для обеспечения перехода в точку программы, находящуюся непосредственно за оператором, внутри которого находится break.
Оператор continue
Оператор перехода к следующей итерации цикла continue пропускает все операторы, оставшиеся до конца тела цикла, и передает управление на начало следующей итерации.
Оператор return
Оператор возврата из функции return завершает выполнение функции и передает управление в точку ее вызова. Вид оператора:
Выражение должно иметь скалярный тип. Если тип возвращаемого функцией значения описан как void, выражение должно отсутствовать.
По материалам книги Т.А. Павловской «CC++. Программирование на языке высокого уровня»
Структура ветвления
-реализует ветвящийся вычислительный процесс, то есть процесс, для реализации которого предусмотрено несколько направлений (ветвей). Ветвление в программе – это выбор одной из нескольких последовательностей операторов при выполнении программы. Выбор направления зависит от заранее определенного признака (условия), который может относиться к исходным данным, к промежуточным данным или конечным результатам. Хотя на схеме алгоритма должны быть показаны все возможные направления вычислений в зависимости от выполнения определенного условия (или условий), при однократном прохождении программы процесс реализуется только по одной ветви, а остальные исключаются. То есть условные выражения позволяют изменять порядок выполнения программных элементов. Любая ветвь, по которой осуществляются вычисления, должна приводить к завершению вычислительного процесса.
В языках программирования структура ветвления реализуется условными конструкциями и конструкциями выбора (селективными).
в общем случае имеют форму
если выражение то действие1 иначе действие2;
и имеют следующей смысл: если выражение верно то выполняется действие1, иначе выполняется действие2.
Кроме того, используется и усеченная форма условной конструкции
нет |
да |
условие |
оператор1 |
оператор 2 |
оператор3 |
нет |
да |
условие |
оператор1 |
оператор3 |
На блок-схеме ветвление и усеченное ветвление изображаются следующим образом:
В С оператор if имеет следующую структуру:
if (условие) опрератор1; else оператор2; // полный вариант
if (условие) опрератор1; // сокращенный вариант
Условие может быть арифметическим выражением, отношением и логическим выражением. Оно должно записываться в круглых скобках. От его истинности зависит, будет или не будет выполняться действие, задаваемое следующим далее оператором. В операторе if оператор1 выполняется в том случае, если выражение ненулевое (то есть считается истинным), иначе выполняется оператор2 или не выполняются никакие действия, если оператор2 не задан, то есть отсутствует else. В частности, если a целое, то if (a) эквивалентно if (a!= 0).
Операторы и в сокращенном, и в полном вариантах if могут быть как отдельными, так и составными (несколько действий внутри блочного оператора).
if (выражение_условие) оператор;
Приведем пример программки, определяющей, является ли год високосным (делится нацело на 4, на 400, но не делится на 100).
if ((year%4==0 && year%100!=0)|| year%400==0)
printf(“Вы ввели год %d”, year);
Обратите внимание, что действия, следующие за оператором if записаны в <>. Всегда помните о том, что оператор if может работать только с одним действием. Если же действий несколько, они должны быть оформлены как составной (блочный) оператор, то есть в <>. Если бы этого не было, то второй оператор printf выполнялся бы всегда, а не только в случае истинности условия. (здесь пример на ошибку)
Полная форма оператора if:
if (выражение_условие) оператор1; else оператор2;
Вычислим следующее значение:
y=
printf(«Vvedite cifru ot 1 do 3: «);
Пример (для выполнения лабораторных работ)
Классификация введенного с терминала символа
Вложенные операторы if представляют собой конструкцию, в которой внутрь ветви одного if вложен другой оператор if. В соответствии со стандартом ANSI компиляторы обязаны поддерживать не менее 15 уровней вложенности. Но большинство позволяют и более. При этом подключенная ветвь else относится к ближайшему оператору if. В следующем примере
ветвь else относится к вложенному if, так как именно он является ближайшим. Если же необходимо, чтобы в этом примере ветвь else относилась к внешнему if, то необходимо воспользоваться блочным оператором <>:
Используя вложенные уловные операторы, найдем максимум из трех целых чисел.
printf(«\n Введите x,y,z»);
В качестве оператора1 и оператора2 (см. синтаксис if) нельзя использовать определения. Однако, как уже сказано, здесь могут быть составные операторы и блоки. Например:
При использовании блоков надо помнить о локализации определяемых в блоке объектов. Например, ошибка:
Оператор 1 и оператор 2 в свою очередь тоже могут условными (if-ами), что позволяет организовывать цепочку поверок условий любой глубины вложенности. Но могут быть ошибки Особенность: синтаксис языка предполагает, что при вложениях условных операторов каждое else соответствует ближайшему к нему предшествующему if. Пример неверного толкования этого правила:
Оператор ветвления
Оператор ветвления (условная инструкция, условный оператор) — оператор, конструкция языка программирования, обеспечивающая выполнение определённой команды (набора команд) только при условии истинности некоторого логического выражения, либо выполнение одной из нескольких команд (наборов команд) в зависимости от значения некоторого выражения.
Содержание
Общее описание
Оператор ветвления применяется в случаях, когда выполнение или невыполнение некоторого набора команд должно зависеть от выполнения или невыполнения некоторого условия. Ветвление — одна из трёх (наряду с последовательным исполнением команд и циклом) базовых конструкций структурного программирования.
Виды условных инструкций
Существует две основные формы условной инструкции, встречающиеся в реальных языках программирования: условный оператор (оператор if) и оператор многозначного выбора (переключатель, case, switch).
Условный оператор
Встречаются следующие формы условного оператора:
Условный оператор с одной ветвью
Реализация
Algol, Pascal
Algol-68, Ada, Modula-2
Необходимость условного оператора в Алголе и Паскале с момента появления была объектом критики. Критики говорили, что многочисленные составные операторы загромождают программу, мешают нормальной расстановке отступов и провоцируют ошибки (если в последней ветви оператора if забыть составной оператор там, где он необходим, то компилятор ничего не заметит, но при выполнении программы из группы операторов, которые должны выполняться в этой ветви, по условию будет выполняться только первый, все остальные — всегда). Следующие поколения языков — потомков Алгола попытались избавиться от этого недостатка. В их числе три широко известных языка: Алгол-68, Модула-2 и Ада. Конструкция оператора if в них практически одинакова, с точностью до отдельных ключевых слов:
Во всех случаях «командыX» — любое число операторов разделённых точкой с запятой. Во всех случаях все ветви условного оператора, кроме первой (ветви «then») необязательны и могут быть пропущены. Если ветвь «else» отсутствует и ни одно из условий не выполняется, то управление передаётся на команду, следующую за ключевым словом завершения условной конструкции (END, FI или END IF).
C, C++ и их потомки
C и C++ (а вслед за ними и Java, C#, PHP и множество других языков) имеют условный оператор, структурно аналогичный Паскалю. Отличие состоит в том, что условие должно быть записано в круглых скобках, а вместо ключевых слов begin и end используются фигурные скобки <> :
Nemerle
Forth
Здесь просто помещает значение на вершину стека, IF анализирует флаг, и если:
При отсутствии ELSE получается селектор с одной ветвью: выражения между IF и THEN выполняются только при ненулевом значении флага.
Fortran
Fortran изначально имел только арифметический IF, в котором в зависимости от знака выражения производился переход на одну из трёх меток. Например, часть кода подпрограммы решения квадратного уравнения:
Затем были добавлены логические (булевские) выражения и логический IF с одним оператором, вычисляемый GOTO, позже — структурный IF (с несколькими условиями), например:
Perl поддерживает структурный if с несколькими условиями, а также модификаторы оператора (statement modifiers), которые записываются после выполняемой части оператора. Например, два следующих примера идентичны по функциональности:
Вместо if можно писать unless, что приводит к инверсии значения условного выражения перед проверкой. То же самое действие через unless:
Для составного оператора (блока) допустима только структурная форма, но не модификатор. Например:
Завершающее ключевое слово не нужно, за счёт требования обязательного оформления операторов под условиями в блоки <…>.
Не существует аналога слова unless для веток elsif.
Erlang
Erlang использует два условных оператора — if и case. Оба имеют результирующее значение, которое равно значению последнего оператора в выполненной ветке и может быть использовано (назначено имени, передано в функцию…), поэтому в нём нет отдельного тернарного условного оператора. В операторе case выполняется Сопоставление с образцом, с возможностью дополнительных условий на значения в сравниваемом, а в операторе if — только проверка условий. В условиях (guard tests) допускается ограниченное множество операций и встроенных функций.
Пример на case (удаление записи о событии из дерева времён):
Переключатель
Конструкция переключателя имеет несколько (две или более) ветвей. Переключатель выполняет одну заданную ветвь в зависимости от значения вычисляемого ключевого выражения. Принципиальным отличием этой инструкции от условного оператора является то, что выражение, определяющее выбор исполняемой ветви, возвращает не логическое, а целое значение, либо значение, тип которого может быть приведён к целому. В некоторых языках допускается использовать в переключателе выражения некоторых типов, не приводимых к целому (например, текстовые строки).
Прототипом современной синтаксической конструкции была используемая в старых языках программирования команда перехода по вычисляемой метке. В этой команде указывалось выражение-селектор, возвращающее целое значение, и набор меток. При выполнении команды вычислялось выражение, а его значение использовалось как номер метки (в списке команды), на которую производился переход. Такие конструкции были, например, в языках программирования Фортран («вычисляемый GOTO») и Бейсик. Привлекательной стороной конструкции является её достаточно высокая эффективность: для определения нужной ветви (метки перехода) не требуется последовательно сравнивать результат выражения-селектора со многими занчениями, достаточно записать в память массив команд безусловного перехода с нужными адресами, чтобы при выполнении команды вычислять нужный элемент непосредственно из значения выражения. При этом скорость выполнения команды не зависит от количества меток. В современных языках реализация оператора-переключателя также часто выполняется в виде таблицы перехода, состоящей из команд безусловного перехода на соответствующие фрагменты кода. Вычисляемое выражение преобразовывается в значение сдвига по таблице перехода, определяющее выполняемую команду. В языках, где выражение-селектор может иметь нецелое значение, напрямую вычислить нужную ветвь конструкции переключателя можно далеко не всегда, поэтому в них используются другие методы оптимизации исполнения.
Например, в языке Си синтаксис команды следующий:
Синтаксис команды-переключателя Си унаследован множеством языков, но семантика его не всегда полностью аналогична Си. Например, в C# допускается использовать выражение-селектор строкового типа и соответствующие метки.
Особенности вычисления логических выражений
На порядок исполнения программы с условными операторами может существенно влиять принятая в языке логика вычисления условных выражений. Когда условие представляет собой сложное логическое выражение, к примеру «f(x) > 0 И g(y) > 0», существует две стратегии вычисления его результата:
Второй вариант является наиболее распространённым для промышленных языков (в частности, для Алгола, Фортрана, С++, С, Java, JavaScript, ECMAScript, JScript, C#, Python). В этих языках действует жёсткое правило: «Логическое выражение всегда вычисляется слева направо и его вычисление останавливается сразу же, как только результат всего выражения становится определённым». Это означает, что если выражение состоит из нескольких подусловий, объединённых оператором «И» (AND), то вычисление выражения прекратится, как только одно из подусловий окажется ложным (так как «ложь AND любое значение» в результате всегда даёт «ложь»), и, наоборот, если несколько подусловий объединены оператором «ИЛИ» (OR), вычисление прекратится после первого же истинного подусловия, поскольку в этом случае всё выражение истинно, независимо от дальнейших вычислений. А вот выражение, содержащее оператор «Исключающее ИЛИ» (XOR) неполному вычислению не поддаётся, поскольку в нём одно из значений не может определить результат вычисления всего выражения.
Языки Ада и Erlang используют разные ключевые слова для этих вариантов: слова and и or означают полное вычисление, а and then, or else (Ада), andalso, orelse (Erlang) — неполное. В Erlang andalso и orelse менее приоритетны, чем операции сравнения, что позволяет избежать скобок вокруг элементарных условий.
Фиксированный порядок вычисления подусловий (логическое выражение всегда вычисляется слева направо) вводится для того, чтобы иметь возможность управлять порядком вычисления выражения и помещать в него сначала те условия, которые должны вычисляться в первую очередь. Этим, кстати, логические выражения отличаются арифметических, для которых, в большинстве языков, порядок вычисления подвыражений (если только он не определён приоритетом и ассоциативностью операций) языком не задаётся и в разных случаях может быть различным.
Выбор именно такой логики исполнения связан с тем, что она позволяет упростить логические выражения, в которых используются зависимые элементы. Классический пример — линейный поиск в массиве:
Алгоритм, реализуемый программой, совершенно очевиден, но в реализации есть одна тонкость (см. строку, помеченную восклицательными знаками): условие цикла состоит из двух частей, связанных оператором AND. Первое подусловие проверяет, не вышел ли индекс i за пределы массива, второе — не равен ли текущий элемент массива искомому значению. Если массив не содержит искомого значения, то после проверки последнего элемента значение переменной i увеличится на единицу; на следующей итерации первое подусловие окажется ложным и цикл завершится без проверки второго подусловия. Если бы логические выражения вычислялись полностью, то при отсутствии искомого элемента в массиве после последней итерации происходила бы ошибка: попытка определить a[i] вызывала бы некорректное обращение к памяти.
Следует обратить внимание, что, кроме неполного вычисления значения выражения, здесь также играет существенную роль фиксированный порядок вычисления подусловий: поскольку проверка выхода за границу массива записана первой, она всегда будет выполняться раньше, чем проверка достижения искомого значения. Если бы порядок вычисления подвыражений был неопределённым, гарантировать правильность приведённого фрагмента программы было бы невозможно.
При полном вычислении логических выражений приведённый алгоритм пришлось бы записать примерно в следующем виде:
Как видим, пришлось искусственно задать порядок вычисления условий выхода и ввести дополнительную переменную. Именно для того, чтобы избежать подобных трюков, и введено неполное вычисление логических выражений.
Примечание: Код изложенный выше, является примером использования оператора IF но не более. Этот код нельзя использовать как правило для написания алгоритмов на языке Паскаль.
Ниже приведен оптимальный алгоритм для поиска числа в массиве: