УСЛОВНЫЙ ОПЕРАТОР IF
УСЛОВНЫЙ ОПЕРАТОР IF
Условный оператор if
позволяет поставить выполнение одного или двух
блоков в зависимость от результата вычисления
логического выражения. Именно это выражение
собственно и задает условие. Рассмотриваются
частные случаи if, а также случай более общей
конструкции SelectCase, позволяющей
выбирать один из многих случаев.
В Фортране предусмотрено 4 варианта
написания IF:
структурный IF - реализует двухблочную
конструкцию
если (условие) то .. .. иначе .. ..
- это наиболее общий случай оператора IF, он
появился в Фортране-77
структурный оператор if позволяет
поставить выполнение двух блоков в зависимость
от результата вычисления логического выражения
одноблочная конструкция IF
если (условие) то .. ..
- это частный случай структурного IF без
блока "НЕТ", он появился в Фортране-77
такой if позволяет поставить выполнение
одного блока в зависимость от результата
вычисления логического выражения
логический оператор IF реализует
безблочную конструкцию
если (условие) то простой_оператор
- это частный случай одноблочного IF с
единственным простым оператором вместо блока;
оператор появился в первой же версии
Фортрана, но и сейчас не устарел;
логический оператор if позволяет
поставить выполнение одного простого оператора
в зависимость от результата вычисления
логического выражения.
арифметический IF
if( e ) Mneg , Mzero , Mpos
e- арифметическое выражение; оператор
появился в первой же версии Фортрана, но
сейчас считается морально устаревшим и сохранен
только для преемственности ранее написанных
программ
Согласно классификации структурный
и одноблочный IF - это составные блочные
операторы. Как для составных опрераторов для
них действуют все перечисленные выше правила, в
частности, о не допущении перекрытия
блоков и о входе только через начало. Как для
блочных операторов для них допускаются взаимные
следования и вложения.
Структурный IF
Структурный IF - самый общий случай
записи условного оператора.
Он реализует двухблочную конструкцию "если
(условие e) то .. .. иначе .. .. ".
Условие задается логическим выражением e.
Структурный IF записывается так :
if (условие e ) then
.. .. ! любые исполняемые операторы,
образующие блок "ДА"
else
.. .. ! любые исполняемые операторы,
образующие блок "НЕТ"
end if
Можно писать endif без пробела или с
пробелом end if
Кострукцию if можно писать с именем,
повторяя имя дважды в начале (с
двоеточием) и в конце.
имя: if (условие e )
then
.. .. ! любые исполняемые операторы,
образующие блок "ДА"
else
.. .. ! любые исполняемые операторы,
образующие блок "НЕТ"
end if имя
Блок-схема, реализуемая структурным IF , полностью
симметрична:
Сначала вычисляется условие e, а затем в
зависимости от его истинности выполняется на
выбор один из двух блоков, а после этого -
следующий оператор.
Один оператор if можно вкладывать в другой
оператор IF. Один из таких случаев вложения, а
именно if в блок "НЕТ" другого IF
допускает упрощенную запись:
IF (условие e) THEN |
IF (условие e) THEN |
.. .. ! блок "ДА" |
.. .. ! блок "ДА" |
ELSE ! блок "НЕТ" |
ELSEif (условие) then
! блок "НЕТ" |
|
if (условие) then
.. .. ! блок "да"
else
.. .. ! "нет"
end if |
|
.. .. ! блок "да"
else
.. .. ! "нет" |
ENDIF |
ENDIF |
Одноблочный IF-частный случай структурного
IF, когда отсутствует блок "НЕТ", он
реализует конструкцию "если (условие e )
то .. .. ". Условие задается логическим
выражением e .
Частный случай структурного IF, когда
отсутствует блок "ДА", сводится к
предыдущему и реализует конструкцию "если
(инверсия_условия e ) то .. .. ". Следует
помнить о правилах Деморгана при инвертировании
суммы ~(a+b) = ~a & ~b и произведения ~(a &b)
= ~a + ~b
Одноблочный IF записывается так :
if (условие e ) then
.. .. ! любые операторы, образующие блок "ДА"
end if
Блок-схема, реализуемая одноблочным IF , ассимметрична:
Сначала вычисляется условие e : если
оно истинно, то выполняется блок "ДА", а
после этого - следующий оператор: если ложно - то
сразу следующий оператор.
Логический IF
Логический IF-это
частный случай одноблочного IF, когда вместо
блока "ДА" имеется лишь один простой_оператор.
Логический if записывается в одну строку
так :
if ( условие e ) простой_оператор
условие задается логическим
выражением e. Поскольку эта форма
безблочная, то не разрешается вложение логических
IF друг в друга. Выполнение лишь одного
простого оператора подчинено условию e.
Блок-схема, реализуемая логическим if:
Вычисляется условие e : если
оно истинно, то выполняется простой_оператор,
а после этого - следующий оператор; если ложно - то
сразу следующий оператор.
Арифметический IF
Арифметический IF - это безблочный
IF с тремя метками, реализующий условный
переход по знаку арифметического выражения e
. Арифметический IF записывается в одну
строку так : if( e ) m< , m= , m>
Эта форма IF морально устарела и
сохранена только для преемственности ранее
написанных программ. Приводится только для
понимания старых учебников, но не для
написания новых программ. Блок-схема,
реализуемая арифметическим IF:
Вычисляют арифметическое выражение e
и переходят на одну из трех меток по знаку {
- 0 + } выражения e . Метки опускать
нельзя, но можно две из них написать одинаковыми.
Заключительные примеры
Пример 1. Как написать плохую
программу ? Ответ очень прост - не думая. Вот
пример несложной програмы
goto 45
46 if( x.gt.40 ) goto 10
goto 21
10 R=y+40+y*1.5*(x-40)
1 write(*,*) r
goto 45
21 r=y*x
goto 1
45 read(*,*) x,y
goto 46
end ! Спрашивается: "Что же делает эта программа
?"
Пример 2. Из двух чисел a и b
найти наибольшее.
Решим задачу с применением каждого из
условных операторов IF
real a,b
namelist / IN / a,b
read(*,IN)
namelist / gross / a,b, big
-+ Арифметический IF - это несколько
"старомодное" решение, однако быстрое
if( a - b ) 1 , 2 , 2
1 big = b; goto 3
2 big = a
3 write(*,gross)
+- Логический IF: проще выглядит,
но работает медленнее
if( a>=b ) big = a
if( a<b ) big = b ! Повторную проверку условия
опустить никак нельзя !?
write(*,gross)
Повторную проверку условия опустить никак
нельзя, но вот первую можно
big = a ; if( a<b ) big = b ;
write(*,gross) ===> Объсните это себе,
нарисовав блок-схемы!
++ Структурный IF: решение и быстрое и
хорошее
if( a>=b ) then
big = a
else
big = b
end if
write(*,gross)
+++ Однако самое эффектное решение - это
решение в одну строчку вообще без IF:
write(*,*) 'a=' , a, ' b=' , b, ' GROSS=' ,
max(a,b)
Пример 3. Попадание точки (x,y) в верхний
полукруг радиуса R
Program inStyleF90
real :: x , y, R=2.0
read(1,*) x,y
if( y>0 .and. y*y + x*x <=R*R ) then
! точка выше оси X И внутри круга
write(*,*) ' точка (', x, ',' ,
y, ') в верхнем полукруге '
else
write(*,*) ' точка (', x, ',' ,
y, ') не в верхнем полукруге '
end if
end
Пример4. Что делается в примере 1 ?
- или как написать хорошую программу. Наличие
шести операторов goto в примере 1
завязывает простую программу морским
"узлом" и она становится аморфной и
нечитаемой.
Сначала "на словах" о примере 1:
вводить значения аргумента X, пока они есть
проверять " X>40 ? "
в зависимости от выполнения либо
невыполнения " X>40 ? " вычислять R по одной из
двух формул
Приняв во внимание словесное описание
алгоритма, получим внятное решение,
вложив в бесконечный цикл
do ! подряд следующие
действия
структурный if
( внутри которого две формулы на
выбор )
write
enddo
Окончательное оформление программы
! Структурированная программа
Program EstXY_estR
real x,y,R
open(2,file='rezult.txt')
do
read(*,*, end=77) x,y !
параметр end о завершении цикла по
вводу данных
if( x>40 ) then
R = y + 40 + y * 1.5 * (x-40)
write(2, *) ' R = y + 40 + y * 1.5 * (x-40)=', R,'
at x=',x,' y=', y
else
R = y*x
write(2, *) ' R = y*x=' , R,' at
x=',x,' y=', y
end if
end do
77 end ! задача завершается по концу данных
В предложенном решении сделаны уточнения по
сравнению с небрежным примером 1:
В левой колонке таблицы показан порядок
следования простых и составных операторов, а
также структура составных операторов.
Написание "лесенкой" отражает глубину
вложения операторов. Самый сложный оператор - это
двухблочный составной структурный оператор if - у
него есть не только н-начало и к-конец, но и
с-"середина".
Как видно, в программе
10 операторов, из них |
9 исполняемых, из них |
1 неисполняемых |
6 простых |
3 составных |
это 1 описание |
По-другому, в программе
10 операторов, из них |
7 простых, из них |
3 составных, из них |
1описание |
4ввод-вывод |
2присваивания |
1 ПЕ |
2 блочных |
real |
open
read
2write |
R=.. |
Program
.. ..
end |
они управляют ходом вычислений
-
это do.. ..enddo и if.. ..endif |
Первоначальной версией Фортрана
предусмотрено переключение между многими
помеченными ветвями обработки информации с
помощью вычисляемого goto (..m),i в
зависимости от натурального
i, ..m - это список меток . Этот
вычисляемый переключатель, равно как и назначаемый
goto сохранены для преемственности,
однако взамен них в Фортране-90 предложен многоблочный
оператор-переключатель без меток
SelectCase(v)
{ case(c)
.. .. }
[case default
.. ..]
endSelect
Блок case Default(с) то
есть " в остальных случаях" выделен
квадратными скобками, как не являющийся обязательным.
Оператор полностью вписывается в концепцию
стуктурного программирования, которая избегает
применения меток. Число блоков { case(c)
.. .. } выбирает программист. Он сам
разбивает все множество допустимых значений
переменной v типа integer или character
на непересекающиеся подмножества c1, c2, .. cn,
задаваемые в виде перечисления констант:
- c - единственная константа, например Case( 12
)
- ..c - список констант через запятую, например Case(
5, б, 12 )
- ..{c:c} - список диапазонов констант, например Case(
5:б, 12:19 )
- ..сочетание перечисленных способов,
например Case( 3, 1, 5:б, 12:19 )
- естественно, константы могут быть не только
явными, но и неявными (именованными)
SelectCase - блочный оператор как
Do и If : допускается следование и
вложение этих операторов друг в друга. Ввиду
многоблочности обращайте внимание на оформление
оператора SelectCase при помощи пустых строк,
отступов и комментариев.
Пример 5: " угадай-ка мое имя с 3 раз "
линия |
оператор |
1 |
$Debug |
2 |
prorgam request |
3 |
integer Point |
4 |
character *6 name,
PCname, mark *17 |
5 |
parameter (
PCname='IBM-PC' ) |
6 |
write(*,*) "
угадай с 3 раз и ответь например так: 'ВАСЯ' " |
7 |
do Point = 1,7 |
8 |
|
write(*,*) ' как
мое имя? ' |
9 |
|
read(*,*) name |
10 |
|
if( name= = PCname
) exit |
11 |
enddo |
12 |
selectCase ( Point ) !
Point {1,2,3,4,5,6,7,8} |
13 |
|
Case (1 ) |
14 |
|
|
mark = 'отлично' |
15 |
|
Case ( 2 ) |
16 |
|
|
mark = 'хорошо' |
17 |
|
Case ( 3 ) |
18 |
|
|
mark = 'удовлетворительно' |
19 |
|
Case ( 4 ) |
20 |
|
|
mark = 'плохо' |
21 |
|
CaseDefault
! Point {5,6,7,8} |
22 |
|
|
write(*,*) ' кол -
думать надо? ' |
23 |
endSelect ! .. Point |
24 |
write(*,*) 'оценка ' , mark
// ' - за ', Point, ' попыток' |
25 |
end |
Блок caseDefault(с) то есть " в
остальных случаях" не является обязательным.
Тем не менее, следуя строгому стилю структурного
программирования, не стоит опускать этот блок
даже если кажется, что "других случаев"
просто нет. Опытный программист понимает, что
именно "невозможное" в первую очередь
проявляется при отладке, если запрограммировать
сообщение об этом в caseDefault. Эти сообщения
могут также оказаться полезными, когда по
прошествии времени изменятся условия применения
программы. Смотри линии 21,22 в примере.
Блок-схема оператора SelectCase - это
переключатель на n+1 направление:
С точностью до правил оформления блоков и СО ни
в С ни в Паскале нет существенных отличий в
условных операторах.
Однако не только в написании переключателя switch
в C, но в его выполнении есть существенные
отличия:
- в case описывается лишь одна константа
- в Фортране блоки выполняются на выбор
- в С после выполнения выбранного блока
выполняются все последующие подряд, пока не
встретится оператор break - досрочный выход
- располагая блоки в определенном порядке, в С их
таким образом группируют