Теория
Все программы работают с данными. Например целые числа, вещественные числа, строки - это данные. Данные могут быть постоянными, например дата рождения, а могут быть и переменными : например возраст.
Итак давайте представим следующую задачу: необходимо решить уравнение вида ax2 + bx + c = 0.
Из математики нам известно, что решением такого уравнения являются числа:
x1,2 = - b ± (b2 - 4ac)1/2
2a
Где (b2 - 4ac)1/2 - это корень квадратный из числа b2 - 4ac. Спасибо Андрею, который подсказал это изображение корня.
Тем самым нам нужно знать 3 числа: a, b, c. Для конкретных чисел посчитаь всё можно на бумажке, а для любых коэффициентов??
Тут нам понадобятся переменные. В программе написанной на языке паскаль для переменных отводится специальная "секция" VAR (агн VARiable - переменная) и каркас программы выглядит так:
Program ИмяПрограммы;
var
Здесь идёт объявление переменных.
begin
Здесь идёт текст программы.
end.
Переменные - это и есть наши данные. Так как Паскаль является строго типизированным языком, то каждой переменной ставится в соответствие свой тип. И для этой переменной разрещены операции допустимые типом. Но мы не всегда можем делать операции между типами: например нельзя сложить число 5 и строку 'Hello world!'!
Объявляются переменные таким образом:ИмяПеременной : ИмяТипа;
В языке Паскаль существует очень разветвлённая система типов и сегодня мы поговорим только 2 из них: Целые и Вещественные.
Целые типы.
Имя типа. |
Диапозон значений. |
Размер памяти. |
ShortInt |
- 128 .. 127 |
1 байт |
Integer |
- 32768 .. 32767 |
2 байтa |
Long |
- 2147483648 .. 2147483647 |
4 байтa |
Byte |
0 .. 255 |
1 байт |
Word |
0 .. 65535 |
2 байтa |
Теперь я думаю понятно, что если нам надо решить уравнение с целыми коэффициентами, менее 32768 и более - 32768, то а,b,c мы должны объявить следующим образом:
Program Decision_of_quadratic_equalation;
var
a : integer;
b : integer;
c : integer;
begin
Здесь идёт текст программы.
end.
Так же переменные одного типа можно записывать в строчку: a, b, c : integer;
Благодаря такой системе типов мы можем всегда выбрать максимально нам подходящий!
В некоторых языках программирования вообще нет такого понятия, как тип переменной. Наглядный пример - Бейсик. В нём под каждую переменную выделяется максимальное количество памяти. Однако это не рационально. Если мы точно знаем, что переменная Х больше 0 и меньше 255, то зачем нам тратить лишние байты драгоценной памяти ? Но если размер заранее не известен, то лучше подстраховаться.
Итак теперь мы умеем выбирать нужный нам тип переменной, объявлять её.... теперь нам нужно научится что -то с ней делать :))
Так как данные целого типа являются по существу математическими переменными (во загнул-то:), то для них определены операции:
- :=
- присваивание ( двоеточие и равно всегда пишутся слитно!)
Например присвоить a значение 123: a := 123;
Присвоить а значение b: a := b;
Очень частая ошибка: забывают ставить двоеточие перед знаком равно! А что такое просто знак равно, мы поговорим позже и подробнее! Главное привыкнуть к такой записи :=
- +
- сложение
Идём от простого к сложному: присвоить а значение 120 + 3: а := 120 + 3;
Присвоить b значение а + 123: b := a + 123;
Присвоить с значение a + b + 123: c := a + b + 123;
И самое сложное присвоить с старое значение + 3: c := c + 3;
вот тут подробности! С математической точки зрения запись С = С + 3 не имеет ни какого смысла. Однако тут нет ничего сложного если смотреть на это под другим углом зрения. Например вот так: b := c + 3; - строка 1 c := b; - строка 2 Тут всё становится гораздо понятней! Однако что нам стоит оптимизировать этот код, ведь значение b := c + 3, не меняется при переходе от строки 1 к строке 2 и мы можем заменить значение b сразу на c + 3, т.е. и написать с := с + 3. При работе такой программы берёться значение с в памяти, к нему прибавляется 3, а после всё это вновь заносится в с. Надеюсь, что понятно!
- -
- вычитание. Анологично сложению: c := с - a + b - 3; Без вопросов!
- *
- умножение
Оно тоже идёт по анологии со сложением но надо помнить приоритет операций! Первый класс: над длинным примером нас заставляли писать приоритеты операций: у сложения 2, у умножения 1 ??? Вот и здесь схожая ситуация! Помните загадку: сколько будет два плюс два умножить на два? Правильный ответ: 6 (т.к. сначала нужно умножать, а потом складывать 2 + 2 * 2)
Вот и в паскале нужно строго соблюдать приоритет операций! В этом вам поможет оператор ( )! Тут как в математике: операции в скобках имеют высший приоритет: т.е. (2 + 2) * 2 = 8 Т.к. сначала мы складываем 2 и 2.
- /
- деление
Вот тут даёт о себе знать то, что паскаль строготипизированный язык: результат деления всегда вещественный! Т.е. не целый :))) И попытка присвоить целому числу результата деления даже двух целых чисел является незаконной! Тут же возникает извечные вопросы: что делать и кто виноват?
Ну виноват, понятное дело, Никлаус Вирт (можете кинуть в него грязью, если найдёте :). А вот на вопросе что делать мы остановимся подробнее: Итак как всегда существуют 2 пути: простой и очень простой :) Простой: В Паскале есть такая функция Round - она возвращает округлёное значение вещественного числа. При этом округление идёт по правилам математики: т.е. Round (1.4) равно 1, а Round (1.6) равно 2. Можете убедится в этом сами, написав просстенькую программку типа Hello World!, только сделать не вывод строки, а вот так: writeLn (Round (1.4)); - Видите мы можем передавать функции в качестве параметра результат другой функции! можете также написать writeLn (Round ( Round (1.4)); - естественно это не к чему не приведёт (кроме вывода 1 на экран), но наглядно демонстрирует возможность передачи параметров! Мы можем записать результат выполнения функции в переменную, например вот так a := Round (a/b); Теперь об очень простом способе: это и есть следующий оператор.
- div
- Деление нацело.
Вот тут уже идет просто отбрасывание дробной части! Т.е. 14 div 10 и 16 div 10 дадут один и тот же результат 1
- mod
- взятие остатка от деления
Например 16 mod 10 даст результат 6, а 14 mod 10 даст результат 4!
Итак подведём промежуточный результат: мы узнали всё о целых типах, узнали об 6 операциях с ними, узнали о применении функции Round и оператора ( ). Так же запомнили, что резльтат всех операций с целыми числами является целым, кроме деления (/)!
Вещественные типы
Имя типа. |
Диапазон значений. |
Число цифр мантиссы. |
Размер памяти. |
Real |
2.9e-39 .. 1.7e+38 |
11 - 12 |
6 байт |
Single |
1.5e-45 .. 3.4e+38 |
7 - 8 |
4 байт |
Double |
5.0e-324 .. 1.7e+308 |
15 - 16 |
8 байт |
Extende |
3.4e-4932 .. 1.1e+4932 |
19 - 20 |
10 байт |
Comp |
-9.2e+18 .. 9.2e + 18 |
19 - 20 |
8 байт |
Числа записываются таким образом: МАНТИССА е ПОРЯДОК.
Возьмём тип Real: 2.9е-39 означает 2.9 * 10-39 Т.е. мантиссу нужно умножать на 10 в степени, равной порядку!
Почему я сразу не стал так писать? Да просто такое представление естественно для языков программирования: напишите программу:
Program Test;
begin
writeLn (1.4)
end.
и вы увидите вот что: 1.4000000000E+00! Нам с вами, как программистам :) всё понятно, но вот как быть с пользователями?
У параметра, передаваемого функции writeLn (и соответственно write) , есть формат. Вы можете указать в какой форме вам нужно вывести вещественное число. Например нам нужно вывести число 1.5432 Вот ваши шаги:
Ваша программа |
То, что выводится на экран |
writeLn (1.54321) |
1.5432100000E+00 |
writeLn (1.54321:1) |
1.5E+00 |
writeLn (1.54321:1:4) |
1.5432 |
writeLn (1.54321:1:6) |
1.543210 |
Формат состоит:
- общее поле выводимой части
- дробная часть (точность)
Общее поле включает знак числа, количество цифр целой части, разделительная точка. Дробная часть - это количествово цифр дробной части.
Если формат отведен больше, чем кол-во позиций, занимаемых числом, то пред целой частью добавляются пробелы, после дробной части - нули.
Ещё один пример: write (1.54321:10:1) выведет на экран такое ____1.5
Если кол-во указанных позиций недостаточно, то происходит увеличение поля до необходимых чисел.
Также вы можете указывать формат целых чисел. Естественно, что мы можем использовать только общее поле.
|
Программа
Сегодня мы рассмотрим целых две программы:
Program Diapasons;
begin
writeLn ('byte: ', Low (byte), ' .. ', High (byte));
writeLn ('word: ', Low (word), ' .. ', High (word));
writeLn ('shortint: ', Low (shortint), ' .. ', High (shortint));
writeLn ('integer: ', Low (integer), ' .. ', High (integer));
writeLn ('longint: ', Low (longint), ' .. ', High (longint))
end.
Результат работы:
byte: 0 .. 255
word: 0 .. 65535
shortint: -128 .. 127
integer: -32768 .. 32767
longint: -2147483648 .. 2147483647 |
Итак тут появилось много всего нового! Давайте рассмотрим то, что сразу бросается в глаза:
writeLn ('byte: ', Low (byte), ' .. ', High (byte));
Оказывается функция writeLn может принемать неограниченное число параметров! Первый параметр это текст 'low: ', второй это результат функции Low... А кстати, что это за функция?
Функция Low (Х) возвращает минимальное значение переменной х. Тот же результат достигается, если задать в качестве параметра имя типа.
Функция High соответсвенно возвращает максимальное значение типа или переменной.
Соответственно мы могли написать:
Program Diapasons;
var
x : byte;
begin
writeLn ('byte: ', Low (x), ' .. ', High (x));
...................
Но прикинте на каждый тип сколько ж это переменных надо ??? (Правильный ответ - всего пять:)))
Ну а теперь наверное самое интересное! Программа подсчета корней квадратного уравнения!
Program Decision_of_quadratic_equalation;
var
a, b, c, D : integer;
x1, x2 : real;
begin
writeLn ('Решение квадратного уравнения: 3*х^2 + 8*x + 5 = 0');
{ Инициализация начальных значений }
a := 3;
b := 8;
c := 5;
{ Вычисление дискриминанта }
D := sqr (b) - 4 * a * c;
{ Вычисление корней }
x1 := (- b - sqrt (D)) / (2 * a);
x2 := (- b + sqrt (D)) / (2 * a);
{ Вывод результата }
writeLn ('Корни уравнения:');
writeLn ('X1 = ', x1 : 8 : 5);
writeLn ('X2 = ', x2 : 8 : 5)
end.
А вот и результат:
Решение квадратного уравнения: 3*х^2 + 8*x + 5 = 0
Корни уравнения:
X1 = -1.66667
X2 = -1.00000 |
Ну вот тут разбирать нужно уже по-больше :)))
Итак что это за строчки выделенные таким цветом??? И почему они на русском ??? Присмотритесь внимательнее... Присмотрелись? Ага!!! Они начинаются и кончаются с кривых скобок { } !! Замечательно! Ваша наблюдательность не имеет границ! :)))
Сразу вас разочарую, программы на русском писать нельзя :)
Это комментарии. Комментарии - это специальные пояснения к программе, они могут быть на любом языке! Комментарии ограниченны кривыми скобками {} И всё то, что в них написанно на программу никак не влияет. Т.е. компилятор просто не читает эти строки. А эти пояснения очень нужны. Однако не стоит забывать закрывать комментарии!! Иначе можно сесть в крупную лужу, т.е. закоментить код, который вам нужен! Кстати есть ещё один способ задания комментариев: {* Это комментарий *}
Вложенность одинаковых комментариев не допускается!!
Это неправильно:
{ Это комментарий
{ Это второй комментарий }
Это всё ещё первый }
Я показал цветом, где реально кончатся комментарий 1!!
Вкладывать можно только комментарии с различными скобками, т.е:
{ Это комментарий
{* Это второй комментарий *}
Это всё ещё первый }
Тут цвет так же всё демонстрирует.
Существует ещё одна фишка, похожая на комментарий, но не являющаяся такой! Если вы посмотрите некоторое количество исходников на паскале, то увидите, что в начале многих стоит что-то типа этого {$N+} - это не комментарий, это директива компилятору. Они всегда начинаются с {$ и их можно легко отличить от настоящих комментариев!
Итак мы объявляем переменные a, b и с - целыми числами. Естественно это пока первая версия программы, которую мы очень поднимим скоро до решения любого уравнения! Ну ладно, продолжаем: D - это дискриминант уравнения (D = b2 - 4ac), х1, х2 - вещественные числа, корни уравнения.
В начале мы выводим на экран заголовок программы (writeLn ('Решение квадратного уравнения: 3*х^2 + 8*x + 5 = 0');).. Потом присваиваим нужные значения коэффициентам a, b и с. После этого вычисляем дискриминант. Заметьте, что мы используем функцию sqr (x) - которая возвращает квадрат числа x (SQuaRe - англ. квадрат). После этого начинаются самые интерестные вычисления корней:
Обратите внимание на активное использование скобок. Без них формулу x1 := (- b - sqrt (D)) / (2 * a); можно разбить аж на 3 формулы:
x11 := - b - sqrt (D); x12 := 2 * a; x1 : = x11 / x12; Переписав вычисление таким образом вы навернека обратили внимание на использование ещё одной функции - sqrt (X) - она возвращает квадратный корень от х (SQuaRe rooT - англ. квадратный корень).
Вообще нужно поакуратнее со скобками. Неправильное их использование может привести к следующему:
- x1 := (-b - sqrt (D)) / 2 * a - тут мы сначала делим на 2, а потом результат деления умножаем на 2
- x1 := -b - sqrt (D) / 2 * a - из -b вычитаем: корень из D, делённый на 2 и умноженный на a
Ну и напоследок, посмотрите, что х1 у нас равен -1.66667... Как видно использование формата приводит к округлению результата в соответствие с правилами математики, т.к. реально х1 = - 10 / 6 = - 1.(6)
|