TURBO PASCAL

Новости           

Программы

Turbo Pascal

Игры

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

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

FAQ

Ссылки

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

Рассылка

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

От автора

 

 

 
Три волшебных слова: if-then-else
Вступление
Теория
Программа
Как научиться читать программы ?
Голосование
Послесловие

Вступление

Вот рассылка обрела новый дизайн. Выразить своё мнение по этому поводу можно в разделе Голосование
Предыдущие выпуски рассылки можно взять  на www.ibp.narod.ru или  этом сайте.(прим. автора сайта)

Теория

В прошлый раз, мы написали программку для подсчёта корней уравнения. Вот её текст:

	 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 : 1 : 5);
		 writeLn ('X2 = ', x2 : 1 : 5)
	end.

Однако у тех, кто знает математику может возникнуть вопрос: А что если дискриминант отрицательный? Да для этого случая он положительный, но в общем ?
Вопрос вполне законен! Итак как же мы можем сравнить дискриминант с нулём?
В Паскале существует так называемый условный оператор. Вот как он выглядит:

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

Давайте разберём его по полочкам или шкафам, у кого как :)
Итак при переводе на русский if - then - else означает если - то - ещё Можно сказать и так:

ЕСЛИ условие ТО
оператор1
В ДРУГОМ СЛУЧАЕ (ещё)
оператор2

Т.е. если условие истинно, то выполняется оператор1, а если ложно, то оператор2. Как же нам узнать истинно условие или нет?

Для этого существуют операторы сравнения:
= Равно. Будем всё смотреть на примерах: А = В
Ложь, если А не равно В.
Истина, если А равно В.

По этому поводу вспоминается анекдот:

- Чем программист отличается от обычного смертного?
- А тем, что в состоянии ответить на вопрос, в котором уже заключен ответ.
- Это как же?
- Ну, например, ответь на вопрос: сколько будет 2х2=4?
В самом деле, сколько будет 2*2=4, если взглянуть на это со стороны Паскаля ?
Итак '=' - это оператор равно. 2х2 равно четырём в математическом смысле. Программа сначала считает выражение слева 2*2 =4, потом справа - там просто 4. Потом сравнивает их. Так как 4 = 4 , то результат оператора РАВНО будет ИСТИНА! Поэтому нельзя путать := и = !!!!!!

По ходу дела познакомимся с ещё одной функцией : ORD (X) - преобразует к целым числам логические выражения и символы. О символах мы поговорим позже. А пока рассмотрим такую програмку:

var
   a : integer;
begin
   a := ord (2*2 = 4);
   wirteLn (a)
end.
Что же выведет на экран такая программа ? Ответ: 1, т.к. результат логического выражения 2*2=4 - это истина, а при переводе логического выражения в целое истина становится 1, а ложь нулём. Если бы мы написали так:
a := ord (2*2 = 5);
, то на экране увидили бы 0.
<> Не равно
А <> В
Ложь, если А равно В
Истина, если А не равно В
Этот оператор как бы обратное равно.
>,< - Больше / Меньше
A > B
Ложь если А меньше или равно В
Истина, если А больше В
A < B
Ложь если А больше или равно В
Истина, если А меньше В
>=, <= - больше или равно / меньше или равно
A >= B
Ложь если А меньше В
Истина, если А больше или равно В
A <= B
Ложь если А больше В
Истина, если А меньше или равно В

Замечательно теперь мы можем проверить дискриминант с 0:

if D < 0 then
выводим сообщение об ошибке
else
считаем корни

Вторая часть (начиная с else) может отсутствовать. Например такой код:

a := 2;
if a > 3 then
    a := a + 3; { Эта строчка никогда не выполняется!}
writeLn (a);

Но немного изменив текст:

a := 2;
if a > 3 then
    a := a + 3 { Эта строчка никогда не выполняется!}
else
    a := 4; { Эта строчка всегда выполняется!}
writeLn (a);

Однако, что делать если нам нужно написать не одну стрчку (a := a + 3), а сразу 5??? Тогда нам нужно выделить эти операции в блок, начало которого отмечается словом begin, а конец end. Т.е. например так:

