Основы программирования — Осенний семестр; Михалкович С.С.; 2008; II — различия между версиями

Материал из Вики ИТ мехмата ЮФУ
Перейти к: навигация, поиск
(Условный оператор)
(Координаты средней точки)
 
(не показаны 52 промежуточные версии 3 участников)
Строка 1: Строка 1:
[[Категория:Конспекты]]
+
[[Категория:Основы программирования]]
== Оператор присваивания := ==
+
[[Страница курса Основы программирования|К основной странице курса]]
=== Синтаксис ===
+
== Основные операторы ==
 +
=== Оператор присваивания := ===
 +
<xh4> Синтаксис </xh4>
 
  <переменная> ''':=''' <выражение>
 
  <переменная> ''':=''' <выражение>
  
Строка 10: Строка 12:
 
</source>
 
</source>
  
=== Семанитика ===
+
<xh4> Семанитика </xh4>
 
Вычисляется выражение в правой части, при этом, вместо имен переменных подставляются их значения. <br />
 
Вычисляется выражение в правой части, при этом, вместо имен переменных подставляются их значения. <br />
 
Затем результат вычисления записывается в переменную в левой части.
 
Затем результат вычисления записывается в переменную в левой части.
Строка 19: Строка 21:
 
* выражение типа <tt>integer</tt> можно присвоить переменной типа <tt>real</tt>. Обратное неверно.
 
* выражение типа <tt>integer</tt> можно присвоить переменной типа <tt>real</tt>. Обратное неверно.
  
=== Операторы присваивания += и *= ===
+
<xh4> Операторы присваивания += и *= </xh4>
 
''<u>Пример</u>.''
 
''<u>Пример</u>.''
 
<source lang="Pascal">
 
<source lang="Pascal">
Строка 26: Строка 28:
 
</source>
 
</source>
  
=== Примеры использования := ===
+
<xh4> Примеры использования := </xh4>
 
''<u>Пример 1</u>.'' Перемена местами двух значений.
 
''<u>Пример 1</u>.'' Перемена местами двух значений.
 
Дано:  <tt>x, y</tt>;
 
Дано:  <tt>x, y</tt>;
Строка 86: Строка 88:
 
