TURBO PASCAL

Новости           

Программы

Turbo Pascal

Игры

Документация

"Странности"

FAQ

Ссылки

Гостевая книга

Рассылка

Благодарности

От автора

 

 

 
Типы данных
Вступление
Теория
Программа
Голосование

Вступление

В прошлый раз мы попытались провести голосование по поводу периодичности рассылки. Результаты в разделе Голосование.
После первой программы наверняка хочется сделать чего-нибудь покруче. Сегодня мы напишем ещё парочку программ.

Теория

Все программы работают с данными. Например целые числа, вещественные числа, строки - это данные. Данные могут быть постоянными, например дата рождения, а могут быть и переменными : например возраст.

Итак давайте представим следующую задачу: необходимо решить уравнение вида 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 .. 128 1 байт
Integer - 32768 .. 32768 2 байтa
Long - 2147483648 .. 2147483648 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
Формат состоит:

  1. общее поле выводимой части
  2. дробная часть (точность)
Общее поле включает знак числа, количество цифр целой части, разделительная точка. Дробная часть - это количествово цифр дробной части.
Если формат отведен больше, чем кол-во позиций, занимаемых числом, то пред целой частью добавляются пробелы, после дробной части - нули.
Ещё один пример: 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)

Голосование

Результаты голосования можно посмотреть (и ещё пока даже проголосовать) можно здесь.

Результаты несколько ошарашили. Большинство требует ежедневных выпусков рассылки. Возможно такое и получится, но только не на этой неделе. На этой неделе выйдет ещё один выпуск - #5 посвященный оператору выбора.

 

Если, что надо - мыльте ibp7@yandex.ru.
© 2002 Использование материалов без согласия авторов запрещено.

 

На первую страницу

 

Rambler's Top100 PROext: Top 1000 Rambler's Top100
(с)Все права защищены

По всем интересующим вопросам прошу писать на электронный адрес

Hosted by uCoz