if D >= 0 then
begin
   { Вычисление корней }
   x1 := (- b - sqrt (D)) / (2 * a);
   x2 := (- b + sqrt (D)) / (2 * a);
   { Вывод результата }
   writeLn ('Корни уравнения:');
   writeLn ('X1 = ', x1 : 1 : 5);
   writeLn ('X2 = ', x2 : 1 : 5)
end
else
begin
   { Корней нет }
   writeLn ('Данное уравнение не имеет корней!');
   writeLn ('Попробуйте ещё!')
end;

Очень часто может потребоваться использовать вложенные операторы условия. Как например понимать такую запись:

if a > 3 then
if b < 3 then
c := 4
else
c := 5;

А теперь внимание вопрос: к какому if относится в данном случае else?? минута пошла :)) Правильный ответ: ко второму!
Или по-русски: else ассоциируется с ближайшим if, которое ещё не связанно со словом else, т.к. при такой конструкции:

if a > 3 then
   if b < 3 then
     c := 4
   else
     c := 5
else
    c := 6;

второй else относится к первому if :)))

Теперь вновь о точках с запятой :((( Это тема довольно-таки запарная:
Оператор if then - else по идее должен заканчиваться ";" но т.к. после else идут операторы, то последняя строчка относящаяся к else должна кончаться ";"
Вот он пример: между if и else ";" быть не должно, ";" ставится после последнего оператора, принадлежащего else:

if условие then
   оператор1 { После оператора1 ";" не нужна ! }
else
   оператор2 ;{ А вот после второго операторы она обязательна }

На сегодня с теорией покончено!

Программа

Ну а сегодня мы сделаем полную програму решения квадратных и заодно линейных уравнений.

Однако сначала - мат.часть. "Даже самая маленькая практика стоит большой теории!" - прочитал в учебнике по физике :)
Итак мы помним, что корни квадратного уравнения можно найти следующим образом:

x1,2 = - b ± (b2 - 4ac)1/2
	2a
Давайте рассмотрим, какие ограничения налагает на нас использование этой формулы:
Ну прежде всего, коэффициент а не должен быть равне 0 (иначе это уже линейное уравнение, его мы рассмотрим ниже)
Дискриминант должен быть положительным (комплексные корни мы пока не рассматриваем)

Если это выполненно, то значит мы можем воспользоваться формулой (*) для вычисления корней.
Теперь рассмотрим случай, когда а = 0, т.е. наше уравнение вырождается в линейное. Тут только одно ограничение: коэффициент b не должен быть равным 0.
Ну и самое простое: если b = 0, то тогда проверим с на совпадения с нулём. Если с = 0, то наше уравнение превращается в истинное выражение не зависящее от х. (0 = 0). Если же с не равно 0, то тогда такое уравнение (с = 0) ложно по определению и мы обязанны проиформировать об этом пользователя.
Долго получилось, но без этого нельзя - надо знать врага в лицо! Чем больше вы знаете о задаче, тем легче её решить! Ну вот и сама программа:

 

Program   Decision_of_quadratic_equalation_Release;

uses   CRT;

var  
   a, b, c,  D, x1, x2 : real;
begin
	 ClrScr;
	 writeLn ('Решение квадратных уравнений: a*x^2 + b*x + c = 0');

	 { Инициализация начальных значений }
	 Write ('Введите коэффициент a: ');
	 ReadLn (a);
	 Write ('Введите коэффициент b: ');
	 ReadLn (b);
	 Write ('Введите коэффициент c: ');
	 ReadLn (c);

	 { Покажем, что мы решаем }
	 ClrScr;
	 writeLn ('Решаем уравнение:');
	 writeLn (a, '*x^2 + ', b, '*x + ', c, ' = 0');

	 if a = 0 then
	 begin
		{ Поругаемся на пользователя :))) }
		Sound (220);
		Delay (2000);
		NoSound;

		writeLn ('Это не квадратное уравнение! (a = 0) ');

		{ Но всё же подсчитаем корни... }
		{ Однако b тоже не может быть равно 0 в этом случае }
		if b = 0 then
		begin

		   { Если с = 0, то 0 = 0 истинно! }
		   if c = 0 then
			 writeLn ('Условие истинно для любых х!')
		   else
			 writeLn ('Условие ложно!')
		end
		else
		begin
		   x1 := - c / b; { Только один корень! }
		   writeLn ('Корень уравнения:');
		   writeLn ('X = ', x1)
		end
	 end
	 else
	 begin

		{ Вычисление дискриминанта }
		D := sqr (b) - 4 * a * c;

		if D < 0 then
		   writeLn ('Рациональных корней  нет! Дискриминант = ', D)
		else
		begin
			{ Вычисление корней }
			x1 := (- b - sqrt (D)) / (2 * a);
			x2 := (- b + sqrt (D)) / (2 * a);

			{ Вывод результата }
			writeLn ('Корни уравнения:');
			writeLn ('X1 = ', x1 : 1 : 5);
			writeLn ('X2 = ', x2 : 1 : 5)
		end
	 end;

	 ReadLn