Об этом читай [http://it.mmcs.sfedu.ru/forum?func=view&id=22350&catid=1 тему].
 
Об этом читай [http://it.mmcs.sfedu.ru/forum?func=view&id=22350&catid=1 тему].
  
== Оператор ввода ==
+
=== Оператор ввода ===
=== Синтаксис ===
+
<xh4> Синтаксис </xh4>
 
  '''read''' (<список переменных>) | '''readln''' (<список переменных>)
 
  '''read''' (<список переменных>) | '''readln''' (<список переменных>)
  
=== Семантика ===
+
<xh4> Семантика </xh4>
 
Происходит считывание данных с клавиатуры и запись их в переменные из <tt><списка переменных></tt>.  
 
Происходит считывание данных с клавиатуры и запись их в переменные из <tt><списка переменных></tt>.  
 
Вводить данные нужно либо через пробел, либо по нажатию <tt><Enter></tt>, при этом программа не перейдет к выполнению следующего оператора, пока не будут считаны все данные.
 
Вводить данные нужно либо через пробел, либо по нажатию <tt><Enter></tt>, при этом программа не перейдет к выполнению следующего оператора, пока не будут считаны все данные.
  
С процедурой ввода связан ряд '''''ошибок''''' (например, если переменная используется в качестве делителя, и вводится 0, или, если должно быть получено целое число, а вводится <tt>'ABC'</tt>). Эти ошибки нужно уметь обрабатывать.
+
Имеются также стандартные функции ReadInteger, ReadReal, ReadlnInteger, ReadlnReal:
  
== Оператор try/except и обработка ошибок ввода ==
+
<source lang="Delphi">var n := ReadInteger;
 +
var r := ReadlnReal;</source>
 +
 
 +
С процедурой ввода связан ряд '''''ошибок''''' времени выполнения (например, если переменная используется в качестве делителя, и вводится 0, или, если должно быть получено целое число, а вводится <tt>'ABC'</tt>). Эти ошибки нужно уметь обрабатывать.
 +
 
 +
=== Оператор try/except и обработка ошибок ввода ===
 
Операторы, которые могут получать ошибку, заключаются специальный охранный блок - оператор <tt>'''try'''</tt>.
 
Операторы, которые могут получать ошибку, заключаются специальный охранный блок - оператор <tt>'''try'''</tt>.
  
=== Синтаксис ===
+
<xh4> Синтаксис </xh4>
 
<source lang="Pascal">
 
<source lang="Pascal">
 
try
 
try
Строка 111: Строка 118:
 
</source>
 
</source>
  
=== Семантика ===
+
<xh4> Семантика </xh4>
 
Если внутри блока '''<tt>try</tt>''' происходит ''ошибка выполнения'', то все последующие операторы в блоке игнорируются, и выполнение программы переходит к блоку '''<tt>except</tt>'''. По выходе из '''<tt>except</tt>''' программа продолжает работу.
 
Если внутри блока '''<tt>try</tt>''' происходит ''ошибка выполнения'', то все последующие операторы в блоке игнорируются, и выполнение программы переходит к блоку '''<tt>except</tt>'''. По выходе из '''<tt>except</tt>''' программа продолжает работу.
  
 
Если ошибки не происходит, то выполняются все операторы в блоке '''<tt>try</tt>''', блок '''<tt>except</tt>''' не выполняется, и программа продолжает работу.
 
Если ошибки не происходит, то выполняются все операторы в блоке '''<tt>try</tt>''', блок '''<tt>except</tt>''' не выполняется, и программа продолжает работу.
  
== Оператор вывода ==
+
=== Оператор вывода ===
=== Синтаксис ===
+
<xh4> Синтаксис </xh4>
 
  '''write'''(<список выражений>) | '''writeln'''(<список выражений>)
 
  '''write'''(<список выражений>) | '''writeln'''(<список выражений>)
  
=== Семантика ===
+
<xh4> Семантика </xh4>
 
Выражения в списке вычисляются, и их значения выводятся на экран. <br />
 
Выражения в списке вычисляются, и их значения выводятся на экран. <br />
 
В случае <tt>writeln</tt> после вывода осуществляется переход на новую строку.
 
В случае <tt>writeln</tt> после вывода осуществляется переход на новую строку.
  
=== Форматы вывода ===
+
<xh4> Форматы вывода </xh4>
 
После каждого выражения в списке вывода можно использовать '''формат вывода''' в виде <tt>''':a'''</tt>, где <tt>'''a'''</tt> — выражение целого типа.<br />
 
После каждого выражения в списке вывода можно использовать '''формат вывода''' в виде <tt>''':a'''</tt>, где <tt>'''a'''</tt> — выражение целого типа.<br />
 
После вещественного типа — <tt>''':a:b'''</tt> (<tt>'''a'''</tt> задает ширину поля вывода (выравнивание по правому краю), <tt>'''b'''</tt> — количество знаков в дробной части).
 
После вещественного типа — <tt>''':a:b'''</tt> (<tt>'''a'''</tt> задает ширину поля вывода (выравнивание по правому краю), <tt>'''b'''</tt> — количество знаков в дробной части).
  
=== Вывод с помощью write[ln]Format ===
+
<xh4> Вывод с помощью write[ln]Format </xh4>
 
  '''writelnFormat'''('<форматная строка>', <список выражений>)
 
  '''writelnFormat'''('<форматная строка>', <список выражений>)
  
Строка 142: Строка 149:
 
<br><tt>{0, 10}</tt>: 10 — это ширина поля вывода
 
<br><tt>{0, 10}</tt>: 10 — это ширина поля вывода
 
<br><tt>{0, 10:f3}</tt>: 3 — это количество знаков в дробной части для вещественного числа (показывает это спецификатор <tt>'''f'''</tt>).
 
<br><tt>{0, 10:f3}</tt>: 3 — это количество знаков в дробной части для вещественного числа (показывает это спецификатор <tt>'''f'''</tt>).
 +
<br><tt>{0, 10:e3}</tt> — экспоненциальный формат.
  
== Условный оператор ==
+
=== Арифметические выражения ===
=== Синтаксис ===
+
==== Основные сведения ====
'''if''' <условие> '''then''' <оператор<sub>1</sub>>
+
Каждое выражение имеет '''тип'''. Выражение называется '''''арифметическим''''', если его тип — ''числовой''. <br />
              '''else''' <оператор<sub>2</sub>>
+
Выражение строится посредством '''''операций''''' (унарных или бинарных) и '''''операндов'''''.
 
 
=== Семантика ===
 
[[Изображение: If.jpg]]
 
 
 
=== Примеры использования для решения задач ===
 
''<u>Пример 1</u>.'' Нахождение минимума
 
<br>Дано: <tt>x, y</tt>;
 
<br>Найти: <tt>min</tt>;
 
 
 
<source lang="Pascal">
 
if x > y then
 
  min := y
 
else
 
  min := x;
 
</source>
 
 
 
''<u>Пример 2</u>.'' Упорядочение <tt>a, b</tt> по возрастанию.
 
<br>Ясно, что если a > b, — нужно [[Основы программирования — Осенний семестр; Михалкович С.С.; 2008; II#Примеры использования := | поменять их местами]]. <br />
 
Но тут одним оператором не обойтись.
 
Для этого можно использовать '''''составной оператор''''' — один или больше операторов, заключенных в операторные скобки <tt>'''begin'''  - '''end''';</tt>:
 
<source lang="Pascal">if a > b then
 
begin
 
  var v := b;
 
  b := a;
 
  a := v;
 
end;
 
</source>
 
 
 
''<u>Пример 3</u>.'' Вычисление функции по взаимоисключающим веткам <br />
 
<math>y = \begin{cases} x, & x < 2 \\ x^2, & 2 < x < 3 \\ 1-x, & x \ge\; 3 \end{cases}</math>
 
<source lang="Pascal">
 
if x < 2 then
 
  y := x
 
else
 
  if x < 3 then
 
    y := x * x
 
  else
 
    y := 1 - x;
 
</source>
 
 
 
'''Замечание.''' Если по ветви '''<tt>else</tt>''' располагается другой оператор '''<tt>if</tt>''', то говорят, что возникает '''''цепочка вложенных операторов <tt>if</tt>'''''.
 
 
 
''<u>Пример 4</u>.'' Найти среднее среди <tt>a, b, c</tt> (<tt>a, b, c</tt> попарно не равны) <br />
 
Эта задача имеет несколько вариантов решения.
 
<source lang="Pascal">
 
if a < b then
 
  if a < c then
 
    if b < c then
 
      sr := b
 
    else
 
      sr := c
 
  else
 
    sr := a
 
else
 
  if a > c then
 
    if b > c then
 
      sr := b
 
    else
 
      sr := c
 
  else sr := a;
 
</source>
 
 
 
Очевидно, это не самое лучшее решение. <br>
 
Можно воспользоваться стандартными функциями сравнения.
 
<source lang="Pascal">
 
sr := min(a,b);
 
if sr < c then
 
  sr := min(max(a,b), c);
 
</source>
 
 
 
''Самостоятельно.''
 
* Даны координаты вершин треугольника и точка M. Принадлежит ли M треугольнику.
 
* Является ли 4-угольник ABCD корректно заданным.
 
 
 
==Арифметические выражения==
 
<h4>Основные сведения</h4>
 
Каждое выражение имеет ''тип''. Выражение называется '''''арифметическим''''', если его тип — числовой.
 
Выражение строится посредством ''операций''( унарных или бинарных ) и ''операндов''.
 
  
 
В арифметических выражениях если <tt>a</tt> и <tt>b</tt> — одного типа, то и <tt>a '''op''' b</tt> принадлежит к тому же типу. ''Исключением'' является операция "'''/'''":
 
В арифметических выражениях если <tt>a</tt> и <tt>b</tt> — одного типа, то и <tt>a '''op''' b</tt> принадлежит к тому же типу. ''Исключением'' является операция "'''/'''":
 
:<tt>'''a / b'''</tt> — вещественное.
 
:<tt>'''a / b'''</tt> — вещественное.
  
Если <tt>a</tt> и <tt>b</tt> принадлежат к различным тиапм, то выражение принадлежит к "'''старшему'''" типу.
+
Если <tt>a</tt> и <tt>b</tt> принадлежат к различным типам, то выражение принадлежит к "'''''старшему'''''" типу. <br />
<br>Например:
+
Например:
 
  byte < integer < int64
 
  byte < integer < int64
 
  integer < real
 
  integer < real
  
 +
==== Стандартные функции ====
 
В арифметические выражения могут входить стандартные функции:
 
В арифметические выражения могут входить стандартные функции:
:<tt>exp(x)</tt>
+
'''exp'''(x)
:<tt>ln(x)</tt>
+
'''ln'''(x)
:<tt>abs(x)</tt> // модуль x
+
'''abs'''(x) // модуль x
:<tt>sin(x)</tt>
+
'''sin'''(x)
:<tt>cos(x)</tt>
+
'''cos'''(x)
:<tt>sqr(x)</tt> // квадрат x
+
'''sqr'''(x) // квадрат x
:<tt>sqrt(x)</tt> // корень из x  
+
'''sqrt'''(x) // корень из x  
:<tt>min(x,y)</tt>
+
'''round'''(x) - целое, полученное в результате округления вещественного x
:<tt>max(x,y)</tt>
+
'''trunc'''(x) - целое, полученное в результате отбрасывания дробной части у вещественного x
:<tt>pow(x,y)</tt> // x в степени y
+
'''min'''(x,y)  
 +
'''max'''(x,y)  
 +
'''power'''(x,y)// x в степени y
 +
'''random'''(n)// псевдослучайное целое число от 0 до n-1
 +
'''random'''(a,b)// псевдослучайное целое число от a до b
  
<h3>Порядок выполнения операций в арифметических выражениях</h3>
+
<xh4> Порядок выполнения операций в арифметических выражениях </xh4>
*Операции с большим приоритетом выполняются первыми
+
* Операции с большим приоритетом выполняются первыми
*Функции вычисляются до операций
+
* Функции вычисляются до операций
*Выражение в скобках вычисляется раньше
+
* Выражение в скобках вычисляется раньше
*Операции с одинаковым приоритетом выполняются слева направо, если идут подряд.
+
* Операции с одинаковым приоритетом выполняются слева направо, если идут подряд.
  
<h3>Операции div и mod для целых</h3>
+
<xh4> Операции div и mod для целых </xh4>
<tt>x '''div''' y = x / y, округленное до ближайшего целого по направлению к нулю.</tt> Это '''''результат''''' от ''целочисленного деления''.
+
<tt>x '''div''' y = x / y, округленное до ближайшего целого по направлению к нулю.</tt> Это '''''результат''''' от ''целочисленного деления''. <br />
<br><tt>x '''mod''' y = x - (x div y) * y.</tt> Это '''''остаток''''' от ''целочисленного деления''.
+
<tt>x '''mod''' y = x - (x div y) * y.</tt> Это '''''остаток''''' от ''целочисленного деления''.
  
'''Пример использования'''
+
''<u>Пример</u> использования'' <br />
<br>Целочисленные операции часто применяются для определения '''четности''' числа:
+
Целочисленные операции часто применяются для определения '''четности''' числа:
  x '''mod''' 2 = 0   <->  x — четное
+
  x '''mod''' 2 = 0   <->  x — четное
 
  x '''mod''' 2 <> 0  <->  x — нечетное
 
  x '''mod''' 2 <> 0  <->  x — нечетное
  
==Логические выражения==
+
=== Логические выражения ===
<h3>Основные сведения</h3>
+
<xh4> Основные сведения </xh4>
Выражение назывется '''''логическим''''', если оно имеет тип <tt>'''boolean'''.</tt>
+
Выражение назывется '''логическим''', если оно имеет тип <tt>'''boolean'''.</tt> <br />
<br><tt>'''Пример'''.</tt>
+
''<u>Пример</u>''.
 
  x < 0
 
  x < 0
 
  a >= b
 
  a >= b
 
  a <> 3
 
  a <> 3
 +
 
Это простые логические выражения. Однако, с помщью '''логических операций''' можно составлять сложные.
 
Это простые логические выражения. Однако, с помщью '''логических операций''' можно составлять сложные.
( бинарные )   ( унарные )
+
  (бинарные)     (унарные)
 
   a '''and''' b        '''not''' a
 
   a '''and''' b        '''not''' a
 
   a '''or''' b
 
   a '''or''' b
 
   a '''xor''' b
 
   a '''xor''' b
  
<h3>Таблицы истинности логических операций</h3>
+
<xh4> Таблицы истинности логических операций </xh4>
 
  a | b | a '''and''' b | a '''or''' b | a '''xor''' b  
 
  a | b | a '''and''' b | a '''or''' b | a '''xor''' b  
 
   
 
   
 
  T | T |    T    |  T    |    F
 
  T | T |    T    |  T    |    F
 
  T | F |    F    |  T    |    T
 
  T | F |    F    |  T    |    T
  F | T |    F    |  T    |    F
+
  F | T |    F    |  T    |    T
  F | F |    F    |  F    |    T
+
  F | F |    F    |  F    |    F
'''
+
 
<h3>Сокращение вычислений логических выражений</h3>
+
<xh4> Сокращение вычислений логических выражений </xh4>
Большинство современных компиляторов, в т.ч. PascalABC.NET производит '''''сокращенное вычисление логических выражений'''''.
+
Большинство современных компиляторов, в т.ч. PascalABC.NET производит '''''сокращенное вычисление логических выражений'''''. <br />
<br>Это означает, что в выражении
+
Это означает, что в выражении
 
  a '''and''' b
 
  a '''and''' b
если a — ложно, то b не вычисляется, а в
+
если a — ложно, то <tt>b</tt> не вычисляется, а в
 
  a '''or''' b
 
  a '''or''' b
если a — истинно, b не вычисляется.
+
если <tt>a</tt> — истинно, <tt>b</tt> не вычисляется.
  
 
Это очень полезно при вычислении таких выражений, как, например,
 
Это очень полезно при вычислении таких выражений, как, например,
  ( y <> 0 ) '''and''' (x / y > 0 )
+
  (y <> 0) '''and''' (x / y > 0)
Логически здесь все верно, однако, если бы не использовалось сокращенное вычисление, в случае равенства нулю y возникала бы ошибка деления на ноль.
+
 
 +
Логически здесь все верно, однако, если бы не использовалось сокращенное вычисление, в случае равенства нулю <tt>y</tt>'а возникала бы ошибка деления на ноль.
  
<h3>Логические переменные</h3>
+
<xh4> Логические переменные </xh4>
Можно описывать логические переменные ( тип <tt>boolean</tt> ). Им можно присваивать логические выражения.  
+
Можно описывать логические переменные (тип <tt>'''boolean'''</tt>). Им можно присваивать логические выражения. <br />
<br>Эти переменные принимают одно из двух возможных значений:
+
Эти переменные принимают одно из двух возможных значений:
:<tt>'''true'''</tt> ( истина )
+
:<tt>'''true'''</tt> (истина)
:<tt>'''false'''</tt> ( ложь )
+
:<tt>'''false'''</tt> (ложь)
  
'''Пример''' использования логических переменных
+
''<u>Пример</u> использования логических переменных'' <br />
:Дано: прямоугольник со сторонами, параллельными осям координат, задан координатами абсцисс вертикальных сторон ( x1, x2 ) и ординатами горизонтальных ( y1, y2 ); точка M( x, y );
+
Дано: прямоугольник со сторонами, параллельными осям координат, задан координатами абсцисс вертикальных сторон (<tt>x1, x2</tt>) и ординатами горизонтальных (y1, y2); точка M( x, y ); <br />
:Найти: находится точка внутри прямоугольника, снаружи, или лежит на границе;
+
Найти: находится ли точка внутри прямоугольника, снаружи, или лежит на границе;
  
 
<source lang="Pascal">
 
<source lang="Pascal">
Строка 313: Строка 250:
 
</source>
 
</source>
  
==Побитовые операции==
+
=== Побитовые операции ===
 
+
<xh4> Побитовые операции and, or, xor, not </xh4>
<h3>Побитовые операции and, or, xor</h3>
 
 
'''Замечание.''' Работают только с целыми.
 
'''Замечание.''' Работают только с целыми.
  
Смысл такой — каждое целое переводится в '''двоичную''' систему счисления и производится ''побитовое'' применение этих операций.
+
Соответствующая операция применяется к каждому биту двоичного представления числа. <br />
<br>'''Пример'''
+
''<u>Пример</u>.''
  5 '''and''' 10
+
  5 '''and''' 7
5<sub>10</sub> = 101<sub>2</sub>
+
5<sub>10</sub> = 101<sub>2</sub> <br />
<br>7<sub>10</sub> = 111<sub>2</sub>
+
7<sub>10</sub> = 111<sub>2</sub>
  
 
  101
 
  101
Строка 330: Строка 266:
 
  101<sub>2</sub> = 5<sub>10</sub>
 
  101<sub>2</sub> = 5<sub>10</sub>
  
<h3>Операции shl и shr</h3>
+
<xh4> Операции shl и shr </xh4>
''Побитовый'' '''сдвиг влево''' и '''сдвиг вправо''' соответственно.
+
'''''Побитовый сдвиг влево''''' и '''''сдвиг вправо''''' соответственно.
<h4>shl</h4>
+
 
 +
<xh4> shl </xh4>
 
  x '''shl''' n = x * 2<sup>n</sup>
 
  x '''shl''' n = x * 2<sup>n</sup>
Сдвигает двоичное представление x на n позиций влево.
+
 
<h4>shr</h4>
+
Сдвигает двоичное представление <tt>x</tt> на <tt>n</tt> позиций влево.
 +
 
 +
<xh4> shr </xh4>
 
  x '''shr''' n = x div 2<sup>n</sup>
 
  x '''shr''' n = x div 2<sup>n</sup>
Сдвигает двоичное представление x на n позиций вправо.
+
 
<h4>Примеры</h4>
+
Сдвигает двоичное представление <tt>x</tt> на <tt>n</tt> позиций вправо.
 +
 
 +
<xh4> Примеры </xh4>
 
  x = 5<sub>10</sub> = 101<sub>2</sub>
 
  x = 5<sub>10</sub> = 101<sub>2</sub>
 
   
 
   
Строка 347: Строка 288:
 
           001<sub>2</sub> = 1<sub>10</sub>
 
           001<sub>2</sub> = 1<sub>10</sub>
  
==Таблица приоритетов операций языка Object Pascal==
+
=== Таблица приоритетов операций языка Object Pascal ===
 
# унарные <tt>'''+ - not'''</tt>
 
# унарные <tt>'''+ - not'''</tt>
#имеющие смысл ''умножения'' <tt>'''* / div mod and shl shr'''</tt>
+
# имеющие смысл ''умножения'' <tt>'''* / div mod and shl shr'''</tt>
#имеющие смысл ''сложения'' <tt>'''+ - or xor'''</tt>
+
# имеющие смысл ''сложения'' <tt>'''+ - or xor'''</tt>
#операции ''отношения'' <tt>'''<> <= >= < > in'''</tt>
+
# операции ''отношения'' <tt>'''<> <= >= < > in'''</tt>
  
==Оператор case выбора варианта==
+
=== Условный оператор ===
<h3>Синтакстис</h3>
+
<xh4> Синтаксис </xh4>
  '''case''' <переключатель> '''of'''
+
  '''if''' <условие> '''then''' <оператор<sub>1</sub>>
  {<список выбора>: <оператор>;}
+
              ['''else''' <оператор<sub>2</sub>>]
  ['''else''' <оператор>[;]]
 
'''end'''
 
  
<h3>Семантика</h3>
+
<xh4> Семантика </xh4>
Вначале вычисляется выражение-'''''переключатель''''', после чего его значение ищется в одном из <списков выбора>.
+
[[Изображение: If.jpg]]
<br>Если значение попадает в какой-то <список выбора>, то выполняется соответствующий ему оператор, иначе, если есть ветвь <tt>'''else'''</tt>, то выполняется оператор по ветке <tt>'''else'''</tt>.
 
<h3>Ограничения</h3>
 
*выражение-переключатель должно иметь так называемый '''порядковый''' тип:
 
:''целый''
 
:''символьный''
 
:''перечислимый''
 
НО НЕ строковый или вещественный.
 
*значения в <списках выбора> не должны пересекаться.
 
<h3>Примеры использования оператора выбора</h3>
 
'''Пример 1.''' День недели
 
<source lang="Pascal">
 
case DayOfWeek of
 
  1..5: writeln('Будний');
 
  6,7: writeln('Выходный');
 
  else writeln('Ошибка');
 
end;</source>
 
'''Пример 2.''' Цифра или буква
 
<source lang="Pascal">
 
var c: char;
 
read(c);
 
case c of
 
  '0'..'9': writeln('Цифра');
 
  'A'..'Z', 'a'..'z', 'а'..'я', 'А'..'Я', 'ё', 'Ё': writeln('Буква');
 
end;</source>
 
  
<small>'''Лекция 5'''</small>
+
==== Примеры использования для решения задач ====
 +
''<u>Пример 1</u>.'' Нахождение минимума
 +
<br>Дано: <tt>x, y</tt>
 +
<br>Найти: <tt>min</tt>
  
==Циклы с предусловием (while) и постусловием (repeat)==
+
<source lang="Pascal">
<h3>Синтаксис цикла while</h3>
+
if x > y then
'''while''' <условие> '''do'''  <— '''''заголовок цикла'''''
+
   min := y
  <оператор>  <— '''''тело цикла'''''
+
else
+
  min := x;
<условие>::= <логическое выражение>
+
</source>
<h3>Семантика цикла while</h3>
 
[[Изображение:Цикл_while_м.png]]
 
<h3>Синтаксис цикла repeat</h3>
 
'''repeat'''
 
  <операторы>
 
'''until''' <условие>
 
<h3>Семантика цикла repeat</h3>
 
[[Изображение:Цикл_repeat_м.png]]
 
<h3>Зацикливание</h3>
 
'''''Зацикливание''''' происходит, если:
 
*условие цикла с '''предусловием''' всегда ''истинно''
 
Пример
 
<source lang="Pascal">while true do
 
  <оператор></source>
 
*условие цикла с '''постусловием''' всегда ''ложно''
 
Пример
 
<source lang="Pascal">repeat
 
   <операторы>
 
until false</source>
 
'''''Итерация''''' — однократное повторение тела цикла
 
<h4>Отличия между циклами while и repeat</h4>
 
'''while'''
 
:тело может не выполниться ни разу
 
'''repeat'''
 
:тело выполнится хотя бы один раз
 
<h4>Примеры</h4>
 
'''Пример 1.''' Сумма нечетных двузначных чисел
 
  
''С использованием while''
+
''<u>Пример 2</u>.'' Упорядочение <tt>a, b</tt> по возрастанию.
<source lang="Pascal">s := 0; x := 11;
+
<br>Ясно, что если a > b, — нужно [[Основы программирования — Осенний семестр; Михалкович С.С.; 2008; II#Примеры использования := | поменять их местами]]. <br />
while x < 100 do
+
Но тут одним оператором не обойтись.
 +
Для этого можно использовать '''''составной оператор''''' — один или больше операторов, заключенных в операторные скобки <tt>'''begin'''  - '''end''';</tt>:
 +
<source lang="Pascal">if a > b then
 
begin
 
begin
   s += x;
+
   var v := b;
   x += 2;
+
   b := a;
end;</source>
+
   a := v;
''С использованием repeat''
+
end;
<source lang="Pascal">s := 0; x := 11;
+
</source>
repeat
 
   s += x;
 
  x += 2;
 
until x = 99;</source>
 
  
'''Пример 2.''' Факториал
+
''<u>Пример 3</u>.'' Вычисление функции по взаимоисключающим веткам <br />
 +
<math>y = \begin{cases} x, & x < 2 \\ x^2, & 2 < x < 3 \\ 1-x, & x \ge\; 3 \end{cases}</math>
 +
<source lang="Pascal">
 +
if x < 2 then
 +
  y := x
 +
else if x < 3 then
 +
  y := x * x
 +
else y := 1 - x;
 +
</source>
  
''С использованием repeat''
+
'''Замечание.''' Если по ветви '''<tt>else</tt>''' располагается другой оператор '''<tt>if</tt>''', то говорят, что возникает '''''цепочка вложенных операторов <tt>if</tt>'''''.
<source lang="Pascal">var n: integer;
 
read(n);
 
var x := n;
 
var p :=1;
 
  
repeat
+
====Координаты средней точки====
  p *= x;
+
''<u>Пример 4</u>.'' Даны координаты трех точек на прямой <tt>a, b, c</tt> (<tt>a, b, c</tt> попарно не равны). Найти m - координаты средней точки <br />
  x -= 1;
 
until x = 1;</source>
 
''С использованием while''
 
<source lang="Pascal">var n: integer;
 
read(n);
 
var x := n;
 
var p :=1;
 
  
while x > 1 do
+
'''Решение 1.'''
begin
 
  p *= x;
 
  x -= 1;
 
end;</source>
 
<h3>Моделирование repeat с помощью while</h3>
 
'''repeat'''            ''Op''
 
  '' Op''      ——>    '''while''' '''not''' A '''do'''
 
'''until''' A;          '''begin'''
 
                      ''Op''
 
                    '''end;'''
 
<h3>Моделирование while с помощью repeat</h3>           
 
'''while''' A '''do'''        '''if''' A '''then'''
 
  ''Op''        ——>    '''repeat'''
 
                      '' Op''
 
                      '''until not''' A
 
  
==Оператор цикла с параметром (for)==
+
Достаточно рассмотреть случай, когда координаты точек равны 1,2 и 3
<h3>Синтаксис</h3>
 
<заголовок цикла>
 
  <тело цикла>
 
  
<заголовок цикла> ::= '''for''' <переменная>:=<выражение1> <направление> <выражение2> '''do'''
+
Рассмотрим все возможные ситуации распределения этих значений между a,b,c:
<тело цикла> ::= <оператор>
 
<направление> ::= to | downto
 
<h3>Семантика</h3>
 
<source lang="Pascal">var b := <выражение1>;
 
var e := <выражение2>;
 
  <переменная> := b;
 
 
while <переменная> <> e do
 
begin
 
  <оператор>
 
  <получить следующее значение переменной>
 
  <переменная> += 1; | <переменная> -= 1;
 
end;
 
</source>
 
  
  <получить следующее значение переменной> ::= <переменная> '''+'''= 1; | <переменная> '''-'''= 1;
+
  a  b  c
'''<big>Ограничения:</big>'''
+
1 2  3  a<b
*выражения 1 и 2 должны быть совместимы по присваиванию с переменной
+
1 2 a<b
*переменная должна иметь порядковый тип ( такой же, как и в case — целый, символьный или перечислимый )
+
2  1  3
*переменная цикла for не должна меняться внутри цикла for
+
2  3  1 a<b
*переменная цикла for должна быть описана в той же п/п, где используется цикл
+
3  1  2
<h3>Дополнительные возможности PascalABC.NET</h3>
+
3  2  1
Возможно ''описание переменной цикла в его заголовке'':
 
<source lang="Pascal">for [var] i: integer := 1 to 5 do
 
  <оператор></source>
 
Возможно ''автоопределение типа при описании'':
 
<source lang="Pascal">for var i := 1 to 5 do
 
  <оператор></source>
 
Переменная цикла, описанная в заголовке цикла, определена только внутри цикла.
 
'''Замечание!''' Значение переменной цикла после завершения цикла не определено. Именно поэтому рекомендуется описывать переменную цикла в заголовке цикла.
 
  
==Примеры использования циклов==
+
При a<b возможны три варианта, в двух из которых a<c.
<h3>Пример 1. Табулирование функции</h3>
+
При a>b возможны три варианта, в двух из которых a>c.
:Дана f(x) на [a; b], разбитая на N частей.
 
:Выдать таблицу значений в точках разбиения.
 
'''Решение'''
 
<source lang="Pascal">var a, b: real;
 
var N: integer;
 
read(a, b, N);
 
  
assert(N <> 0);
+
Решение представляется вложенными операторами if с уровнем вложенности 3.
assert(b > a);
 
var h := (b - a) / N;</source>
 
''Дальнейшее решение с помощью'' '''for''':
 
<source lang="Pascal">for var i:=0 to N do
 
begin
 
  writelnFormat('{0,6:f2} {1,9:f4}', x, f(x));
 
  x += h;
 
end;</source>
 
''Дальнейшее решение с помощью'' '''while''':
 
<source lang="Pascal">var eps := h / 2;
 
while x < (b + eps) do
 
begin
 
  writelnFormat('{0,6:f2} {1,9:f4}', x, f(x));
 
  x += h;
 
end;</source>
 
'''Замечание.''' Вещественные числа в памяти компьютера представлены приближенно. Ошибка, которая возникает при представлении вещественного числа в памяти, называется '''''ошибкой округления'''''.
 
<br>Ошибка, которая возникает в результате вычислений с вещественными числами называется '''''вычислительной погрешностью'''''.
 
  
:'''Вывод.''' Вещественные числа нельзя сравнивать на равенство, можно только на ''больше/меньше''.
+
<source lang="Pascal">
<small>'''Лекция 6'''</small>
+
if a < b then
===Рекуррентные соотношения===
+
   if a < c then
Говорят, что последовательность данных
+
    if b < c then
x<sub>1</sub>, x<sub>2</sub>, x<sub>3</sub>,..., x<sub>n</sub>
+
      m := b
является '''''рекуррентной''''', если
+
    else
x<sub>k + 1</sub> = f( x<sub>k</sub> ), k = 1, 2, 3...
+
      m := c
<h3>Пример 2. Вывод степеней двойки</h3>
+
  else
<source lang="Pascal">var x := 1;
+
    m := a
for var i:=1 to 10 do
+
else
begin
+
   if a > c then
   writeln(x);
+
    if b < c then
  x *= 2;
+
      m := c
end;</source>
+
    else
<h3>Пример 3. Последовательность Фибоначчи</h3>
+
      m := b
<math>\begin{cases} x_1 = 1, x_2 = 1 \\ x_{k+1} = x_k + x_{k-1}\end{cases}</math>
+
   else m := a;
<source lang="Pascal">var a := 1;
+
</source>
var b := 1;
 
write(a, ' ', b, ' ');
 
for var i := 3 to 20 do
 
begin
 
   c := a + b;
 
  write(c, ' ');
 
  a := b;
 
   b := c;
 
end;</source>
 
<h3>Пример 4. Вычисление НОД (алгоритм Евклида)</h3>
 
<math>\begin{cases} x_1 = a \\ x_2 = b \\ x_{k+1} = x_{k-1} mod  x_k\end{cases}</math>
 
  
'''Решение'''
+
По количеству операций (3 сравнения, одно присваивание) это - самое лучшее решение
<source lang="Pascal">var a, b: integer;
 
read(a, b);
 
assert((a > 0) and (b > 0));
 
repeat
 
  c := a mod b;
 
  a := b;
 
  b := c;
 
until c = 0;
 
writeln(a);</source>
 
  
===Пример 5. Суммирование рядов (конечных и бесконечных)===
+
То же решение, записанное с помощью функции min:
*<math> \sum_{i=1}^n  \frac{a^i}{i!}</math>
 
Найдем рекуррентную связь между '''a<sub>i</sub>''':
 
x<sub>1</sub> = a
 
x<sub>i</sub> = x<sub>i-1</sub> * a / i, i = 2, 3..
 
'''Решение'''
 
<source lang="Pascal">read(a, n);
 
x := a;
 
s := x;
 
for var i:=2 to n do
 
begin
 
  x *= a / i;
 
  s += x;
 
end;</source>
 
*<math> \sum_{i=1}^\infty  (-1)^i\frac{a^i}{i}</math>
 
Для вычисления суммы ''бесконечного ряда'' в простейшем случае используют следующий метод:
 
:задается некоторый малый <tt>'''eps'''</tt> и сумма <math>\sum_{i=1}^\infty  x_i</math> вычисляется, пока <math>|x_i| <\ eps</math>
 
  
'''Решение'''
+
<source lang="Pascal">
<source lang="Pascal">assert((a > 0) and (a < 1));
+
if a < b then
i := 1;
+
  if a < c then
s := 0;
+
    m := min(b,c)
y := -a;
+
  else m := a
repeat
+
else
   s += y / i;
+
   if a > c then
  i += 1;
+
    m := min(b,c)
   y *= -a;
+
   else m := a;
until abs(y / i) < eps;</source>
+
</source>
  
===Пример 6. Нахождение max в последовательности чисел===
+
'''Решение 2.'''
'''Решение'''
 
<source lang="Pascal">max := - real.MaxValue;
 
for var i:=1 to n do
 
begin
 
  read(x);
 
  if x > max then
 
    max := x;
 
end;</source>
 
  
<h3>Пример 7. Разложение целого числа на простые множители</h3>
+
<source lang="Pascal">
Будем делить x на p, начиная с ''p = 2''. Если делится нацело, то p — множитель, если не делится, то увеличиваем p на 1, пока ''x <> 1''.
+
var m1 := min(a,b);
 +
var m2 := max(a,b);
 +
</source>
  
'''Решение'''
+
a  b  c 
<source lang="Pascal">read(x);
+
1  2  3  c>m2
p := 2;
+
1  3  2
repeat
+
2  1  3  c>m2
  if x mod p = 0 then
+
2  3  1  c<m1
  begin
+
1
    write(p, ' ');
+
3  2  1 c<m1
    x := x div p;
 
  end
 
  else
 
    p += 1;
 
until x = 1;</source>
 
  
<small>'''Лекция 7'''</small>
+
<source lang="Pascal">
===Операторы break и continue===
+
var m1 := min(a,b);
'''break''' — оператор ''досрочного завершения цикла''.
+
var m2 := max(a,b);
[[Изображение:break_м.png|none]]
+
if c<m1 then
'''continue''' — оператор ''досрочного завершения текущей итерации'' цикла.
+
   m := m1
[[Изображение:continue_м.png|none]]
+
else if c>m2 then
<h3>Пример 8. Поиск заданного значения среди введенных</h3>
+
   m := m2
'''Решение 1'''. С использованием оператора ''break''
+
else m := c;
<source lang="Pascal">var exists: boolean := false;
+
</source>
for var i:=1 to n do
 
begin
 
  read(x);
 
  if x = k then
 
  begin
 
    exists := true;
 
    break;
 
  end;
 
end;</source>
 
'''Решение 2'''
 
<source lang="Pascal">var i := 1;
 
var exists: boolean:= false;
 
repeat
 
  read(x);
 
  if x = k then
 
    exists := true;
 
   i += 1;
 
until (i > n) or exists;</source>
 
<h3>Пример 9. Обработка последовательности, завершающейся нулем</h3>
 
:Вводятся числа. Конец ввода — ноль.
 
:Найти сумму и произвведение положительных чисел.
 
'''Решение'''
 
<source lang="Pascal">s := 0;
 
p := 1;
 
while True do
 
begin
 
  read(x);
 
  if x = 0 then
 
    break;
 
  if x < 0 then
 
    continue;  //фильтр
 
   s += x;
 
  p *= x;
 
end;</source>
 
===Пример 10. Вычисление значения многочлена. Схема Горнера===
 
Необходимо вычислить
 
<math>\ a_0x^n + a_1x^{n-1} + ... + a_{n-1}x + a_n</math>
 
если
 
:a<sub>0</sub>...a<sub>n</sub> известны
 
:x дано
 
  
'''Решение1'''
+
Данное решение менее эффективно по числу сравнений и присваиваний (посчитайте самостоятельно), но по понятности может восприниматься лучше предыдущего.
<source lang="Pascal">var p := 1.0;
 
var s := 0.0;
 
for var i:=0 to n do
 
begin
 
  read(a);
 
  s += p * a;
 
  p *= x;
 
end;</source>
 
Это решение использует <tt>2(n + 1)</tt> умножений.
 
  
Однако есть и другое решение — '''схема Горнера'''.
+
====Самостоятельные задания====
Оно основана на том, что
+
* Даны координаты вершин треугольника и точка M, не лежащая на границе треугольника. Принадлежит ли M треугольнику.
<br><math>\ a_0x^2 + a_1x + a_2 = ((a_0)x + a_1)x + a_2</math>
+
* Является ли 4-угольник ABCD корректно заданным.
  
'''Решение2'''
+
=== Оператор case выбора варианта ===
<source lang="Pascal">read(a);
+
<xh4> Синтакстис </xh4>
var res: real := a;
+
'''case''' <переключатель> '''of'''
for var i:=1 to n do
+
  {<список выбора>: <оператор>;}
begin
+
  ['''else''' <оператор>[;]]
  read(a);
+
'''end'''
  res *= x;
 
  res += a;
 
end;</source>
 
Итого — всего <tt>n</tt> умножений.
 
===Пример 11. Поиск нуля функции на отрезке===
 
Требуется найти корень уравнения <tt>f( x ) = 0</tt>
 
*на отрезке <tt>[a; b]</tt>
 
*с заданной точностью eps
 
*<tt>f(x)</tt> непрерывна на этом отрезке
 
*имеет на нем ровно 1 корень, т.е. <tt>f(a ) * f( b ) < 0</tt>
 
  
Эта задача решается '''методом половинного деления'''.
+
<xh4> Семантика </xh4>
<source lang="Pascal">assert(b > a);
+
Вначале вычисляется выражение-<tt><переключатель></tt>, после чего его значение ищется в одном из <tt><списков выбора></tt>. <br />
var fa := f(a);
+
Если значение попадает в какой-то <tt><список выбора></tt>, то выполняется соответствующий ему оператор, иначе, если есть ветвь '''<tt>else</tt>''', то выполняется оператор по ветке <tt>else</tt>.
var fb := f(b);
 
assert(fa * fb < 0);
 
  
while b - a > eps do
+
<xh4> Ограничения </xh4>
begib
+
* выражение-переключатель должно иметь так называемый '''''порядковый''''' тип:
  var x := (b + a) / 2;
+
:''целый''
  var fx := f(x);
+
:''символьный''
  if f(x) * f(a) > 0 then
+
:''перечислимый''
  begin
+
НО НЕ строковый или вещественный.
    a := x;
+
* значения в <tt><списках выбора></tt> не должны пересекаться.
    fa := fx;
 
  end
 
  else
 
    b := x;
 
end;</source>
 
<small>'''Лекция 8'''</small>
 
  
==Вложенные циклы==
+
<xh4> Примеры использования оператора выбора </xh4>
<h3>Метод последовательной детализации</h3>
+
''<u>Пример 1</u>.'' День недели
'''Задача.''' Вывести все простые числа <= n
+
<source lang="Pascal">
<source lang="Pascal">writeln(2);
+
case DayOfWeek of
x := 3;
+
  1..5: writeln('Будний');
while x <= n do
+
   6, 7: writeln('Выходный');
begin
+
   else  writeln('Ошибка');
   Если число x — простое, то
+
end;
    writeln(x);
+
</source>
   x += 2;
 
end;</source>
 
<h3>Метод окаймления</h3>
 
'''Задача.''' Вывести A<sup>k</sup>, A = 2..10
 
  
'''Метод окаймления''' заключается в том, что что мы окаймляем данный алгоритм внешним циклом, "''размораживая''" некоторый параметр.
+
''<u>Пример 2</u>.'' Цифра или буква
 
+
<source lang="Pascal">
Итак, пусть A — фиксировано( "''заморожено''" ).
+
var c: char;
<source lang="Pascal">var p := 1.0;
+
read(c);
for var i:=1 to k do
+
case c of
  p *= A;
+
  '0'..'9': writeln('Цифра');
write(p);</source>
+
  'A'..'Z', 'a'..'z', 'а'..'я', 'А'..'Я', 'ё', 'Ё': writeln('Буква');
Теперь ''размораживаем'' A:
+
end;
<source lang="Pascal">for A:=2 to 10 do
+
</source>
begin
 
  ...
 
end;</source>
 
<h3>Переборные задачи</h3>
 
Класс задач, в которых требуется перебрать множество вариантов и выбрать несколько оптимальных по каким-то критериям.
 
 
 
'''Задача'''
 
:Дано равенство: a<sup>2</sup> + b<sup>2</sup> = c<sup>2</sup>, a,b,c — целые
 
:Вывести все такие тройки (a, b, c), что: a<=100, b<=1000, c<=1000;
 
'''Решение'''
 
<source lang="Pascal">for var a:=1 to 1000 do
 
  for var b:=1 to 1000 do
 
    for var c:=1 to 1000 do
 
      if a*a + b*b = c*c then
 
        writeln(a, b, c);</source>
 
Однако, ясно, что
 
a<sup>2</sup> + b<sup>2</sup> = c<sup>2</sup> <=> b<sup>2</sup> + a<sup>2</sup> = c<sup>2</sup>
 
'''Оптимизация'''
 
<source lang="Pascal">for var a:=1 to 1000 do
 
  for var b:=1 to a-1 do
 
  begin
 
    var c := round(sqrt(a*a + b*b));
 
    if a*a + b*b = c*c then
 
    begin
 
      writeln(a, b, c);
 
      writeln(b, a, c);
 
    end;
 
  end;</source>
 
'''Вывод.''' При наличии нескольких вложенных циклов нужно оптимизировать ''самый внутренний''.
 

Текущая версия на 11:21, 14 сентября 2013

К основной странице курса

Основные операторы

Оператор присваивания :=

<xh4> Синтаксис </xh4>

<переменная> := <выражение>

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

a := (3 + 5) * 8; 
b := a + 2;

<xh4> Семанитика </xh4> Вычисляется выражение в правой части, при этом, вместо имен переменных подставляются их значения.
Затем результат вычисления записывается в переменную в левой части.

Ограничение. Тип выражения должен быть совместим по присваиванию с переменной.
Например:

  • одинаковые типы совместимы.
  • выражение типа integer можно присвоить переменной типа real. Обратное неверно.

<xh4> Операторы присваивания += и *= </xh4> Пример.

d += 1; //прибавить 1 к d
d *= 2; //умножить d на 2

<xh4> Примеры использования := </xh4> Пример 1. Перемена местами двух значений. Дано: x, y;

var x, y: integer;
begin
  read(x,y);
  var v := x;
  x := y;
  y := v;
  writeln(x, ' ', y);
end.

Это стандартное решение. В PascalABC.NET на основе этого алгоритма определена стандартная процедура Swap(x, y).

Однако, существуют и другие решения. Например:

var x, y: integer;
begin
  read(x, y);
  x := x + y;
  y := x - y;
  x := x - y;
  writeln (x, ' ', y);
end.

Пример 2. Использование промежуточных переменных в вычислениях Дано: x: real; Найти: x15;

Решение 1.

y := x * x;
z := y * y;
t := z * z;
p := t * z;
q := p * x * y;

Решение 2.

y := x * x;
z := y * x;
t := z * y;
p := t * t * t;

Решение 3.

y := x * x;
x := x * y * y;
t := x * x * x;

Заметим, что в первом решении используется 6 операций умножения, в во 2м и 3м — 5. Возникает задача: найти xn за минимальное число умножений.
Об этом читай тему.

Оператор ввода

<xh4> Синтаксис </xh4>

read (<список переменных>) | readln (<список переменных>)

<xh4> Семантика </xh4> Происходит считывание данных с клавиатуры и запись их в переменные из <списка переменных>. Вводить данные нужно либо через пробел, либо по нажатию <Enter>, при этом программа не перейдет к выполнению следующего оператора, пока не будут считаны все данные.

Имеются также стандартные функции ReadInteger, ReadReal, ReadlnInteger, ReadlnReal:

var n := ReadInteger;
var r := ReadlnReal;

С процедурой ввода связан ряд ошибок времени выполнения (например, если переменная используется в качестве делителя, и вводится 0, или, если должно быть получено целое число, а вводится 'ABC'). Эти ошибки нужно уметь обрабатывать.

Оператор try/except и обработка ошибок ввода

Операторы, которые могут получать ошибку, заключаются специальный охранный блок - оператор try.

<xh4> Синтаксис </xh4>

try
  ...
  readln(a);
  ...
except
  <обработка ошибки>
end;
<продолжение работы>

<xh4> Семантика </xh4> Если внутри блока try происходит ошибка выполнения, то все последующие операторы в блоке игнорируются, и выполнение программы переходит к блоку except. По выходе из except программа продолжает работу.

Если ошибки не происходит, то выполняются все операторы в блоке try, блок except не выполняется, и программа продолжает работу.

Оператор вывода

<xh4> Синтаксис </xh4>

write(<список выражений>) | writeln(<список выражений>)

<xh4> Семантика </xh4> Выражения в списке вычисляются, и их значения выводятся на экран.
В случае writeln после вывода осуществляется переход на новую строку.

<xh4> Форматы вывода </xh4> После каждого выражения в списке вывода можно использовать формат вывода в виде :a, где a — выражение целого типа.
После вещественного типа — :a:b (a задает ширину поля вывода (выравнивание по правому краю), b — количество знаков в дробной части).

<xh4> Вывод с помощью write[ln]Format </xh4>

writelnFormat('<форматная строка>', <список выражений>)

Пример вывода с использованием форматной строки.

writelnFormat('{0} * {1} = {2}', a, b, a * b)

Будет выведено:

a * b = a * b

В форматной строке тоже можно использовать формат вывода.
{0, 10}: 10 — это ширина поля вывода
{0, 10:f3}: 3 — это количество знаков в дробной части для вещественного числа (показывает это спецификатор f).
{0, 10:e3} — экспоненциальный формат.

Арифметические выражения

Основные сведения

Каждое выражение имеет тип. Выражение называется арифметическим, если его тип — числовой.
Выражение строится посредством операций (унарных или бинарных) и операндов.

В арифметических выражениях если a и b — одного типа, то и a op b принадлежит к тому же типу. Исключением является операция "/":

a / b — вещественное.

Если a и b принадлежат к различным типам, то выражение принадлежит к "старшему" типу.
Например:

byte < integer < int64
integer < real

Стандартные функции

В арифметические выражения могут входить стандартные функции:

exp(x)
ln(x)
abs(x)  // модуль x
sin(x)
cos(x)
sqr(x)  // квадрат x
sqrt(x) // корень из x 
round(x) - целое, полученное в результате округления вещественного x
trunc(x) - целое, полученное в результате отбрасывания дробной части у вещественного x
min(x,y) 
max(x,y) 
power(x,y)// x в степени y
random(n)// псевдослучайное целое число от 0 до n-1
random(a,b)// псевдослучайное целое число от a до b

<xh4> Порядок выполнения операций в арифметических выражениях </xh4>

  • Операции с большим приоритетом выполняются первыми
  • Функции вычисляются до операций
  • Выражение в скобках вычисляется раньше
  • Операции с одинаковым приоритетом выполняются слева направо, если идут подряд.

<xh4> Операции div и mod для целых </xh4> x div y = x / y, округленное до ближайшего целого по направлению к нулю. Это результат от целочисленного деления.
x mod y = x - (x div y) * y. Это остаток от целочисленного деления.

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

x mod 2 = 0    <->   x — четное
x mod 2 <> 0   <->   x — нечетное

Логические выражения

<xh4> Основные сведения </xh4> Выражение назывется логическим, если оно имеет тип boolean.
Пример.

x < 0
a >= b
a <> 3

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

 (бинарные)     (унарные)
  a and b         not a
  a or b
  a xor b

<xh4> Таблицы истинности логических операций </xh4>

a | b | a and b | a or b | a xor b 

T | T |    T    |   T    |    F
T | F |    F    |   T    |    T
F | T |    F    |   T    |    T
F | F |    F    |   F    |    F

<xh4> Сокращение вычислений логических выражений </xh4> Большинство современных компиляторов, в т.ч. PascalABC.NET производит сокращенное вычисление логических выражений.
Это означает, что в выражении

a and b

если a — ложно, то b не вычисляется, а в

a or b

если a — истинно, b не вычисляется.

Это очень полезно при вычислении таких выражений, как, например,

(y <> 0) and (x / y > 0)

Логически здесь все верно, однако, если бы не использовалось сокращенное вычисление, в случае равенства нулю y'а возникала бы ошибка деления на ноль.

<xh4> Логические переменные </xh4> Можно описывать логические переменные (тип boolean). Им можно присваивать логические выражения.
Эти переменные принимают одно из двух возможных значений:

true (истина)
false (ложь)

Пример использования логических переменных
Дано: прямоугольник со сторонами, параллельными осям координат, задан координатами абсцисс вертикальных сторон (x1, x2) и ординатами горизонтальных (y1, y2); точка M( x, y );
Найти: находится ли точка внутри прямоугольника, снаружи, или лежит на границе;

var inside, outside, bound: boolean;
begin
  inside := (x > x1) and (x < x2) and (y > y1) and (y < y2);
  outside := (x < x1) or (x > x2) or (y < y1) or (y > y2);
  bound := not inside and not outside;
end.

Побитовые операции

<xh4> Побитовые операции and, or, xor, not </xh4> Замечание. Работают только с целыми.

Соответствующая операция применяется к каждому биту двоичного представления числа.
Пример.

5 and 7

510 = 1012
710 = 1112

101
   ( and )
111
———
1012 = 510

<xh4> Операции shl и shr </xh4> Побитовый сдвиг влево и сдвиг вправо соответственно.

<xh4> shl </xh4>

x shl n = x * 2n

Сдвигает двоичное представление x на n позиций влево.

<xh4> shr </xh4>

x shr n = x div 2n

Сдвигает двоичное представление x на n позиций вправо.

<xh4> Примеры </xh4>

x = 510 = 1012

x shl 2 = <—(2)101
             101002 = 2010

x shr 2 = 101—>(2)
          0012 = 110

Таблица приоритетов операций языка Object Pascal

  1. унарные + - not
  2. имеющие смысл умножения * / div mod and shl shr
  3. имеющие смысл сложения + - or xor
  4. операции отношения <> <= >= < > in

Условный оператор

<xh4> Синтаксис </xh4>

if <условие> then <оператор1>
             [else <оператор2>]

<xh4> Семантика </xh4> If.jpg

Примеры использования для решения задач

Пример 1. Нахождение минимума
Дано: x, y
Найти: min

if x > y then
  min := y
else
  min := x;

Пример 2. Упорядочение a, b по возрастанию.
Ясно, что если a > b, — нужно поменять их местами.
Но тут одним оператором не обойтись. Для этого можно использовать составной оператор — один или больше операторов, заключенных в операторные скобки begin - end;:

if a > b then
begin
  var v := b;
  b := a;
  a := v;
end;

Пример 3. Вычисление функции по взаимоисключающим веткам
<math>y = \begin{cases} x, & x < 2 \\ x^2, & 2 < x < 3 \\ 1-x, & x \ge\; 3 \end{cases}</math>

if x < 2 then
  y := x
else if x < 3 then
  y := x * x
else y := 1 - x;

Замечание. Если по ветви else располагается другой оператор if, то говорят, что возникает цепочка вложенных операторов if.

Координаты средней точки

Пример 4. Даны координаты трех точек на прямой a, b, c (a, b, c попарно не равны). Найти m - координаты средней точки

Решение 1.

Достаточно рассмотреть случай, когда координаты точек равны 1,2 и 3

Рассмотрим все возможные ситуации распределения этих значений между a,b,c:

a  b  c
1  2  3  a<b
1  3  2  a<b
2  1  3
2  3  1  a<b
3  1  2
3  2  1

При a<b возможны три варианта, в двух из которых a<c. При a>b возможны три варианта, в двух из которых a>c.

Решение представляется вложенными операторами if с уровнем вложенности 3.

if a < b then
  if a < c then
    if b < c then
      m := b
    else
      m := c
  else
    m := a
else
  if a > c then
    if b < c then
      m := c
    else
      m := b
  else m := a;

По количеству операций (3 сравнения, одно присваивание) это - самое лучшее решение

То же решение, записанное с помощью функции min:

if a < b then
  if a < c then
    m := min(b,c)
  else m := a
else
  if a > c then
    m := min(b,c)
  else m := a;

Решение 2.

var m1 := min(a,b);
var m2 := max(a,b);
a  b  c  
1  2  3  c>m2
1  3  2  
2  1  3  c>m2
2  3  1  c<m1
3  1  2  
3  2  1  c<m1
var m1 := min(a,b);
var m2 := max(a,b);
if c<m1 then
  m := m1
else if c>m2 then
  m := m2
else m := c;

Данное решение менее эффективно по числу сравнений и присваиваний (посчитайте самостоятельно), но по понятности может восприниматься лучше предыдущего.

Самостоятельные задания

  • Даны координаты вершин треугольника и точка M, не лежащая на границе треугольника. Принадлежит ли M треугольнику.
  • Является ли 4-угольник ABCD корректно заданным.

Оператор case выбора варианта

<xh4> Синтакстис </xh4>

case <переключатель> of
  {<список выбора>: <оператор>;}
  [else <оператор>[;]]
end

<xh4> Семантика </xh4> Вначале вычисляется выражение-<переключатель>, после чего его значение ищется в одном из <списков выбора>.
Если значение попадает в какой-то <список выбора>, то выполняется соответствующий ему оператор, иначе, если есть ветвь else, то выполняется оператор по ветке else.

<xh4> Ограничения </xh4>

  • выражение-переключатель должно иметь так называемый порядковый тип:
целый
символьный
перечислимый

НО НЕ строковый или вещественный.

  • значения в <списках выбора> не должны пересекаться.

<xh4> Примеры использования оператора выбора </xh4> Пример 1. День недели

case DayOfWeek of
  1..5: writeln('Будний');
  6, 7: writeln('Выходный');
  else  writeln('Ошибка');
end;

Пример 2. Цифра или буква

var c: char;
read(c);
case c of
  '0'..'9': writeln('Цифра');
  'A'..'Z', 'a'..'z', 'а'..'я', 'А'..'Я', 'ё', 'Ё': writeln('Буква');
end;