TW-CAD
    Что такое TestWard
    Технология
    Заказать тест
    Регистрация
    FAQ
    Статьи
  Проектирование
    Информация
    Вирт. лаборатория
  Учебный процесс
    1-й курс
      Лекции
      Ликбез
      Сессия
    5-й курс
      Литература
      Практикум
      Сессия
    Консультации
  Информация
    Как с нами связатся
    О нас

 

 

 

УСЛОВНЫЙ ОПЕРАТОР IF

УСЛОВНЫЙ ОПЕРАТОР IF

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

В Фортране предусмотрено 4 варианта написания IF:

  1. структурный IF  - реализует двухблочную конструкцию
    если (условие) то .. .. иначе .. ..
    - это наиболее общий случай оператора IF, он появился в Фортране-77
    структурный оператор if позволяет поставить выполнение двух блоков в зависимость от результата вычисления логического выражения

  2. одноблочная конструкция IF  
    если (условие) то .. ..
    - это частный случай структурного IF без блока "НЕТ", он появился в Фортране-77
    такой if позволяет поставить выполнение одного блока в зависимость от результата вычисления логического выражения

  3. логический оператор IF реализует безблочную конструкцию
    если (условие) то простой_оператор
    - это частный случай одноблочного IF с единственным простым оператором вместо блока; оператор появился в первой же версии Фортрана, но и сейчас не устарел; 
    логический оператор if позволяет поставить выполнение одного простого оператора в зависимость от результата вычисления логического выражения.

  4. арифметический 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     !  подряд  следующие действия

  • read
  • структурный 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:

  • программе дан характерный заголовок Est_XY_est R
  • явно описаны все переменные x,y,R
  • оператор read написан с параметром  end=77, что обеспечивает реальный выход из цикла по концу данных на конец программы, помеченный как 77
  • помимо значения функции R напечатаны аргументы X и Y
  • помимо значения функции R напечатана и сама формула, чтоб подчеркнуть сделанный выбор

    Проведем грамматический разбор программы по порядку следования и глубине вложения операторов

    N опер   Оператор   на глубине вложения==>1234 Глубина Назначение
    комментарий  ! Структурированная программа строка-комментарий
    Program EstXY_estR 1 заголовок программы
    2 real  x,y,R 2 описание
    3 open(2,file='rezult.txt') 2 открытие файла
    do 2 начало цикла do
      5 read(*,*,end=77)x,y !выход по концу данных   3   чтение
      6н   if( x>40 ) then   3   then -
    начало блока ДА
       7    R = y + 40 + y*1.5*(x-40)    4    присваивание
       8    write(2,*)'R=y+40+y*1.5*(x-40)=',R,' at x=',x,' y=', y    4    вывод
      6с   else   3 иначе -
    конец блока ДА
    начало блока НЕТ
       9    R = y*x    4    присваивание
      10    write(2, *)'R=y*x=', R ,'  at  x=', x, '  y=', y    4    вывод
      6к   end if   3   условие -
    конец блока НЕТ
    конец if
    end do 2 конец цикла
    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

    Перечисление случаев - оператор Select case

Первоначальной версией Фортрана предусмотрено переключение между многими помеченными ветвями обработки информации с помощью вычисляемого 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 - досрочный выход
  • располагая блоки в определенном порядке, в С их таким образом группируют

 

Hosted by uCoz
.

 

 Web-design Звягин В.Ф. со товарищи: Аминев Р.Ш..
197101, Россия, Санкт-Петербург, ул.Саблинская, 14
ИТМО
Hosted by uCoz