end.

Оно конечно длинновато, но того стоит!
Итак первое, что бросается в глаза: uses CRT; - Что это такое??

Директива подключения модуля (uses - использовать) - т.е. мы хотим использовать функции модуля CRT - это модуль для создания красивостей программ - цвет, звук, окошки (типа как у BP), экран (в текстовом режиме). Вот я и решил использоать какие-то функции из него и поэтому "сказал" компилятору, что было бы не плохо подключить его, что бы компилятор знал, какие функции там содержатся. Описание функций модуля CRT можно найти следующим образом: Shift+F1 - CRT Unit - появится окошко с общими словами о модуле и ссылками на константы и функции модуля.

Модуль - это отдельный файл с функциями. Например вам не хочется по сто раз в каждой программе писать одну и туже функцию, тогда вы создаёте модуль с этой функцией и просто подключаете его к программе с помощью uses! О том, как делать модули мы поговорим позже.

ClrScr; - вызываем функцию очистки экрана (CLeaR SCReen - очистить экран), что бы не осталось инфы от других программ! Заметьте, что функция не получает параметров и поэтому просто пишется её имя! Эта функция из модуля CRT (!)
ReadLn (a) - эта функция ввода числа а с клавиатуры. Как бы обратная функции writeLn :) При этом внутри её стоит обработчик ошибок - попробуйте вместо числа ввести слово и получите уведомление об ошибке!

{ Поругаемся на пользователя :))) }
Sound (220);
Delay (2000);
NoSound;

Функция Sound (HZ) - заставляет пищать спикер с частотой HZ в герцах. Кстати любопытная информация, которой не содержится в help'e к паскалю, а вычитал я её из help'a по С: Около одной из птицеферм в Австралии был комп, которы издавал звук с частотой 7 Гц. Однако 7 Гц - это резонансная частота черепа цыплёнка и соответственно все цыплята умерли :(( (Вот она - идея звукового оружия) Но не стоит пытаться повторить этот эксперимент: 7 Гц эта частота, кажется называется ультразвуком, не слышима человеком! К тому же там же написанно, что некоторые компьютеры неспособны воспроизводить эту частоту!
Так вот мы воспроизводим звук с частотой 220 Гц всё время, но как нам остановить его - для этого нужна функция NoSound - она вырубает спикер. Спикер будет пищать пока вы не вызовете функцию NoSound !!!

Соответственно нам нужно сделать задержку между вызовами Sound и NoSound. Для этого есть специальный "остановщик" выполнения программ - функция Delay (MilliSeconds) - параметр, как вы догадались указывает на сколько милли секунд нужно остановить выполнения программы, после истечения 2000 мс программа продолжит своё выполнение, однако что бы спикер запищал мы должны послать только один "сигнал", что мы и делаем функцией Sound! Получив сигнал спикер начинает пищать как бы отдельно от программы! Он так и будет пищать до тех пор, пока мы не вызовем функцию NoSound!

Ну и ещё одно в предпоследней строке мы вызываем функцию ReadLn без параметров. Что бы это значило? А значит это, что нам до балды, что введёт пользователь - главное, что бы он нажал ENTER!!!

На этом неизвестные функции закончились.

Отладка - краткий курс молодого отладчика :)
Итак Отладка (дебаг - debug) - поиск ошибок в программе. Сейчас искать ошибки мы не будем. Мы просто посмотрим как выполняется наша программа изнутри!
Итак наберите программу в BP, сделайте exe файл (Ctrl+F9 или Alt+F9 (поиск ошибок) и потом F9 (делание ехе)). Итак тут много конструкций If - else, как узнать какая когда работает?? Очень Просто!

Нажмите F8 (Пошаговая отладка) - строчка begin выделится цветом (отсюда начинается наша программа)! дальше нажимая F8 мы перейдём к строчке ClrScr; т.е. мы сделали один шаг в нашей программе! Проследить, что же было с экраном за время шага можно нажимая Alt+F5 (во время первого шага (begin - ClrScr;) - копирайты борланда, во время второго (ClrScr; - writeLn) - экран очистится, т.е. вызов функции очистки прошёл успешно). Обратите внимание, что дойдя до строчки, где что-то требуется ввести мы увидим рабочий экран программы, т.к. её выполнение приостанавливается на это время. Жмите F8 и вводите числа, пока мы не дойдём до первого if. Если вы ввели а не 0, то вы заметите, что мы сразу проскочим большой кусок программы и перейдём на выполенения условия else, а если а = 0, то else вы не увидите! Когда эта подсветка исчезнет значит программа закончилась! Что бы прервать программу в середине отладки, если вам известен результат, нажмите Ctrl+F2.

Итак это только одна из возможностей Отладчика. Остальные мы изучим после. Однако поэкспериментируйте с различными числами, посмотрите по каким веткам идёт программа.

Как научиться читать программы ?

Читать программы, особенно чужие, это всегда очень сложно. Если вы новичок в этом деле, то вот несколько советов, которые взяты из личного опыта:

  1. Всегда начинайте сначала. Прочитайте коментарии перед программой, если они есть.
  2. Читайте программу последовательно - строка за строкой.
  3. Пытайтесь понять, что делает каждая строка.
  4. Если вы всё таки не поняли, то переходите к следующей строке.

Эта последовательность действий похожа на процесс работы компилятора, только если он не понимает строку, то выдаёт сообщение об ошибке.

Например прочитаем нашу программу из этого выпуска:

Program Decision_of_quadratic_equalation_Release;

Вы можете подумать следующее: "Гм, очевидно это программа! И если не врёт имя, то она решает квадратные уравнения!"

uses CRT;

"Это что-то новое, наверное, раскажут ниже. Пока пропустим"

var
a, b, c, D, x1, x2 : real;

"Ага! Это точно переменные!"

begin
ClrScr;

"Выглядит страннова-то, догадываюсь, что лучше этот кусок пропустить."

.....................

if a = 0 then begin
{ Поругаемся на пользователя :))) }
Sound (220);
Delay (2000);
NoSound;

"Это какие-то технические подробности, в них лучше пока не суваться"

..............

 

end
end
else
begin

"Причудливое сочетание ! Наверное так надо."

{ Вычисление дискриминанта }
D := sqr (b) - 4 * a * c;

"Понятно, дискриминант считается по этой формуле!"

..................

 

end.

"Ну вот уже и конец :( А ведь я только разошёлся... посмотрю ка я ещё разик, те непонятные строчки! "

Если у вас есть принтер, то тексты программ лучше печать - так удобнее их читать. Программу лучше вводить своими руками - так всё быстрее запомнится.

Посмотрите программы из рассылки смотрите сначала целиком, выделяйте непонятные моменты. Потом читайте комментарии и постарайтесь решить все вопросы. Если они всё же остались, то пишите - вам обязательно ответят.

Голосование

Как вы заметили дизайн рассылки несколько изменился. Вот нам и интересно узнать в лучшую или в худшую сторону для вас он изменился. Выразить своё мнение можно здесь.

Послесловие

Вот выпуски и пошли чаще. Надеюсь, что на содержании это не отразится. Если есть вопросы, то пишите - mailto:ibp7@yandex.ru

Следующий выпуск ждите приблизительно во вторник.

 

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

 

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

 

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

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

Hosted by uCoz