Добавил справку и средства для автогенерации справки по системному модулю

This commit is contained in:
miks1965 2018-08-02 22:04:49 +03:00
parent 753759b888
commit ca51bafdcd
633 changed files with 71636 additions and 14 deletions

3
.gitignore vendored
View file

@ -11,6 +11,9 @@ bin/*.xml
bin/log.txt
bin/CompilerController.ini
**/_vti_cnf
**/_vti_pvt
TestSuite/CompilationSamples/*.pcu
TestSuite/CompilationSamples/*.pdb
TestSuite/CompilationSamples/*.exe

View file

@ -0,0 +1,50 @@
uses System.Collections.Generic;
var
mnem,f,f1: text;
d := new Dictionary<string,char>;
c: char;
s: string;
function Convert(s: string): string;
begin
foreach x: KeyValuePair<string,char> in d do
begin
var p := Pos(x.Key,s);
while p>0 do
begin
Delete(s,p,Length(x.Key));
Insert(x.Value,s,p);
p := Pos(x.Key,s);
end;
end;
Result := s;
end;
begin
assign(mnem,'mnemonicsrus.txt');
reset(mnem);
for c:='а' to 'я' do
begin
readln(mnem,s);
d.Add(Trim(s),c);
end;
for c:='А' to 'Я' do
begin
readln(mnem,s);
d.Add(Trim(s),c);
end;
close(mnem);
assign(f,'Table of Contents.hhc');
assign(f1,'Table of Contents New.hhc');
reset(f);
rewrite(f1);
while not eof(f) do
begin
readln(f,s);
s := Convert(s);
writeln(f1,s);
end;
close(f);
close(f1);
end.

View file

@ -0,0 +1,54 @@
var dict := new Dictionary<string,string>;
procedure CollectInDir(path: string);
begin
var ff := System.IO.Directory.EnumerateFiles(path,'*.html');
foreach f: string in ff do
begin
var l := new List<string>;
ReadLines(f).ForEach(
procedure(s) ->
begin
if s.Contains('name="Keyword"') then
begin
var p := s.IndexOf('value="');
var q := s.IndexOf('"',p+8);
l.Add(Copy(s,p+8,q-p-7));
end;
end);
if l.Count>0 then
begin
dict[f.Substring(2)] := l.JoinIntoString('`\')+'`\';
end;
end;
var dd := System.IO.Directory.EnumerateDirectories(path);
foreach d: string in dd do
CollectInDir(d);
end;
begin
CollectInDir('.');
//dict.Println(NewLine);
var f := ReadLines('WinChmWebHelp\Table of Contents.wcp',Encoding.UTF8);
var name := '';
f := f.Select(s->begin
if s.StartsWith('TitleList.Url') then
begin
var p := s.IndexOf('=');
name := s.Substring(p+1);
end;
if s.StartsWith('TitleList.Keywords') then
begin
var p := s.IndexOf('=');
if dict.ContainsKey(name) then
begin
s := s.Substring(0,p+1)+dict[name];
end;
end;
Result := s;
end);
WriteLines('WinChmWebHelp\Table of Contents.wcp',f.ToArray,new System.Text.UTF8Encoding(false));
end.

View file

@ -0,0 +1,92 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title></title>
<link rel="StyleSheet" href="../default.css">
</head>
<body>
<h1>Преимущества PascalABC.NET</h1>
<h2>Современный язык программирования Object Pascal</h2>
<p>Язык <b>PascalABC.NET</b> включает в себя практически весь стандартный язык
Паскаль, а также большинство языковых расширений языка Delphi. Однако, этих
средств недостаточно для современного программирования. Именно поэтому <b>PascalABC.NET</b>
расширен рядом конструкций, а его стандартный модуль - рядом подпрограмм, типов
и классов, что позволяет создавать легко читающиеся приложения средней
сложности. </p>
<p>Кроме этого, язык <b>PascalABC.NET</b> использует большинство средств,
предоставляемых платформой .NET: единая система типов, классы, интерфейсы,
исключения, делегаты, перегрузка операций, обобщенные типы (generics), методы
расширения, лямбда-выражения.</p>
<p>Стандартный модуль PABCSystem, автоматически подключаемый к любой программе,
содержит огромное количество стандартных типов и подпрограмм, позволяющих писать
ясные и компактные программы. </p>
<p>В распоряжении <b>PascalABC.NET</b> находятся все средства .NET-библиотек
классов, постоянно расширяющихся самыми современными возможностями. Это
позволяет легко писать на <b>PascalABC.NET</b> приложения для работы с сетью,
Web, XML-документами, использовать регулярные выражения и многое другое.&nbsp;</p>
<p>Язык <b>PascalABC.NET</b> позволяет программировать в классическом <em>
процедурном стиле</em>, в <em>объектно-ориентированном стиле</em> и содержит
множество элементов для программирования в <em>функциональном стиле</em>. Выбор
стиля или комбинации этих стилей - дело вкуса программиста, а при использовании
в обучении - методический подход преподавателя.</p>
<p>Сочетание богатых и современных языковых средств, возможностей выбора разных
траекторий обучения позволяет рекомендовать <strong>PascalABC.NET</strong> с
одной стороны как язык для обучения программированию (от школьников до студентов
младших и средних курсов), с другой - как язык для создания проектов и библиотек
средней сложности.</p>
<h2>Простая и мощная среда разработки</h2>
<p>Интегрированная среда разработки <strong>PascalABC.NET</strong> ориентирована
на создание проектов малой и средней сложности. Она достаточно легковесна и в то
же время обеспечивает разработчика всеми необходимыми средствами, такими как
встроенный отладчик, средства Intellisense (подсказка по точке, подсказка по
параметрам, всплывающая подсказка по имени), переход к определению и реализации
подпрограммы, шаблоны кода, автоформатирование кода. </p>
<p>В среду <strong>PascalABC.NET</strong> встроен также <em>дизайнер форм</em>,
позволяющий создавать полноценные оконные приложения в стиле RAD (Rapid
Application Development - быстрое создание приложений).</p>
<p>В отличие от многих профессиональных сред, среда разработки <strong>
PascalABC.NET</strong> не имеет громоздкого интерфейса и не создает множество
дополнительных вспомогательных файлов на диске при компиляции программы. Для
небольших программ это позволяет соблюсти принцип &quot;Одна программа - один файл на
диске&quot;.</p>
<p>В среде <b>PascalABC.NET</b>
большое внимание уделено связи запущенной программы с оболочкой: консольная
программа, запущенная из-под оболочки, осуществляет ввод-вывод в специальное
окно, встроенное в оболочку. Можно также запустить несколько программ
одновременно - все они будут контролироваться оболочкой.</p>
<p>Интегрированная среда <b>PascalABC.NET</b>
позволяет переключать в настройках русский и английский язык, при этом
локализованы не только элементы интерфейса, но и сообщения об ошибках.</p>
<p>Кроме этого, внутренние представления <strong>PascalABC.NET</strong> позволяют создавать
компиляторы других языков программирования и встраивать их в среду разработки с помощью
специальных
<a href="http://pascalabc.net/wiki/index.php/Плагины_для_PascalABC.NET">плагинов</a>.</p>
<h2>Специализированные модули для обучения</h2>
<p>Платформа Microsoft.NET обеспечивает <strong>PascalABC.NET</strong>
стандартной библиотекой, состоящей из огромного количества класссов для решения
практически любых задач: от алгоритмических до прикладных. Именно поэтому в
<strong>PascalABC.NET</strong> отсутствует необходимость в разработке большого
числа собственных модулей.</p>
<p>Собственные модули, которые имеются в <strong>PascalABC.NET</strong>,
ориентированы именно на начальное обучение программированию. </p>
<p>Для обучения программированию школьников реализованы модули классических
школьных исполнителей Робот и Чертежник, содержащие около двухсот автоматически
проверяемых заданий на основные конструкции языка программирования.</p>
<p>Кроме этого, среда <b>PascalABC.NET</b>
содержит модуль электронного задачника <a href="http://ptaskbook.com">Programming
Taskbook</a> (автор Абрамян М.Э.), позволяющий осуществлять
автоматическую постановку и проверку заданий. Имеются также модули для преподавателя, позволяющие создавать
задания для исполнителей Робот, Чертежник и электронного задачника.</p>
<p>Модуль растровой графики GraphABC и модуль векторных графических объектов
ABCObjects могут быть использованы для создания простейших графических. а также
интерактивных анимационных приложений, управляемых событиями.</p>
<p>Следует также отметить &quot;студенческие&quot; модули: модуль <span lang="en-us">Collections
</span>упрощенных коллекций, модуль <span lang="en-us">Arrays </span>для
простейших операций с динамическими массивами и модуль Forms для ручного
создания простых приложений с оконным пользовательским интерфейсом.</p>
<p>&nbsp;</p>
</body>
</html>

124
PABCNetHelp/Common/Net.html Normal file
View file

@ -0,0 +1,124 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title></title>
<link rel="StyleSheet" href="../default.css">
</head>
<body>
<h1>Что такое .NET</h1>
<p>Платформа <b>Microsoft .NET</b> - это комплекс
программ, устанавливаемый поверх операционной системы и обеспечивающий
выполнение программ, написанных специально для .NET.
.NET-программы компактны, пользуются единым набором типов
данных и библиотек. Компания Microsoft активно развивает платформу
.NET, выпуская новые версии с расширенными
возможностями. На момент начала 2015 г. последней версией является
.NET 4.5.</p>
<p>В результате компиляции .NET-программы генерируется не машинный код, а
так называемый байт-код, содержащий команды <i>виртуальной машины </i>
.NET он называется <b>IL-кодом</b>
от англ. Intermediate Language - промежуточный язык). Команды байт-кода не зависят
от процессора и используемой операционной системы. При запуске
программа, содержащая IL-код,
подается на вход виртуальной машины, которая и производит выполнение программы.
Часть виртуальной машины, называемая <b>JIT-</b><b>компилятором</b>
(Just In Time - непосредственно в данный момент),
сразу после запуска .NET-программы переводит
ее промежуточный код в машинный (проводя при этом его
оптимизацию), после чего запускает программу
на исполнение. Если быть точными, то промежуточный код переводится в машинный
частями по мере выполнения программы.</p>
<p>Такой способ двойной компиляции сложнее обычного, но имеет
ряд преимуществ. Во-первых, JIT-компилятор может
определить тип процессора, установленного на данном компьютере, поэтому
генерирует максимально эффективный машинный код. Тесты показывают, что за счет
этого некоторые программы выполняются даже быстрее обычных. Во-вторых,
IL-код - гораздо более высокоуровневый, чем машинный, и содержит
ряд объектно-ориентированных команд. В их числе - команда newobj
вызова конструктора объекта, команда callvirt
вызова виртуального метода объекта и команда throw генерации исключения.</p>
<p>Программа или библиотека для .NET
называется <i>сборкой</i> и имеет традиционное расширение - exe
или dll. Поскольку в сборках содержится IL-код,
они значительно компактнее обычных программ и библиотек. Так, приложение с
главным окном, меню и элементами управления занимает на диске всего несколько
десятков килобайт.</p>
<p>Наиболее &quot;чистым&quot; .NET-языком является
<b>C#</b>: он создавался специально для платформы .NET
и включает практически все ее возможности. .NET-языки легко взаимодействуют друг с другом не только за
счет высокоуровневого промежуточного кода, но и за счет общей системы типов (<b>CTS</b>
- Common Type System - общая система типов). Все стандартные
типы (строковые, символьные, числовые и логический) имеют одинаковое
представление в памяти во всех .NET-языках. Это
позволяет, например, создать библиотеку dll
на C#, <span lang="ru">поместить в нее описание класса, </span>а затем воспользоваться этой
библиотекой из программы на PascalABC.NET, <span lang="ru">сконструировав</span> объект
<span lang="ru">данного</span> класса. Можно также разработать библиотеку на PascalABC.NET,
а потом подключить ее к проекту на Visual Basic.NET.
Отметим, что традиционные
библиотеки dll не позволяют хранить классы, доступные
извне, и обладают рядом других ограничений.</p>
<p>Важнейшими средствами, предоставляемыми платформой
.NET, являются единый способ обработки ошибок - генерация и
перехват исключений, - а также автоматическое управление освобождением
динамической памяти, называемое <i>сборкой мусора</i>. Последнее, в частности,
означает, что отсутствует необходимость в деструкторах классов.</p>
<p>Имеются программы,
которые могут восстанавливать текст программы по IL-коду
(например, программа <span lang="en-us">ILSpy</span>).</p>
<p>Помимо JIT-компилятора, важной частью
платформы .NET является набор стандартных библиотек (FCL
- Foundation Class Library - общая библиотека классов).
Среди них - библиотеки работы с графикой, сетью, базами данных, XML,
контейнерами, потоками, содержащие тысячи классов. Каждый .NET-язык
может пользоваться всеми возможностями этих библиотек.</p>
<p>Имеется открытая кроссплатформенная реализация среды <span lang="en-us">
Microsoft.NET - </span><a href="http://www.mono-project.com/">среда
<span lang="en-us">Mono</span></a>, позволяющая в частности разрабатывать и
запускать <span lang="en-us">.NET-</span>программы под <span lang="en-us">Linux</span>.</p>
<p>Кратко отметим достоинства и недостатки платформы .NET.</p>
<h2>Достоинства платформы .NET</h2>
<ol>
<li>Платформа .NET поддерживает множество
.NET-языков. В их числе C#,
Visual Basic.NET, <span lang="en-us">F</span>#,
управляемый C++,
<span lang="en-us">Delphi Prism</span>, Oberon, Zonnon,
&nbsp;<span lang="en-us">Iron Python, Iron Ruby, </span>PascalABC.NET.</li>
<li>Любой .NET-язык содержит самые современные
языковые возможности: классы, свойства, полиморфизм, исключения, перегрузка
операций, легкое создание библиотек.</li>
<li>.NET-языки легко сочетаются друг с другом,
похожи друг на друга по синтаксическим конструкциям и системе типов.</li>
<li>Имеется обширная библиотека стандартных классов FCL.</li>
<li>.NET-приложения компактны.</li>
<li>Платформа .NET активно развивается фирмой
Microsoft, добавляются как новые языковые возможности,
так и новые библиотеки.</li>
<li>Компилятор .NET-языка создать значительно проще,
чем компилятор обычного языка.</li>
</ol>
<h2>Недостатки платформы .NET</h2>
<ol>
<li>Запуск .NET-приложения выполняется в несколько раз
медленнее запуска обычного приложения, поскольку требует загрузки в
оперативную память компонентов виртуальной машины и внешних библиотек.</li>
<li>.NET-код в некоторых ситуациях работает медленнее
обычного (однако, в большинстве задач это отставание незначительно, а в
некоторых - приложения .NET могут опережать
обычные программы).</li>
<li>Сборщик мусора начинает работу в момент
исчерпания динамической памяти, его работа занимает несколько миллисекунд. Для
приложений реального времени это непозволительно.</li>
<li>Запуск .NET-приложения обязательно требует
установки на компьютере платформы .NET. Без нее
приложение работать не будет (Отметим, что в Windows Vista и в
<span lang="en-us">Windows 7 </span>платформа .NET встроена).</li>
</ol>
<p>Отметим, что достоинства платформы .NET
многократно перекрывают ее недостатки.</p>
</body>
</html>

View file

@ -0,0 +1,109 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title></title>
<link rel="StyleSheet" href="../default.css">
</head>
<body>
<H1>Îòëè÷èÿ ÿçûêà PascalABC.NET îò Delphi</H1>
<h3>Äîáàâëåíî</h3>
<ol>
<li>Îïåðàöèè <code>+=</code> <code>-=</code> äëÿ ñîáûòèé .NET è äëÿ ïðîöåäóðíûõ
ïåðåìåííûõ.</li>
<li>Îïåðàöèè <code>+=</code> <code>-=</code> <code>*=</code> äëÿ öåëûõ è&nbsp;
<code>+=</code> <code>-=</code> <code>*=</code> <code>/=</code>
äëÿ âåùåñòâåííûõ.</li>
<li>Îïåðàöèÿ <code>+=</code> äëÿ ñòðîê.</li>
<li>Ïîäïðîãðàììû ñ ïåðåìåííûì ÷èñëîì ïàðàìåòðîâ.</li>
<li>Îïåðàöèÿ <b> <code>new</code></b> äëÿ âûçîâà êîíñòðóêòîðà (<code>ident := new type_name(params);</code>).</li>
<li>Îïåðàöèÿ <b> <code>new</code></b> äëÿ ñîçäàíèÿ äèíàìè÷åñêîãî ìàññèâà. </li>
<li>Îïåðàöèÿ <code><b>typeof</b></code> .</li>
<li>Èñïîëüçîâàíèå <code><b>uses</b></code> äëÿ
ïîäêëþ÷åíèÿ ïðîñòðàíñòâ èìåí .NET (<span lang="ru">ðåàëèçîâàíî â </span>
Delphi Prism).</li>
<li>Âèä äîñòóïà <code><b>internal</b></code> (íàðÿäó ñ <code><b>public</b></code>,
<code><b>private</b></code>, <code><b>protected</b></code>).</li>
<li>Èíèöèàëèçàöèÿ ïåðåìåííûõ: <code><b>var</b> a: integer :=
1</code>;</li>
<li>Èíèöèàëèçàöèÿ ïåðåìåííûõ: <code><b>var</b> a :=
1</code>;</li>
<li>Îáúÿâëåíèå ëîêàëüíûõ ïåðåìåííûõ â áëîêå.</li>
<li>Îáúÿâëåíèå ïàðàìåòðà öèêëà â çàãîëîâêå öèêëà: <code><b>for</b> <b>var</b>
i := 1 <b>to</b> 10 <b>do</b></code>, <code><b>foreach</b>
<strong>var</strong> x <b>in</b> a <b>do</b></code>.</li>
<li>Îïåðàòîð <code><b>lock</b></code>, îáåñïå÷èâàþùèé ñèíõðîíèçàöèþ ïîòîêîâ.</li>
<li>Ìåòîäû â çàïèñÿõ.</li>
<li>Èíèöèàëèçàòîðû ïîëåé â êëàññàõ è çàïèñÿõ.</li>
<li>Îáîáùåííûå êëàññû (generics).</li>
<li>Ðåàëèçîâàíû òèïèçèðîâàííûå ôàéëû (â îòëè÷èå îò
Delphi Prism, ãäå îíè óáðàíû).</li>
<li>Óïðîùåííûé ñèíòàêñèñ ìîäóëåé.</li>
<li>Îïèñàíèå ìåòîäîâ âíóòðè èíòåðôåéñà êëàññà èëè çàïèñè.</li>
<li>Ðåàëèçàöèÿ çàïèñüþ èíòåðôåéñà.</li>
<li><span lang="ru">Ìåòîäû ðàñøèðåíèÿ.</span></li>
<li>Ëÿìáäà-âûðàæåíèÿ.</li>
</ol>
<h3>Èçìåíåíî</h3>
<ol>
<li>Òîëüêî ñîêðàùåííîå âû÷èñëåíèå ëîãè÷åñêèõ âûðàæåíèé.</li>
<li>Äðóãîé ñèíòàêñèñ <code><b>foreach</b></code>.</li>
<li>Èíòåðôåéñû <code><b>interface</b></code> â ñòèëå .NET.</li>
<li>Äðóãîé ñèíòàêñèñ ïåðåãðóçêè îïåðàöèé.</li>
<li>Ñòàòè÷åñêèå ìåòîäû êëàññîâ âìåñòî êëàññîâûõ ìåòîäîâ. Îòñóòñòâèå òèïà
<code>TClass</code>.</li>
<li>Äåñòðóêòîðû îñòàâëåíû ëèøü äëÿ ñîâìåñòèìîñòè è íå âûïîëíÿþò íèêàêèõ
äåéñòâèé.</li>
<li>Òèï <code>object</code> -
ñèíîíèì <code>System.Object</code>.</li>
<li>Òèï <code>exception</code> -
ñèíîíèì <code>System.Exception</code>.</li>
<li>Èíäåêñàöèÿ <code>string</code> ñ 1, äèðåêòèâà ïåðåêëþ÷åíèÿ íà èíäåêñàöèþ ñ 0.</li>
<li>Ïðîöåäóðà <code>write</code>
âûâîäèò ëþáûå òèïû.</li>
<li>Ñòðóêòóðíàÿ ýêâèâàëåíòíîñòü òèïîâ äëÿ ïðîöåäóðíûõ ïåðåìåííûõ, äèíàìè÷åñêèõ ìàññèâîâ,
òèïèçèðîâàííûõ óêàçàòåëåé è
ìíîæåñòâ (â Delphi Object
Pascal - èìåííàÿ ýêâèâàëåíòíîñòü òèïîâ çà èñêëþ÷åíèåì îòêðûòûõ
ìàññèâîâ).</li>
<li>Ìíîæåñòâà íà áàçå ïðîèçâîëüíûõ òèïîâ (<code><b>set</b> <b>of</b>
string</code>).</li>
<li>Çàïðåò èñïîëüçîâàíèÿ óêàçàòåëåé íà óïðàâëÿåìóþ ïàìÿòü.</li>
<li>Ïðîöåäóðíûå ïåðåìåííûå (äåëåãàòû) âìåñòî <code><b>procedure of</b>
object</code>.</li>
<li>Ñ áåñòèïîâûìè ôàéëàìè <b><code>file</code></b>
ìîæíî ðàáîòàòü ñ ïîìîùüþ ïðîöåäóð <code>read</code>,
<code>write</code>.</li>
<li>Ìàññèâû ìàññèâîâ îòëè÷àþòñÿ ïî òèïó îò äâóìåðíûõ ìàññèâîâ (â ÷àñòíîñòè,
çàïèñè <code>a[i][j]</code> è <code>a[i,j]</code> íåýêâèâàëåíòíû).</li>
<li>Ïåðåãðóçêà âûïîëíÿåòñÿ áåç êëþ÷åâîãî ñëîâà <b> <code>overload</code></b>.</li>
<li>Âñå êîíñòðóêòîðû èìåþò èìÿ <code>Create</code>.</li>
<li>Àâòîìàòè÷åñêîå óïðàâëåíèå ïàìÿòüþ ñ ïîìîùüþ ñáîðùèêà ìóñîðà (çà
èñêëþ÷åíèåì óêàçàòåëåé íà íåóïðàâëÿåìóþ ïàìÿòü).</li>
</ol>
<h3>Îòñóòñòâóåò</h3>
<ol>
<li>Êëþ÷åâûå ñëîâà è äèðåêòèâû <code><b>packed threadvar inline asm exports library unsafe resourcestring dispinterface in out absolute dynamic
local platform requires abstract export message resident assembler safecall
automated far near stdcall cdecl published stored contains implements
varargs default deprecated package register dispid pascal writeonly</b></code>
è ñâÿçàííûå ñ íèìè âîçìîæíîñòè.</li>
<li>Ïðèâåäåíèå òèïîâ äëÿ ïåðåìåííûõ: <code>Char(b)</code>
<code>:=</code> <code>'d'</code>.</li>
<li>Âîçìîæíîñòü ïðèñâîèòü àäðåñ ïîäïðîãðàììû óêàçàòåëþ <code>pointer</code>.</li>
<li>Çàïèñè ñ âàðèàíòàìè.</li>
<li>Ñòðîêè <code>PChar</code>.</li>
<li>Âîçìîæíîñòü èñïîëüçîâàòü îïåðàöèþ <code>@</code> äëÿ ïðîöåäóðíûõ ïåðåìåííûõ.</li>
<li>Âàðèàíòíûå òèïû.</li>
<li>Áåñòèïîâûå ïàðàìåòðû (<code><b>var</b> a; <b>
const</b> b</code>).</li>
<li>Îòêðûòûå ìàññèâû (íå ïóòàòü ñ äèíàìè÷åñêèìè!).</li>
<li>Ìåòîäû, ñâÿçàííûå ñ ñîîáùåíèÿìè (<code><b>message</b></code>).</li>
<li>Êëàññîâûå ñâîéñòâà.</li>
<li>Âëîæåííûå îïðåäåëåíèÿ êëàññîâ.</li>
<li>Êîíñòàíòû-ïîëÿ êëàññîâ.</li>
</ol>
</body>
</html>

View file

@ -0,0 +1,283 @@
<html>
<head>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
</object>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title></title>
<link rel="StyleSheet" href="../default.css">
</head>
<body>
<OBJECT id=exam type="application/x-oleobject" classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11" style="position:absolute; top:-100; left:-100;">
<param name="Command" value="TCard">
<param name="Text" value="">
</OBJECT>
<H1>Коротко о главном</H1>
<p>Данный текст содержит краткий <b>обзор </b>
<b>особенностей</b> PascalABC.NET. </p>
<ul>
<li>PascalABC.NET легковесная и мощная среда разработки программ с
подробной справочной системой, средствами подсказки по коду,
автоформатированием, встроенным отладчиком и встроенным дизайнером форм.
Интегрированная среда разработки PascalABC.NET ориентирована на создание
проектов малой и средней сложности, а также на обучение современному
программированию. </li>
<li>PascalABC.NET мощный и современный язык
программирования. По предоставляемым возможностям он превосходит язык Delphi
и содержит практически все возможности языка C#.</li>
<li>PascalABC.NET опирается на платформу Microsoft .NET - её языковые
возможности и библиотеки, что делает его гибким, эффективным, постоянно
развивающимся. Кроме того, можно легко сочетать <span lang="ru">библиотеки</span>, разработанные на PascalABC.NET
и других .NET-языках.</li>
<li>Компилятор PascalABC.NET генерирует код, выполняющийся так же быстро,
как и код на C#, и несколько медленнее, чем код на
C++ и Delphi.</li>
<li>PascalABC.NET является представителем линейки современных языков Паскаль
вместе с Delphi XE и Oxygene.</li>
<li>Мнение, что язык Паскаль устарел и утрачивает свои
позиции, основано на представлении о старом Паскале и старых средах
программирования (например, <span lang="en-us">Free Pascal </span>с его
несовременной консольной оболочкой и языком <span lang="en-us">Delphi </span>
образца 2002 года). К сожалению, масса отечественной учебной литературы
<span lang="ru">с упорством,
достойным лучшего применения, </span>ориентируется на <span lang="ru">отживший
</span>Turbo Pascal<span lang="ru"> с древней
консольной оболочкой, бедной графической библиотекой и устаревшими
средствами объектно-ориентированного программирования, развивая у
обучающихся стойкое отвращение к языку Паскаль вообще.</span></li>
<li>PascalABC.NET расширен современными языковыми
возможностями для легкого, компактного и понятного програмирования.</li>
<li>PascalABC.NET достаточно зрелая среда. Ее прототип учебная система
Pascal ABC появилась в 2002 году. PascalABC.NET развивающаяся среда. Ведутся разработки новых языковых возможностей, новых библиотек.</li>
</ul>
<p>Далее приводится <b>ряд программ с короткими комментариями</b>, раскрывающих
возможности и особенности языка PascalABC.NET.&nbsp; </p>
<p>Тексты программ располагаются в рабочей папке (по умолчанию
C:\PABCWork.NET) в подпапке Samples\!MainFeatures.</p>
<p>Для запуска программ данное окно должно быть открыто через
пункт меню &quot;Помощь/Коротко о главном&quot; так, чтобы оно не
полностью закрывало окно оболочки <b>PascalABC.NET</b>.</p>
<p><b>Основное</b></p>
<ol>
<li><a href="JavaScript:exam.TCard(201,0)"><b>AssignExt.pas.</b></a> Данный
пример иллюстрирует использование расширенных операторов присваивания += -=
*= /= для целых и вещественных. Оператор /= для целых, разумеется,
запрещен. </li>
<li><a href="JavaScript:exam.TCard(202,0)"><b>BlockVar.pas.</b></a> Переменные могут описываться внутри блока
begin-end
и инициализироваться при описании. Это крайне удобно для промежуточных
переменных, а в PascalABC.NET в силу особенностей
реализации еще и ускоряет доступ к переменным процентов на 30.</li>
<li><a href="JavaScript:exam.TCard(203,0)"><b>AutoVars.pas.</b></a> Если переменная инициализируется при описании, то ее тип
можно не указывать: он определяется по типу правой части (автоопределение типа). Переменную - параметр цикла for
можно описывать прямо в заголовке цикла, сочетая это с автоопределением типа.</li>
<li><b><a href="JavaScript:exam.TCard(204,0)">SimpleNewFeatures.pas</a>.</b> Пример, объединяющий
возможности из предыдущих трех примеров.</li>
<li><b><a href="JavaScript:exam.TCard(205,0)">WriteAll.pas</a>.</b> Процедура write
выводит любой тип.
В частности, она выводит все элементы множества. Если тип ей неизвестен, то она
выводит имя типа. </li>
<li><b><a href="JavaScript:exam.TCard(206,0)">WriteFormat.pas</a>.</b> Стандартная процедура WriteFormat
позволяет осуществлять форматированный вывод. Вид форматной строки заимствуется
из .NET.</li>
<li><b><a href="JavaScript:exam.TCard(207,0)">StandardTypes.pas</a>.</b> В этой программе приведены все стандартные целые и
вещественные типы. Программа выводит их размеры.</li>
<li><b><a href="JavaScript:exam.TCard(208,0)">RandomDiap.pas</a>.</b> К функциям генерации случайных чисел добавилась
Random(a,b), возвращающая случайное целое в диапазоне
[a,b].
Процедуру Randomize в начале программы вызывать не надо.</li>
<li><b><a href="JavaScript:exam.TCard(209,0)">RealExtNums.pas</a>.</b> Действия с вещественными значениями не могут в .NET
привести к переполнению. При некорректных операциях (деление на 0,
переполнение или взятие логарифма отрицательного числа) мы получим либо
значение &quot;бесконечность&quot;, либо значение &quot;NaN&quot; (не число).</li>
<li><b><a href="JavaScript:exam.TCard(210,0)">Foreach.pas</a>.</b> Оператор
foreach предназначен для цикла по
контейнерам, таким как массивы, множества и контейнеры стандартной
библиотеки (например, List&lt;T&gt;). Элементы контейнера
доступны только на чтение.</li>
<li><b><a href="JavaScript:exam.TCard(211,0)">Amp.pas</a>.</b> Ключевые слова могут использоваться в качестве имен, в
этом случае перед ними следует ставить значок &amp;
снятия атрибута ключевого слова. Кроме того, ключевые слова могут
использоваться в качестве полей. Например, &amp;Type
или System.Type.</li>
</ol>
<p><b>Типы</b></p>
<ol start=12>
<li><b><a href="JavaScript:exam.TCard(212,0)">CharFunc.pas</a>.</b> Символы Char хранят Unicode и поэтому занимают 2 байта. Для функций Ord и Chr оставлено, тем
не менее, прежнее действие (предполагается, что символы находятся в
Windows-кодировке). Для
работы с кодами Unicode
следует использовать OrdUnicode и
ChrUnicode.</li>
<li><b><a href="JavaScript:exam.TCard(213,0)">StringTypes.pas</a>.</b> Строки string
занимают память переменной длины и проецируются на .NET-тип System.String. Однако, в отличие от
NET-строк они изменяемы и индексируются с 1. Для
работы со строками фиксированной длины следует использовать тип
string[n] или shortstring=string[255].
В частности, типизированные файлы допустимы только для коротких строк.</li>
<li><b><a href="JavaScript:exam.TCard(214,0)">StringMethods.pas</a>.</b> Строки string имеют ряд
методов как .NET-классы. В этих методах
предполагается, что строки индексируются с нуля. </li>
<li><b><a href="JavaScript:exam.TCard(215,0)">StringInteger.pas</a>.</b> Все типы - классы. Простые типы тоже. Поэтому преобразование строки в целое и вещественное
проще выполнять с помощью статических методов
Parse соответствующего класса (например,
integer.Parse(s)). Преобразование целого или вещественного в строку
удобнее выполнять с помощью экземплярного метода ToString
(например, r.ToString). </li>
<li><b><a href="JavaScript:exam.TCard(216,0)">Enum.pas</a>.</b> Перечислимый тип позволяет обращаться к его константам
не только непосредственно, но и используя запись вида ИмяТипа.ИмяКонстанты.
Нелишне отметить, что все перечислимые типы - производные от System.Enum.</li>
<li><b><a href="JavaScript:exam.TCard(217,0)">Sets.pas</a>.</b> Множества могут иметь произвольный базовый тип. Внутри
множество хранится как хеш-таблица, однако при выводе множества в процедуре
write его элементы упорядочиваются.</li>
<li><b><a href="JavaScript:exam.TCard(218,0)">DynArray.pas</a>.</b> Динамические массивы array of
T представляют собой ссылки. Память под них должна выделяться либо
вызовом стандартной процедуры
SetLength, либо использованием инициализатора вида
new T[n]. Процедура SetLength
сохраняет старое содержимое массива. Динамические массивы являются классом, производным от
класса System.Array, имеющего достаточно
богатый интерфейс. Следует упомянуть прежде всего статические методы
&amp;Array.Sort и &amp;Array.Resize.</li>
<li><b><a href="JavaScript:exam.TCard(219,0)">InitRecords.pas</a>.</b> В записях допустимы инициализаторы полей.
Поля записи инициализируются при создании переменной-записи.</li>
<li><b><a href="JavaScript:exam.TCard(220,0)">UntypedFile.pas</a>.</b> Бестиповые файлы file изменены по сравнению с Delphi.
Отсутствуют процедуры BlockRead и
BlockWrite, но в бестиповой файл можно
непосредственно записывать данные разных типов. Лишь бы считывание
производилось в том же порядке.</li>
<li><b><a href="JavaScript:exam.TCard(221,0)">PointerToRef.pas</a>.</b> Имеют место некоторые ограничения для указателей на управляемую память.
Так, указатель не может прямо или косвенно указывать на объект класса,
память для которого выделена вызовом конструктора.</li>
<li><b><a href="JavaScript:exam.TCard(222,0)">Pointers.pas</a> и <a href="JavaScript:exam.TCard(22201,0)">References.pas</a>.</b> Указатели утрачивают свои позиции. Вместо них мы
рекомендуем активно использовать ссылки.</li>
<li><b><a href="JavaScript:exam.TCard(223,0)">StructTypeEquiv.pas</a>.</b> В отличие от Delphi,
для некоторых типов имеет место структурная, а не именная эквивалентность
типов. Так, структурная эквивалентность имеет место для динамических
массивов, указателей, множеств и процедурных типов.
</li>
</ol>
<p><b>Подпрограммы</b></p>
<ol start=24>
<li><b><a href="JavaScript:exam.TCard(224,0)">FuncParams.pas</a>.</b> Подпрограммы с переменным числом параметров делаются
легко добавлением ключевого слова params
перед параметром - динамическим массивом. Такой параметр должен быть
последним в списке.</li>
<li><b><a href="JavaScript:exam.TCard(225,0)">Overload.pas</a>.</b> Перегрузка имен подпрограмм осуществляется без ключевого
слова overload.</li>
<li><b><a href="JavaScript:exam.TCard(226,0)">ProcVars.pas</a>.</b> Процедурные переменные могут &quot;накапливать&quot; действия при
помощи оператора +=. Эти действия можно отключать при помощи
оператора -=. Процедурные переменные могут инициализироваться не только
обычными подпрограммами, но и статическими и экземплярными методами класса.</li>
<li><b><a href="JavaScript:exam.TCard(227,0)">SwapT.pas</a>.</b> Обобщенные подпрограммы имеют простой синтаксис и
используются сразу наряду с обычными: procedure
Swap&lt;T&gt;(var x,y: T);</li>
</ol>
<p><b>Модули</b></p>
<ol start=28>
<li><b><a href="JavaScript:exam.TCard(228,0)">SystemUnitTest.pas</a>.</b> Системный модуль имеет название PABCSystem, а не System, как в
Delphi, и подключается неявно первым в списке
uses. Причина такого именования состоит в том, что
важнейшее пространство имен .NET имеет имя
System. Системный модуль
объединяет многие подпрограммы модулей System,
Math и Utils языка
Delphi. Данная программа иллюстрирует пересечение имен во модуле
PABCSystem и пространстве имен
System.</li>
<li><b><a href="JavaScript:exam.TCard(229,0)">MainProgram.pas</a> и
<a href="JavaScript:exam.TCard(22901,0)">MyUnit.pas</a>.</b> Модуль может иметь упрощенный синтаксис (без
деления на раздел интерфейса и раздел реализации), что удобно для начального
обучения. В этом случае все описанные имена попадают в раздел интерфейса
модуля.</li>
<li><b><a href="JavaScript:exam.TCard(230,0)">SystemUnitTest.pas</a>.</b> Для использования пространств имен .NET
применяется тот же синтаксис, что и при подключении модулей:
пространства имен .NET указываются в списке uses.
Порядок поиска имен такой же, как и в Delphi -
справа налево в списке uses, модуль
PABCSystem просматривается последним.</li>
<li><b><a href="JavaScript:exam.TCard(231,0)">Main.pas</a> и
<a href="JavaScript:exam.TCard(23101,0)">MyDll.pas</a>.</b> В PascalABC.NET легко создать и использовать
dll. Библиотека dll по-существу представляет собой
модуль, где вместо ключевого слова unit
используется слово library. Для подключения
dll к другой программе используется директива
компилятора reference. </li>
<li><b><a href="JavaScript:exam.TCard(232,0)">CallCS.pas</a>.</b> PascalABC.NET -
полноценный .NET-язык, легко совмещаемый с другими
.NET-языками. В данном примере показывается, как в программе
на &nbsp;PascalABC.NET вызвать функцию из dll, созданной на
C#.</li>
<li><b><a href="JavaScript:exam.TCard(233,0)">CallNative.pas</a>.</b> PascalABC.NET позволяет легко вызывать функции
из обычных dll. </li>
</ol>
<p><b>Стандартные графические библиотеки</b></p>
<ol start=34>
<li><b><a href="JavaScript:exam.TCard(234,0)">GraphABCTest.pas</a>.</b> Графическая библиотека
GraphABC заточена под легкое обучение программированию графики. Она
скрывает большинство сложностей программирования графики: сама осуществляет
перерисовку графического окна в нужный момент и заботится о синхронизации
рисования в нескольких обработчиках. Кроме того, графические примитивы -
процедурные, а значит, не надо создавать многочисленные классы, как в
NET. И еще можно писать графические команды сразу
после begin основной программы, то есть использовать графику в
несобытийных приложениях.</li>
<li><b><a href="JavaScript:exam.TCard(235,0)">MouseEvents.pas</a>.</b> Для графических приложений можно
использовать простейшие события мыши и клавиатуры, реализованные как
глобальные процедурные переменные.</li>
<li><b><a href="JavaScript:exam.TCard(236,0)">ABC.pas</a>.</b> Библиотека векторных графических объектов ABCObjects используется нами
для раннего обучения школьников основам объектно-ориентированного
программирования. Однако, ее вполне можно использовать для написания
несложных графических обучающе-игровых приложений.</li>
</ol>
<p><b>Классы</b></p>
<ol start=37>
<li><b><a href="JavaScript:exam.TCard(237,0)">AllFromObject.pas</a>.</b> Все классы - наследники Object, все типы - классы.
У каждой переменной можно узнать тип, вызвав метод
GetType. Операция typeof для типа возвращает System.Type.</li>
<li><b><a href="JavaScript:exam.TCard(238,0)">WriteRecord.pas</a>.</b> Переопределив метод ToString в классе или
записи, мы получаем возможность выводить их значения в процедуре
writeln</li>
<li><b><a href="JavaScript:exam.TCard(239,0)">ClassConstructor.pas</a>.</b> Для статических методов и полей используется ключевое
слово class. Статические конструкторы используются для нетривиальной
инициализации статических полей.</li>
<li><b><a href="JavaScript:exam.TCard(240,0)">PersonInternal.pas</a>.</b> Новый синтаксис конструкторов использует ключевое слово
new и является предпочтительным. По этой
причине все конструкторы, определенные в старом стиле, должны иметь имя
Create. Описание методов может производиться непосредственно внутри классов и записей
(как в C++, C# и
Java)</li>
<li><b><a href="JavaScript:exam.TCard(241,0)">Records.pas</a>.</b> Методы и конструкторы в записях можно использовать так же, как и в
классах. От записей нельзя наследовать и записи нельзя наследовать.</li>
<li><b><a href="JavaScript:exam.TCard(242,0)">Boxing.pas</a>.</b> При присваивании размерного типа объекту типа Object происходит упаковка. Для
распаковки следует использовать явное приведение типа.</li>
<li><b><a href="JavaScript:exam.TCard(243,0)">GarbageCollection.pas</a>.</b> Деструкторы отсутствуют. Автоматическая сборка мусора
для возврата памяти, распределенной объектной переменной, требует, чтобы на
эту память никто более не ссылался, прямо или косвенно. Поэтому для
освобождения памяти обычно достаточно присвоить объектной переменной nil.
</li>
<li><b><a href="JavaScript:exam.TCard(244,0)">OperatorOverloading.pas</a>.</b> Как и в C++ и C#, в PascalABC.NET можно перегружать
знаки операций для записей и классов.</li>
<li><b><a href="JavaScript:exam.TCard(245,0)">Interf.pas</a>.</b> Интерфейсы
семантически совпадают с интерфейсами в C# и Java. Сложная
реализация интерфейсов Delphi на основе
COM отвергнута.</li>
<li><b><a href="JavaScript:exam.TCard(246,0)">Stack.pas</a>.</b> Обобщенные классы (generics)
позволяют создавать классы, параметризованные одним или несколькими типами.</li>
<li><b><a href="JavaScript:exam.TCard(247,0)">Where.pas</a>.</b> Можно задавать ограничения на типы параметров обобщенных классов.
Ограничения бывают трех сортов: наличие у типа-параметра конструктора по
умолчанию, наследование его от конкретного класса или реализация интерфейса.</li>
</ol>
<p><b>Стандартная </b><b>библиотека .NET</b></p>
<ol start=48>
<li><b><a href="JavaScript:exam.TCard(248,0)">DateTime.pas</a>.</b> Данный пример иллюстрирует применение класса DateTime из стандартной библиотеки
.NET.</li>
<li><b><a href="JavaScript:exam.TCard(249,0)">LinkedList.pas</a>.</b> Данный пример иллюстрирует использование контейнерных
классов из стандартной библиотеки .NET.</li>
<li><b><a href="JavaScript:exam.TCard(250,0)">WinFormWithButton.pas</a>.</b> Данный пример иллюстрирует создание оконного приложения.</li>
</ol>
</body>
</html>

View file

@ -0,0 +1,114 @@
<html>
<head>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="Keyword" value="PascalABC">
</object>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title></title>
<link rel="StyleSheet" href="../default.css">
<style type="text/css">
.auto-style1 {
color: #FF0000;
}
</style>
</head>
<body>
<OBJECT id=exam type="application/x-oleobject" classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11" style="position:absolute; top:-100; left:-100;">
<param name="Command" value="TCard">
<param name="Text" value="">
</OBJECT>
<H1>Система PascalABC.NET</H1>
<p><strong>PascalABC.NET</strong> <font face="Arial"></font> это
<span class="auto-style1"><strong>система
программирования и язык Pascal нового поколения</strong></span> для платформы Microsoft .NET.
Язык <strong>PascalABC.NET</strong> содержит все основные
элементы
современных языков программирования:
<a href="../LangGuide/Modules/indexmodule.html">модули</a>,
<a href="../LangGuide/Classes/index_classes.html">классы</a>,
<a href="../LangGuide/Classes/operoverloading.html">перегрузку операций</a>,
<a href="../LangGuide/Interfaces/indexinterf.html">интерфейсы</a>,
<a href="../LangGuide/ExceptionHandling/Overview.html">исключения</a>,
<a href="../LangGuide/Generics/index_generics.html">обобщенные классы</a>,
<a href="../LangGuide/MemoryManagement/index_memory.html">сборку мусора</a>,
<a href="../LangGuide/FuncProgramming/lambdas.html">лямбда-выражения</a>, а
также некоторые средства параллельности, в том числе
<a href="../LangGuide/OpenMP/indexopenmp.html">директивы OpenMP</a>. Система <b>PascalABC.NET</b> включает
в себя также простую интегрированную среду, ориентированную на эффективное
обучение современному программированию. </p>
<ul>
<li><a href="../LangGuide/index_lang_guide.html">Описание языка <strong>PascalABC.NET</strong></a>.</li>
<li><a href="AdvantagePABC.html">Преимущества&nbsp;<b>PascalABC.NET</b></a> для
разработки программ и для обучения. </li>
<li><a href="PABCNETvsDelphi.html">Отличия <b>PascalABC.NET</b> от Delphi (Object
Pascal)</a>.
</li>
<li>Примеры, иллюстрирующие основные особенности <b>PascalABC.NET</b>,
находятся в меню &quot;Помощь/Коротко о главном&quot;.</li>
</ul>
<p>Язык Паскаль был разработан швейцарским ученым Никлаусом Виртом в 1970 г. как
язык со строгой типизацией и интуитивно понятным синтаксисом. В 80-е годы
наиболее известной реализацией стал компилятор Turbo Pascal
фирмы Borland, в 90-е ему на смену пришла среда
программирования Delphi, которая стала одной из
лучших сред для быстрого создания приложений под Windows.
Delphi ввела в язык Паскаль ряд удачных объектно-ориентированных расширений,
обновленный язык получил название Object Pascal. С версии Delphi 7
<span lang="ru">язык </span>Delphi Object Pascal<span lang="ru"> стал называться
просто </span>Delphi<span lang="ru">. </span>Из
альтернативных реализаций Object Pascal следует отметить
многоплатформенный open source компилятор Free
Pascal.</p>
<p>Создание <strong>PascalABC.NET</strong>
<font face="Arial">диктовалось двумя основными причинами:</font> устаревание
стандартного языка Pascal и систем, построенных на его основе (Free Pascal), а
также необходимость в современной простой, бесплатной и мощной
интегрированной среде
программирования.</p>
<p> <strong>PascalABC.NET</strong> опирается на передовую платформу
программирования Microsoft.NET, которая обеспечивает язык <b>PascalABC.NET</b>
огромным количеством стандартных библиотек и позволяет легко
сочетать его с другими .NET-языками: C#,
Visual Basic.NET, управляемый C++, Oxygene и др. Платформа .NET предоставляет также такие языковые
средства как единый механизм обработки исключений, единый механизм управления
памятью в виде <em>сборки мусора</em>, а также возможность свободного использования классов, наследования,
полиморфизма и интерфейсов между модулями, написанными на разных .NET-языках.
О том, что такое платформа Microsoft.NET, о ее преимуществах для программирования
и для обучения можно прочитать <a href="Net.html">здесь</a>.</p>
<p>Язык <b>PascalABC.NET</b> близок к реализации Delphi (Object Pascal). В нем
отсутствует ряд <a href="PABCNETvsDelphi.html">специфических языковых конструкций Delphi</a>,
некоторые конструкции изменены. Кроме этого,
добавлен ряд возможностей: имеется автоопределение типа при описании, можно описывать переменные внутри блока, имеются операции <code>+=</code>, <code>
-=</code>, <code>*=</code>, <code>/=</code>, методы можно описывать непосредственно в теле класса или
записи, можно пользоваться встроенными в стандартные типы методами и свойствами, память под объекты управляется
<a href="../LangGuide/MemoryManagement/index_memory.html">сборщиком мусора</a> и
не требует явного освобождения, множества <b>
<code>set</code></b> могут быть
созданы на основе произвольных типов, введен операторы <code><b>foreach</b></code>, переменные
циклов <b><code>for</code></b> и <b><code>foreach</code></b>
можно описывать непосредственно в заголовке цикла, имеются
обобщенные классы и подпрограммы (generics), последовательности, кортежи, срезы, лямбда-выражения и др.</p>
<p>Близким по идеологии к <strong>PascalABC.NET</strong>
является язык RemObjects Oxygene (Object Pascal 21 века). Однако он сильно изменен в
сторону .NET: нет глобальных описаний, все описания
помещаются в класс, содержащий <span lang="ru">статический</span> метод Main,
отсутствует ряд стандартных подпрограмм языка Паскаль. Кроме того, система
RemObjects Oxygene - платная
и не содержит собственной оболочки (встраивается в Visual Studio<span lang="ru">
и другие </span>IDE), что практически делает невозможным ее использование в сфере образования.</p>
<p>Интегрированная среда <strong>PascalABC.NET </strong>
обеспечивает подсветку синтаксиса, подсказку по коду (подсказка по точке,
подсказка параметров подпрограмм, всплывающая подсказка по коду), форматирование
текста программы по запросу, переход к определению и реализации имени, элементы
рефакторинга.</p>
<p>Все права на систему программирования <b>PascalABC.NET</b>
принадлежат PascalABCCompiler Team (web-сайт
<a href="http://pascalabc.net/" target=_blank>http://pascalabc.net</a>). </p>
</body>
</html>

View file

@ -0,0 +1,6 @@
cd PABCSystemDocGen
!AllSteps.exe
cd ..
"C:\Program Files (x86)\HTML Help Workshop\hhc.exe" PascalABCNET.hhp
copy PascalABCNET.chm ..\bin\PascalABCNET.chm
copy PascalABCNET.chm ..\Release\PascalABCNET.chm

View file

@ -0,0 +1,41 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title></title>
<link rel="StyleSheet" href="../../default.css">
</head>
<body>
<H1>Анимация без мерцания</H1>
Данная программа иллюстрирует применение процедур <code>LockDrawing</code> и
<code>Redraw</code> для реализации анимации без мерцания:
<blockquote>
<pre>
<code><b>uses</b> GraphABC;
<b>begin</b>
<a href="../../PABCUnits/GraphABC/gr_LockDrawing.html">LockDrawing</a>;
<b>for </b><b>var</b> i:=1 to 500 do
<b>begin</b>
Window.Clear;
Brush.Color := clGreen;
Ellipse(i,100,i+100,200);
<a href="../../PABCUnits/GraphABC/gr_LockDrawing.html">Redraw</a>;
Sleep(1);
<b>end</b>;
<b>end</b>.</code>
</pre>
</blockquote>
<p>Основная идея состоит в следующем: отключим рисование на экране, вызвав <code>
LockDrawing</code> (рисование будет осуществляться только во внеэкранном
буфере), после чего будем всякий раз формировать новый кадр изображения и
выводить его целиком на экран, вызывая <code>Redraw</code>. При вызове <code>
Redraw</code> перерисовывается все графическое окно,
поэтому скорость анимации ограничена скоростью вывода внеэкранного буфера на
экран.</p>
</body>
</html>

View file

@ -0,0 +1,37 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title></title>
<link rel="StyleSheet" href="../../default.css">
</head>
<body>
<H1>Ðèñîâàíèå ìûøüþ â ãðàôè÷åñêîì îêíå</H1>
Äàííàÿ ïðîãðàììà îñóùåñòâëÿåò ðèñîâàíèå ìûøüþ â ãðàôè÷åñêîì îêíå:
<blockquote>
<pre>
<code><b>uses</b> GraphABC;<b>
<span style="font-size: 4pt">
</span>procedure</b> MouseDown(x,y,mb: integer);
<b>begin</b>
MoveTo(x,y);
<b>end</b>;
<b><span style="font-size: 4pt">
</span>procedure</b> MouseMove(x,y,mb: integer);
<b>begin</b>
<b>if</b> mb=1 <b>then</b> LineTo(x,y);
<b>end</b>;
<b><span style="font-size: 4pt">
</span>begin
</b> // Ïðèâÿçêà îáðàáîò÷èêîâ ê ñîáûòèÿì
<a href="../../PABCUnits/GraphABC/gr_events.html">OnMouseDown</a> := MouseDown;
<a href="../../PABCUnits/GraphABC/gr_events.html">OnMouseMove</a> := MouseMove
<b>end</b>.</code>
</pre>
</blockquote>
</body>
</html>

View file

@ -0,0 +1,37 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title></title>
<link rel="StyleSheet" href="../../default.css">
</head>
<body>
<H1>Ïåðåìåùåíèå îêíà ñ ïîìîùüþ êëàâèàòóðû</H1>
Äàííàÿ ïðîãðàììà îñóùåñòâëÿåò ïåðåìåùåíèå ãðàôè÷åñêîãî îêíà ñ ïîìîùüþ êëàâèàòóðû:
<blockquote>
<pre>
<code><b>uses</b> GraphABC;
<b><span style="font-size: 4pt">
</span>procedure</b> KeyDown(Key: integer);
<b>begin</b>
<b> case</b> Key <b>of</b>
<a href="../../PABCUnits/GraphABC/gr_VK.html">VK_Left</a>: Window.Left := Window.Left - 2;
<a href="../../PABCUnits/GraphABC/gr_VK.html">VK_Right</a>: Window.Left := Window.Left + 2;
<a href="../../PABCUnits/GraphABC/gr_VK.html">VK_Up</a>: Window.Top := Window.Top - 2;
<a href="../../PABCUnits/GraphABC/gr_VK.html">VK_Down</a>: Window.Top := Window.Top + 2;
<b> end</b>;
<b>end</b>;
<b><span style="font-size: 4pt">
</span>begin</b>
// Ïðèâÿçêà îáðàáîò÷èêîâ ê ñîáûòèÿì
<a href="../../PABCUnits/GraphABC/gr_events.html">OnKeyDown</a> := KeyDown;
<b>end</b>.</code>
</pre>
</blockquote>
</body>
</html>

View file

@ -0,0 +1,37 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title></title>
<link rel="StyleSheet" href="../../default.css">
</head>
<body>
<H1>Ïðèìåð èñïîëüçîâàíèÿ òàéìåðà</H1>
Äàííàÿ ïðîãðàììà âûâîäèò 1 êàæäûå 100 ìèëëèñåêóíä<span lang="en-us"> </span>â
òå÷åíèå 3 ñåêóíä:<blockquote>
<pre>
<code><b>uses</b> <span lang="en-us">Timers</span>;<b>
<span style="font-size: 4pt">
</span>procedure</b> <span lang="en-us">TimerProc</span>;
<b>begin</b>
<span lang="en-us">write(1)</span>;
<b>end</b>;
<b><span style="font-size: 4pt">
</span>begin
</b> <span lang="en-us"><b>var</b> t := <b>new</b> Timer(100,TimerProc);
t.Start;
Sleep(3000);
</span><b>end</b>.</code>
</pre>
</blockquote>
<p>Âûçîâ <code>Sleep</code><span lang="en-us"> </span>çäåñü îáÿçàòåëåí, èíà÷å
ïðîãðàììà ïîñëå ñîçäàíèÿ òàéìåðà ñðàçó çàêîí÷èòñÿ, è îáðàáîò÷èê òàéìåðà íè ðàçó
íå ñðàáîòàåò.</p>
</body>
</html>

View file

@ -0,0 +1,166 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title></title>
<link rel="StyleSheet" href="../../default.css">
</head>
<body>
<H1>Задание Begin3 из электронного задачника Programming Taskbook</H1>
<hr>
<p>Задание Begin3 относится к самой первой группе задачника, посвященной
знакомству с вводом-выводом и оператором присваивания.
Приведем формулировку этого задания.
</p>
<p><b>Begin3</b>. Даны стороны
прямоугольника <code>a</code> и <code>b</code>.
Найти его площадь <code>S=a*b</code> и периметр <code>P=2*(a+b)</code>. </p>
<p>Далее по шагам опишем сценарий выполнения задания в системе
<b>PascalABC.NET</b>.</p>
<hr>
<p><font color="#0000FF"><b><i>Шаг 1.</i> </b></font>Для
выполнения заданий из электронного задачника подключим к программе модуль
<code>PT4</code> и вызовем в
начале программы процедуру <code>Task</code>, передав ей в
качестве параметра имя задания:</p>
<blockquote>
<code><b>uses</b> PT4;<br><b>begin</b><br>&nbsp;&nbsp;Task('Begin3');<br>
<br><b>end</b>.</code>
</blockquote>
<p>Заметим, что эту программу не обязательно набирать вручную. Для автоматической генерации данной программы
выполним следующие действия. Нажмем кнопку
<img border="0" src="../PT4/gif/load.gif" width="16" height="17">. На экране появится окно
программного модуля <b>PT4Load</b>, позволяющего создать программу-заготовку для требуемого задания:
</p>
<blockquote>
<img border="0" src="../PT4/gif/pt4load.png">
</blockquote>
<p>Наберем в поле ввода «Задание»
текст <code>Begin3</code> и нажмем <b>Enter</b>.
После этого указанный выше текст сгенерируется автоматически и сохранится в
файле Begin3.pas в рабочем каталоге
системы <b>PascalABC.NET</b>
(по умолчанию это каталог C:\PABCWork.NET).</p>
<p>Запустим программу (нажав клавишу <b>F9</b>),
чтобы увидеть на экране текст задания:<a name="s1"></a></p>
<blockquote>
<img border="0" src="gif/Begin3-1.png">
</blockquote>
<p>Запуск нашей программы был признан <i>ознакомительным</i> (и поэтому правильность решения не анализировалась),
так как в ходе ее выполнения не было совершено ни одной операции ввода-вывода.
</p>
<hr>
<p><b><font color="#0000FF"><i>Шаг 2.</i> </font></b>Переменные
<code>a</code> и <code>b</code>
считываются из полей ввода, выделенных желтым цветом, с помощью обычной процедуры <code>read</code>. Закроем окно задачника
и изменим программу следующим образом:
</p>
<blockquote>
<code><b>uses</b> PT4;<br><b>var </b>a, b: integer;<b><br>
begin</b><br>&nbsp;&nbsp;Task('Begin3');<br>
&nbsp; read(a, b);<br>
<b>end</b>.</code>
</blockquote>
<p>После запуска этого вариант программы окно задачник примет вид:</p>
<blockquote>
<img border="0" src="gif/Begin3-2.png">
</blockquote>
<p>Как видим, исходные данные поменялись и появилось сообщение
об ошибке &#151; переменные <code>a</code> и <code>b</code> должны быть объявлены как
вещественные. Если запуск программы не является ознакомительным, то в окне задачника
появляется раздел с полученными результатами
(в нашем случае он не содержит ни одного числа), а также панель индикаторов,
показывающих количество введенных и выведенных данных, а также число успешных тестовых запусков
программы.
</p>
<hr>
<p><font color="#0000FF"><b><i>Шаг 3.</i> </b></font>Исправим тип исходных данных:</p>
<blockquote>
<code><b>uses</b> PT4;<br><b>var </b>a, b: real;<b><br>
begin</b><br>&nbsp;&nbsp;Task('Begin3');<br>
&nbsp; read(a, b);<br>
<b>end</b>.</code>
</blockquote>
<p>Вновь запустим программу:</p>
<blockquote>
<img border="0" src="gif/Begin3-3.png">
</blockquote>
<p>Электронный задачник предупреждает, что не выведен результат.
Обратите внимание на то, что для сообщений о различных видах ошибок используются
разные цвета (например, фиолетовый для ошибок, связанных с несоответствием типов,
и оранжевый для ошибок, связанных с вводом/выводом недостаточного числа данных).
</p>
<hr>
<p><font color="#0000FF"><b><i>Шаг 4.</i> </b></font>Проведем
вычисления и выведем результирующие данные, но в неверном порядке:</p>
<blockquote>
<code><b>uses</b> PT4;<br><b>var </b>a, b, S, P: real;<b><br>
begin</b><br>&nbsp;&nbsp;Task('Begin3');<br>
&nbsp; read(a, b);<br>
&nbsp; S := a * b;<br>
&nbsp; P := 2 * (a + b);<br>
&nbsp; write(P, S)<br>
<b>end</b>.</code>
</blockquote>
<p>Вновь запустим программу:</p>
<blockquote>
<img border="0" src="gif/Begin3-4.png">
</blockquote>
<p>Мы видим, что все требуемые исходные данные введены, все результаты выведены,
однако полученные результаты имеют неверные значения.
В случае ошибочного решения окно задачника всегда содержит раздел с примером
верного решения, чтобы можно было сравнить полученные и правильные результаты.</p>
<hr>
<p><font color="#0000FF"><b><i>Шаг 5.</i> </b></font>Исправим
ошибку:</p>
<blockquote>
<code><b>uses</b> PT4;<br><b>var </b>a, b, S, P: real;<b><br>begin</b><br>&nbsp;&nbsp;Task('Begin3');<br>&nbsp; read(a, b);<br>
&nbsp; S := a * b;<br>
&nbsp; P := 2 * (a + b);<br>
&nbsp; write(S, P)<br><b>end</b>.</code>
</blockquote>
<p>После запуска программы увидим следующее окно:</p>
<blockquote>
<img border="0" src="gif/Begin3-5.png">
</blockquote>
<p>Если решение является правильным, то дополнительный раздел с примером правильного
решения в окне не выводится.</p>
<hr>
<p><font color="#0000FF"><b><i>Шаг 6.</i> </b></font>Чтобы задание считалось выполненным, запустим
программу еще два раза. В результате в окне задачника появится сообщение «Задание
выполнено!»: </p>
<blockquote>
<img border="0" src="gif/Begin3-6.png">
</blockquote>
<p>Поздравляем! Задание <code>Begin3</code>
под руководством электронного задачника выполнено! Результаты выполнения заданий можно просмотреть,
щелкнув мышью на метке &laquo;Результаты (F2)&raquo;, расположенной в правом верхнем
углу окна задачника, или нажав клавишу <b>F2</b>.
После закрытия окна задачника и возврата в среду PascalABC.NET результаты можно отобразить на экране,
нажав кнопку <img border="0" src="../PT4/gif/results.gif" width="16" height="17"> или нажав клавиатурную
комбинацию <b>Shift+Ctrl+R</b>.
</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
</body>
</html>

View file

@ -0,0 +1,101 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title></title>
<link rel="StyleSheet" href="../../default.css">
</head>
<body>
<H1>Задание a1 для исполнителя Робот</H1>
<hr>
<p>Задание a1 относится к вводным заданиям, посвященным
знакомству с основными командами исполнителя Робот.
Приведем формулировку этого задания.
</p>
<p><b>a1</b>. Закрасить помеченные клетки.</p>
<blockquote>
<img border="0" src="gif/RBa1-1.png">
</blockquote>
<p>Опишем сценарий решения задания.</p>
<hr>
<p><font color="#0000FF"><b><i>Шаг 1.</i> </b></font>Подключим
к программе модуль <code>Robot</code> и вызовем в
начале программы процедуру <code>Task</code>, передав ей в
качестве параметра имя задания:</p>
<blockquote>
<code><b>uses</b> Robot;<br><b>begin</b><br>&nbsp;&nbsp;Task('a1');<br>
<br><b>end</b>.</code>
</blockquote>
<p>Чтобы не набирать указанный текст, нажмем кнопку
<img border="0" src="../PT4/gif/load.gif" width="16" height="17"> и
в появившемся окне наберем имя задания <code>RBa1</code> (префикс <code>RB</code>
означает, что решается задача для Робота). Запустим программу (нажав клавишу <b>F9</b>), чтобы увидеть окно Робота с
графическим изображением задания:</p>
<blockquote>
<img border="0" src="gif/RBa1-2.png">
</blockquote>
<hr>
<p><font color="#0000FF"><b><i>Шаг 2.</i> </b></font>
Наберем несколько команд Робота: </p>
<blockquote>
<code><b>uses</b> Robot;<br><b>begin</b><br>&nbsp;&nbsp;Task('a1');<br>
&nbsp; Right;Right;Right;Right;<br><b>end</b>.</code>
</blockquote>
<p>Запустим программу, после чего нажмем <b>Enter</b> или кнопку
«Пуск» чтобы Робот начал выполнять
заложенную в него программу:</p>
<blockquote>
<img border="0" src="gif/RBa1-3.png">
</blockquote>
<p>После окончания движения Робота осуществляется проверка, все
ли помеченные клетки закрашены и находится ли Робот в конечной клетке.
Если проверка дает отрицательный ответ, то задание не считается выполненным.</p>
<hr>
<p><font color="#0000FF"><b><i>Шаг 3.</i> </b></font>
Выполним неверную команду, в результате которой Робот врежется в
стенку:</p>
<blockquote>
<code><b>uses</b> Robot;<br><b>begin</b><br>&nbsp;&nbsp;Task('a1');<br>
&nbsp; Right;Right;Right;Right;<br>
&nbsp; Up;Up;Left;<br><b>end</b>.</code>
</blockquote>
<p>После запуска программы и нажатия <b>Enter</b>
получим следующее окно:</p>
<blockquote>
<img border="0" src="gif/RBa1-4.png">
</blockquote>
<p>Заметим, что квадратный индикатор состояния Робота окрасился в красный цвет, а
последняя команда <code>Left</code> не выполнилась, так как
после фатальной ошибки Робот прекратил выполнение задания.</p>
<hr>
<p><font color="#0000FF"><b><i>Шаг 4.</i> </b></font>
Исправим ошибку и выполним задание до конца:</p>
<blockquote>
<code><b>uses</b> Robot;<br><b>begin</b><br>&nbsp;&nbsp;Task('a1');<br>
&nbsp; Right;Right;Right;Right;<br>
&nbsp; Up;<br>
&nbsp; Left;Paint;<br>
&nbsp; Left;Paint;<br>
&nbsp; Left;Paint;<br>
&nbsp; Left;Paint;<br>
&nbsp; Left;<br>
<b>end</b>.</code>
</blockquote>
<blockquote>
<img border="0" src="gif/RBa1-5.png">
</blockquote>
<p>Последний рисунок не нуждается в комментариях.</p>
<p>Заметим, что сведения о выполненных заданиях
можно просмотреть, нажав кнопку
<img border="0" src="../PT4/gif/results.gif" width="16" height="17">.</p>
<p>&nbsp;</p>
</body>
</html>

View file

@ -0,0 +1,674 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title></title>
<link rel="StyleSheet" href="../../default.css">
</head>
<body>
<a name="main"></a>
<h1>Задания, связанные с ЕГЭ по информатике
</h1>
<hr>
<h2>Пример 1. Простая задача на реализацию базовых алгоритмов
</h2>
<hr>
<p>Группа заданий ExamBegin посвящена базовым алгоритмическим задачам,
включенным в кодификатор ЕГЭ по информатике. Процесс выполнения подобных заданий мы рассмотрим на примере
одной из простых задач, связанных с нахождением максимумов и минимумов из двух, трех или четырех чисел
без использования массивов и циклов.
</p>
<p class="task">ExamBegin2&#176;. На вход подаются три вещественных числа; числа расположены в одной строке.
Вывести вначале минимальное, а затем максимальное из них. Каждое число должно выводиться на новой строке
и снабжаться комментарием: &#171;MIN=&#187; для минимального, &#171;MAX=&#187;
для максимального.
</p>
<hr>
<h3>Создание программы-заготовки и знакомство с заданием
</h3>
<p>Напомним, что программу-заготовку для решения этого задания можно создать с помощью
команды
меню &laquo;Модули | Создать шаблон программы&raquo;, кнопки
<img border="0" src="gif/Load.gif" width="16" height="17"> или клавиатурной
комбинации <b>Shift+Ctrl+L</b>. Приведем текст созданной заготовки:
</p>
<blockquote><code><pre><b>uses</b> PT4Exam;
<b>begin</b>
Task('ExamBegin2');
<b>end</b>.
</pre></code></blockquote>
<p>После запуска программы на экране появится <a href="../PT4/window.html">окно задачника</a>:
</p>
<blockquote>
<img border="0" src="gif/ExamBegin2-1.png">
</blockquote>
<p>Обсудим особенности программы-заготовки и окна задачника.
</p>
<p>В программе-заготовке вместо модуля <code>PT4</code>
подключается модуль <code>PT4Exam</code>, специально предназначенный для использования при выполнении
заданий групп Exam. Данный модуль содержит реализацию единственной процедуры <code>Task</code>,
инициализирующей задание. Никакие дополнительные процедуры, связанные с вводом-выводом, в него не включены.
Это обусловлено тем, что ввод-вывод при выполнении заданий групп Exam надо выполнять, используя
<i>стандартные процедуры языка Pascal</i>.
</p>
<p>Основной особенностью окна задачника является то, что в разделе исходных данных отсутствуют данные,
выделенные желтым цветом (напомним, что желтый цвет используется для выделения данных, которые необходимо
вводить с помощью специальных процедур ввода задачника). Вместо этого в окне отображается
строка бирюзового цвета, содержащая числовые данные. Вид строки подчеркивает то обстоятельство,
что вводить данные требуется не с помощью специальных процедур ввода, имеющихся в задачнике,
а с помощью стандартных процедур языка Pascal. Отметим, что бирюзовый цвет используется в окне задачника
для отображения &laquo;внешних&raquo; данных (содержащихся в файлах или динамических структурах), доступ к которым
должен осуществляться с помощью стандартных средств используемого языка программирования.
</p>
<p>Пример верного решения выделяется серым цветом
(в отличие от &laquo;настоящих&raquo; результатов, выведенных программой учащегося, которые, как и входные данные,
выделяются бирюзовым цветом), однако <i>представление</i> выходных данных совпадает с
представлением входных: это набор строк,
содержащих числовые данные (дополненные комментариями). Вид данных в разделе результатов показывает,
что для их вывода, как и для ввода исходных данных, необходимо использовать стандартные процедуры языка Pascal.
</p>
<p>
<b>Примечание.</b>
Если вы уже выполняли задания, связанные с обработкой файлов, то можете заметить, что отображение данных
в заданиях групп Exam
в точности соответствует способу отображения содержимого <i>текстовых файлов</i>. Это совпадение не случайно.
На самом деле во всех заданиях групп Exam все исходные данные хранятся в специальном входном текстовом файле,
а все результаты должны записываться в специальный выходной текстовый файл. Однако при этом не требуется
выполнять особых действий, связанных с определением имен этих файлов, связыванием файлов с файловыми
переменными, открытием и закрытием файлов (все эти действия выполняются задачником автоматически).
Для программы, выполняющей задание, эти файлы играют роль <i>стандартных потоков ввода-вывода</i>,
поэтому для доступа к ним достаточно использовать обычные процедуры ввода-вывода языка Pascal.
</p>
<hr>
<h3>Ввод исходных данных и их обработка
</h3>
<p>Приступим к выполнению задания. В данном случае следует использовать алгоритм, не требующий
применения массивов, поэтому опишем три простые переменные вещественного типа и введем в них исходные данные:
</p>
<blockquote><code><pre><b>uses</b> PT4Exam;
<b>var</b>
a, b, c: real;
<b>begin</b>
Task('ExamBegin2');
read(a, b, c);
<b>end</b>.
</pre></code></blockquote>
<p>Мы воспользовались стандартной процедурой ввода <code>read</code>, введя все три исходных числа за один ее вызов.
Этого же результата мы могли бы добиться и с помощью процедуры <code>readln</code>:
</p>
<blockquote><code><pre>readln(a, b, c);
</pre></code></blockquote>
<p>Заметим, что использование <i>отдельных</i> процедур <code>readln</code> для ввода каждого числа приведет к ошибочному результату:
</p>
<blockquote><code><pre>readln(a);
readln(b);
readln(c);
</pre></code></blockquote>
<p>В этом случае уже после ввода первого числа произойдет автоматический переход на следующую строку
с исходными данными. Поэтому оставшиеся в первой строке числа будут пропущены, а поскольку
во второй строке &laquo;ничего нет&raquo; (входной поток состоит из единственной строки),
будет выведено сообщение об ошибке &laquo;<i>Input string was not in a correct format</i>&raquo;
(&laquo;<i>Входная строка имела неверный формат</i>&raquo;).
</p>
<p>Приведенный пример показывает, что при организации ввода данных в заданиях групп Exam необходимо учитывать особенности
стандартных процедур <code>read</code> и <code>readln</code>.
</p>
<p>При запуске приведенного выше варианта программы вид окна не изменится, поскольку мы не вывели никаких данных.
В заданиях групп Exam запуск программы считается ознакомительным до тех пор, пока программа не выведет
хотя бы один элемент результирующих данных. Кроме того, задачник не контролирует,
каким образом программа читает исходные данные (например, мы могли бы ввести всю исходную строку
в переменную типа <code>string</code>, а затем &laquo;разобрать&raquo; эту строку, выделив из нее три числа
и преобразовав их к типу <code>real</code>). Отмеченные особенности характерны именно для заданий групп Exam,
в которых для ввода данных не используются специальные средства задачника.
</p>
<p>Реализуем алгоритм нахождения минимального и максимального элемента. Для этого опишем еще две
переменные <code>min</code> и <code>max</code> типа <code>real</code> и добавим в конец программы следующие операторы:
</p>
<blockquote><code><pre><b>if</b> a &lt; b <b>then</b>
<b>begin</b>
min := a;
max := b;
<b>end</b>
<b>else</b>
<b>begin</b>
min := b;
max := a;
<b>end</b>;
<b>if</b> c &lt; min <b>then</b>
min := c
<b>else</b>
<b>if</b> c &gt; max <b>then</b>
max := c;
</pre></code></blockquote>
<p>Таким образом, для одновременного нахождения минимального и максимального из трех чисел требуется
не более трех операций сравнения и не более трех операций присваивания.
</p>
<hr>
<h3>Вывод результатов и их форматирование
</h3>
<p>Осталось вывести полученные результаты. Вывод, как и ввод, следует выполнять с помощью стандартных процедур
языка Pascal, учитывая их особенности.
</p>
<p>Вначале, в качестве примера, организуем вывод, не соответствующий условиям задачи. Для этого добавим в конец программы
следующий оператор:
</p>
<blockquote><code><pre>writeln(min, max);
</pre></code></blockquote>
<p>Приведем вид окна задачника при запуске полученной программы:
</p>
<blockquote>
<img border="0" src="gif/ExamBegin2-2.png">
</blockquote>
<p>Мы видим, что минимум и максимум найдены правильно, однако выведены не в том формате,
который требовался (требуемый формат приводится в разделе с примером верного решения).
Мы допустили при выводе три ошибки: во-первых, вывели оба числа в одной строке
(при этом они &laquo;слились&raquo;, поскольку мы не предусмотрели вывод пробела-разделителя), во-вторых,
не снабдили числа комментариями и, в-третьих, не настроили их отображение в формате
с двумя дробными знаками (первое число было выведено с единственным знаком после точки).
</p>
<p>
<b>Примечание.</b> Следует обратить внимание на панель индикаторов, которая отображается между информационной панелью
и разделом с формулировкой задания в случае, если запуск программы не является
ни демонстрационным, ни ознакомительным. Обычно на этой панели выводятся три индикатора: первый указывает
количество введенных исходных данных, второй &#151; количество выведенных результатов, а третий &#151;
количество успешно пройденных тестовых испытаний. При выполнении заданий, связанных с ЕГЭ, первые два
индикатора являются неактивными, поскольку, как было отмечено выше, для получения исходных данных
и записи результатов не используются средства задачника, и поэтому он не в состоянии
проконтролировать каждую операцию ввода-вывода.
</p>
<p>Для исправления первых двух ошибок достаточно изменить вывод следующим образом:
</p>
<blockquote><code><pre>writeln('MIN=', min);
writeln('MAX=', max);
</pre></code></blockquote>
<p>Однако в этом случае числа по-прежнему могут содержать неверное число дробных знаков.
Для исправления этой последней ошибки проще всего использовать
<i>атрибуты форматирования</i>, начинающиеся с символа &laquo;:&raquo; (двоеточие):
</p>
<blockquote><code><pre>writeln('MIN=', min:0:2);
writeln('MAX=', max:0:2);
</pre></code></blockquote>
<p>Первый атрибут определяет <i>ширину поля вывода</i> (если ширина равна 0, то используется минимально
необходимое поле вывода). Наличие второго атрибута (допустимого только для вещественных чисел) означает,
что число надо вывести в формате с фиксированной точкой, причем его значение равно количеству дробных знаков.
</p>
<p>При запуске исправленной программы будет выведено сообщение о верном решении, а после трех
запусков &#151; сообщение о том, что задание выполнено:
</p>
<blockquote>
<img border="0" src="gif/ExamBegin2-3.png">
</blockquote>
<p>В случае успешного прохождения тестового испытания в окно задачника не включается
раздел с примером верного решения, поскольку данные этого раздела совпадают
с результатами, полученными программой.
</p>
<p>
<b>Примечание.</b>
В системе PascalABC.NET,
благодаря специальному механизму перенаправления данных, стандартные процедуры <code>read-write</code> можно использовать
и при выполнении заданий из других групп, однако важно учитывать ряд особенностей использования этих процедур
в заданиях групп Exam. Во-первых, только в заданиях групп Exam будут проявляться различия в использовании
процедур <code>read-write</code> и <code>readln-writeln</code> (в остальных группах для ввода-вывода можно использовать как вариант
процедуры с суффиксом &laquo;ln&raquo;, так и вариант без этого суффикса). Во-вторых, только в заданиях
групп Exam можно при необходимости <i>использовать атрибуты форматирования</i> при выводе результатов,
а также <i>выводить дополнительные комментарии</i>, если этого требует условие задачи. В-третьих,
только в заданиях групп Exam можно вводить и выводить элементы данных несколькими способами, с использованием переменных
различных типов; например, исходную строку можно либо сразу прочесть в строковую переменную, либо вводить
посимвольно в цикле (в других группах заданий проводится более строгая проверка на соответствие типа переменной
типу элемента исходных или результирующих данных).
</p>
<hr>
<h2>Пример 2. Ввод и вывод массивов
</h2>
<hr>
<p>Рассмотрим еще одно задание группы ExamBegin, особенностью которого является вывод в качестве результата
элементов двумерного массива.
</p>
<p class="task">ExamBegin28&#176;. На вход в первой строке подаются два целых положительных числа <i>M</i> и <i>N</i>,
во второй строке &#8212; вещественное число <i>D</i>, а в третьей строке &#8212; набор из <i>M</i> вещественных чисел.
Сформировать и вывести двумерный вещественный массив размера <i>M</i>&nbsp;&#215;&nbsp;<i>N</i>, у которого первый
столбец совпадает с исходным набором чисел, а элементы каждого следующего столбца равны сумме соответствующего
элемента предыдущего столбца и числа <i>D</i> (в результате каждая строка массива будет содержать
элементы <i>арифметической прогрессии</i>). Каждую строку элементов массива выводить на новой экранной строке,
для каждого числа отводить 7 экранных позиций.
</p>
<p>При запуске программы-заготовки, созданной для этого задания, окно задачника примет следующий вид:
</p>
<blockquote>
<img border="0" src="gif/ExamBegin28-1.png">
</blockquote>
<p>Анализируя исходные данные, можно заметить, что полученная матрица должна иметь 8 строк, тогда как
на экране отображаются только первые пять.
Это связано с тем, что по умолчанию используется режим &laquo;свернутого&raquo; отображения данных, при котором
на экране выводится только несколько начальных строк. Признаком того, что имеются данные,
не выведенные на экране, является кнопка, которая отображается в правом верхнем углу раздела исходных данных
(на этой кнопке изображается стилизованная стрелка, направленная вниз).
Для вывода всех данных достаточно нажать эту кнопку; можно также нажать клавишу <b>Ins</b> или выполнить
щелчок мышью в любом месте раздела с данными задания (кроме раздела, содержащего формулировку).
Если выполнить эти действия для нашего окна, то оно изменится следующим образом:</p>
<blockquote>
<img border="0" src="gif/ExamBegin28-2.png">
</blockquote>
<p>Повторный щелчок мышью, нажатие клавиши <b>Ins</b> или кнопки (на которой в данной ситуации будет отображаться
стрелка, направленная вверх &#151; см. рисунок) восстанавливает &laquo;сокращенное&raquo;
отображение данных. Заметим, что в режиме &laquo;сокращенного&raquo; отображения нумеруется только первая строка данных,
а в режиме полного отображения нумерацией снабжаются все строки.</p>
<p>
<a href="#scroll">Дополнительные возможности</a>, связанные с просмотром
данных большого размера, будут описаны далее, в пункте, посвященном задачам повышенной сложности.
</p>
<p>Если закрыть окно задачника, находясь в режиме отображения всех данных,
то при последующих запусках программы окно будет сразу отображаться в этом режиме.
</p>
<p>Приведем вариант правильного решения данной задачи (в этом варианте учитывается, что результирующий
двумерный массив имеет не более 10 строк и столбцов; соответствующее условие приведено в
преамбуле к описанию
группы ExamBegin):
</p>
<blockquote><code><pre><b>uses</b> PT4Exam;
<b>var</b>
m, n, i, j: integer;
d: real;
a: array[1..10, 1..10] of real;
<b>begin</b>
Task('ExamBegin28');
readln(m, n, d);
<b>for</b> i := 1 <b>to</b> m <b>do</b>
read(a[i, 1]);
<b>for</b> j := 2 <b>to</b> n <b>do</b>
<b>for</b> i := 1 <b>to</b> m <b>do</b>
a[i, j] := a[i, j - 1] + d;
<b>for</b> i := 1 <b>to</b> m <b>do</b>
<b>begin</b>
<b>for</b> j := 1 <b>to</b> n <b>do</b>
write(a[i, j]:7:2);
writeln;
<b>end</b>;
<b>end</b>.
</pre></code></blockquote>
<p>В приведенном решении следует обратить особое внимание на организацию ввода-вывода.
Укажем две особенности, связанные с вводом. Во-первых, несмотря
на то что по условию число <code>d</code> находится во второй строке, мы смогли включить его в один список с
предшествующими числами <code>m</code> и <code>n</code> (поскольку при чтении числовых данных переход на новую строку выполняется
автоматически). Во-вторых, при чтении элементов исходного набора <i>необходимо</i> использовать вариант
процедуры <code>read</code> без суффикса &laquo;ln&raquo;, чтобы не пропустить оставшиеся в этой строке числа.
</p>
<p>При выводе полученного двумерного массива необходимо обеспечить его правильное <i>форматирование</i>:
каждый элемент должен выводиться на семи экранных позициях с двумя дробными знаками и, кроме того,
каждая строка массива должна выводиться на новой экранной строке. Это достигается за счет использования
соответствующих атрибутов форматирования и явного перехода на новую строку с помощью процедуры
<code>writeln</code> без параметров.
</p>
<p>
<b>Примечание.</b>
Заметим, что в заданиях группы Matrix,
также посвященной обработке двумерных массивов, специальные действия по форматированию полученных массивов
выполнять не требуется, так как задачник автоматически форматирует все полученные результаты.
Таким образом, задания группы ExamBegin &laquo;более приближены&raquo; к реальной экзаменационной ситуации,
в которой программа учащегося должна не только обрабатывать исходные данные, но и обеспечивать наглядное
отображение результатов.
</p>
<hr>
<a name="taskc"></a>
<h2>Пример 3. Обработка сложных наборов данных
</h2>
<hr>
<p>Группа ExamTaskC содержит 100 типовых заданий, аналогичных заданиям,
которые предлагаются на ЕГЭ по информатике
в качестве задач повышенной сложности (задача C4). Основную часть данной группы составляют
задания на обработку сложных наборов данных (записей) с элементами-полями различных типов.
В подобных заданиях требуется правильно выбрать способ хранения данных и организовать их эффективную обработку;
при этом обычно требуется применить <i>несколько</i> базовых алгоритмов, например, алгоритм суммирования
или нахождения минимума/максимума и алгоритм поиска нужного элемента или сортировки набора данных по требуемому ключу.
В группу ExamTaskC включены также задания повышенной сложности на обработку текстовых данных
(подобные задания содержатся в завершающем разделе данной группы).
</p>
<p>Следует заметить, что возможность автоматической генерации
больших наборов исходных данных, предоставляемая задачником Programming Taskbook, позволяет существенно ускорить
тестирование учебных программ и сделать его более надежным, что, в свою очередь, повышает эффективность изучения
типовых приемов решения задач группы C.
</p>
<p>В заданиях группы ExamTaskC ввод и вывод имеет те же особенности,
что и в заданиях группы ExamBegin.
</p>
<p>Рассмотрим следующее задание.
</p>
<p class="task">ExamTaskC25&#176;. На вход подаются сведения об абитуриентах. В первой строке
указывается количество абитуриентов&nbsp;<i>N</i>, каждая из последующих <i>N</i>&nbsp;строк имеет
формат<br> <tt>&lt;Номер школы&gt; &lt;Год поступления&gt; &lt;Фамилия&gt;</tt><br>
Номер школы содержит не более двух цифр, годы лежат в диапазоне от 1990 до 2010. Для каждого года,
присутствующего в исходных данных, вывести общее число абитуриентов, поступивших в этом году
(вначале выводить год, затем число абитуриентов). Сведения о каждом годе выводить на новой строке
и упорядочивать по возрастанию номера года.</p>
<p>Программа-заготовка, созданная для этого задания, подобно заготовкам для заданий группы ExamBegin,
будет использовать специальный модуль <code>PT4Exam</code>:
</p>
<blockquote><code><pre><b>uses</b> PT4Exam;
<b>begin</b>
Task('ExamTaskC25');
<b>end</b>.
</pre></code></blockquote>
<p>При запуске этой программы на экране появится окно задачника, содержащее следующие данные:
</p>
<blockquote>
<img border="0" src="gif/ExamTaskC25-1.png">
</blockquote>
<p>Окно будет иметь такой вид, если при его предшествующем закрытии оно находилось в режиме
отображения всех данных.
Для отображения всех данных на экране может потребоваться увеличить высоту окна; для этого достаточно
зацепить мышью заголовок окна и переместить его вверх (для перемещения заголовка окна задачника вверх и вниз
можно также воспользоваться клавиатурными комбинациями <b>Ctrl+Up</b> и <b>Ctrl+Down</b>).
</p>
<p>При первом тестовом испытании программы ей будет предложен для обработки
набор данных не слишком большого размера (порядка 10&#150;20 элементов).
</p>
<p>Вначале следует определиться со структурами данных, которые будут использоваться в программе. Поскольку
требуется найти одну характеристику для каждого года, а число лет невелико, можно использовать
числовой массив <code>year</code>, каждый элемент которого соответствует определенному году. Так как в языке Pascal можно
использовать произвольные границы индексов, удобно в качестве диапазона индексов указать диапазон лет,
который требуется проанализировать: <code>1990..2010</code>. В начале программы выполним инициализацию элементов массива,
положив их значения равными <code>0</code>
(заметим, что если после обработки исходных данных некоторые элементы массива <code>year</code>
останутся нулевыми, то это будет означать, что соответствующие годы не были представлены в наборе исходных данных,
и выводить информацию о них не следует).
</p>
<p>После инициализации массива следует прочесть информацию о количестве абитуриентов и организовать цикл,
в котором будут обрабатываться данные о каждом абитуриенте и соответствующим образом корректироваться
элементы массива <code>year</code>. В дальнейшем сведения об уже обработанном абитуриенте нам не будут нужны, поэтому сохранять
их в специальном наборе данных (например, массиве) не требуется. Заметим также, что фамилия абитуриента
для решения задачи не требуется, поэтому после чтения двух числовых данных можно сразу переходить к новой строке,
пропуская строковый элемент данных (фамилию). В задаче не нужно использовать
и номера школ, однако их придется считывать, так как только после номера школы указывается интересующий
нас год поступления абитуриента.
</p>
<p>Когда данные обо всех абитуриентах будут обработаны,
в массиве <code>year</code> будет содержаться вся необходимая информация, которую останется
вывести в формате, указанном в условии задачи.
</p>
<p>Приведем первый вариант решения (этот вариант содержит одну ошибку):
</p>
<blockquote><code><pre><b>uses</b> PT4Exam;
<b>var</b>
n, i, k, m: integer;
year: array[1990..2010] of integer;
<b>begin</b>
Task('ExamTaskC25');
<b>for</b> i := 1990 <b>to</b> 2010 <b>do</b>
year[i] := 0;
readln(n);
<b>for</b> i := 1 <b>to</b> n <b>do</b>
<b>begin</b>
readln(k, m); <i>{ k - номер школы, m - год поступления }</i>
Inc(year[m]);
<b>end</b>;
<b>for</b> i := 1990 <b>to</b> 2010 <b>do</b>
writeln(i, ' ', year[i]);
<b>end</b>.
</pre></code></blockquote>
<p>Ошибка связана с тем, что на экран выводится информация о годах, отсутствующих в наборе исходных данных.
Поэтому она сразу будет выявлена при обработке наборов данных небольшого размера,
предлагаемых программе при первом тестовом запуске
(для большей наглядности приведем окно задачника в режиме сокращенного отображения данных, при котором
выводятся только пять первых элементов из каждого набора данных):
</p>
<blockquote>
<img border="0" src="gif/ExamTaskC25-2.png">
</blockquote>
<p>Для исправления ошибки достаточно добавить в последний цикл условный оператор:
</p>
<blockquote><code><pre><b>for</b> i := 1990 <b>to</b> 2010 <b>do</b>
<b>if</b> year[i] > 0 <b>then</b>
writeln(i, ' ', year[i]);
</pre></code></blockquote>
<p>Теперь все 9 тестовых испытаний программы, требуемых для того, чтобы решение было зачтено как выполненное,
будут пройдены успешно.
</p>
<a name="scroll"></a><p>Завершая рассмотрение этого задания, опишем некоторые дополнительные возможности, связанные
с просмотром больших наборов данных.
</p>
<p>Начиная со второго испытания,
программе может быть предложен для обработки набор исходных данных большего размера (порядка 50&#150;100
элементов). При этом уже не удастся отобразить на экране все данные, связанные с заданием.
В подобной ситуации у правой границы окна задачника появится <i>полоса прокрутки</i>, позволяющая
перемещаться к той части данных, которая первоначально не отображается на экране.
Прокрутку данных можно выполнять не только с помощью полосы прокрутки, но и используя
клавиши со стрелками, <b>PgUp</b>, <b>PgDn</b>, <b>Home</b>, <b>End</b>, а также колесико мыши.
</p>
<p>Помимо стандартных действий по прокрутке данных, в окне задачника предусмотрены возможности
&laquo;интеллектуальной&raquo; прокрутки,
позволяющие быстро перейти к началу каждого раздела задания, а также сравнить соответствующие фрагменты
полученных результатов и примера верного решения. Для циклического перебора разделов сверху вниз
предназначена клавиша <b>[+]</b> (а также комбинация <b>Ctrl+PgDn</b>), для циклического перебора разделов снизу вверх
&#151; клавиша <b>[&#150;]</b> (а также комбинация <b>Ctrl+PgUp</b>). Для быстрого переключения между
соответствующими фрагментами разделов с результатами и с примером верного решения предназначена клавиша <b>[/]</b>
(а также комбинация <b>Ctrl+Tab</b>). Все эти действия можно выполнить и с помощью мыши; для этого
предусмотрены кнопки в левом верхнем углу прокручиваемой области окна, отведенной под отображение разделов задания
(эти кнопки отображаются
на экране, если размер данных, связанных с заданием, превышает размеры окна).
Приведем вид окна задачника с полосой прокрутки и дополнительными кнопками:
</p>
<blockquote>
<img border="0" src="gif/ExamTaskC25-3.png">
</blockquote>
<p>Обозначения на кнопках совпадают с клавишами,
выполняющими те же действия; при наведении мышью на кнопку рядом с ней появляется всплывающая подсказка.
</p>
<p>Кроме трех кнопок, связанных с &laquo;интеллектуальной&raquo; прокруткой,
в приведенном на рисунке окне отображаются еще две дополнительные кнопки.
Первая из них располагается в правом верхнем углу раздела с формулировкой
и позволяет временно скрыть (а в дальнейшем опять отобразить)
раздел с формулировкой (эти же действия можно выполнить с помощью клавиши <b>Del</b> или щелчка мышью
на разделе с формулировкой).
Вторая дополнительная кнопка расположена в правом верхнем углу раздела с исходными данными.
Как уже отмечалось ранее, эта кнопка позволяет переключаться между полным
и сокращенным отображением наборов данных. Напомним, что
изображение на этой кнопке показывает текущий режим отображения данных. Например, если на кнопке изображена
стилизованная стрелка, направленная вверх (как на приведенном выше рисунке),
значит, в данный момент в окне отображаются все данные, а нажатие на эту кнопку переведет окно
в режим отображения нескольких начальных (как правило, пяти) элементов каждого набора данных.
</p>
<p>Дополнительная информация о возможностях
режима окна с динамической компоновкой приведена в <a href="../PT4/window.html#dynmode">соответствующем разделе</a>
страницы, посвященной описанию окна задачника.
</p>
<hr>
<h2>Пример 4. Более сложное задание на обработку наборов данных
</h2>
<hr>
<p class="task">ExamTaskC53&#176;. На вход подаются сведения о ценах на бензин на автозаправочных станциях (АЗС).
В первой строке содержится значение&nbsp;<i>M</i> одной из марок бензина, во второй строке указывается
целое число&nbsp;<i>N</i>, а каждая из последующих <i>N</i>&nbsp;строк имеет формат<br>
<tt>&lt;Марка бензина&gt; &lt;Улица&gt; &lt;Компания&gt; &lt;Цена 1 литра (в копейках)&gt;</tt><br>
Имеется не более 20 различных компаний и не более 30 различных улиц; названия компаний и улиц
не содержат пробелов. В качестве марки бензина указываются числа 92, 95 или 98. Цена задается целым числом
в диапазоне от&nbsp;2000 до&nbsp;3000. Каждая компания имеет не более одной АЗС на каждой улице;
цены на разных АЗС одной и той же компании могут различаться. Для каждой улицы, на которой имеются
АЗС с бензином марки&nbsp;<i>M</i>, определить максимальную цену бензина этой марки (вначале выводить максимальную
цену, затем название улицы). Сведения о каждой улице выводить на новой строке и упорядочивать
по возрастанию максимальной цены, а для одинаковой цены &#8212; по названиям улиц в алфавитном порядке.
Если ни одной АЗС с бензином марки&nbsp;<i>M</i> не найдено, то вывести текст &#171;Нет&#187;.
</p>
<p>Приведем окно задачника, которое появится на экране при запуске программы-заготовки для данного задания
(в данном окне скрыт раздел с формулировкой; в результате оказались скрытыми и кнопки,
отвечающие за &laquo;интеллектуальную&raquo; прокрутку, поскольку в окне полностью отображается
содержимое оставшихся разделов):
</p>
<blockquote>
<img border="0" src="gif/ExamTaskC53-1.png">
</blockquote>
<p>Выясним, какая структура является наиболее подходящей для хранения информации, необходимой для решения задачи.
Нам требуется информация, связанная с различными улицами, которых по условию не более 30, причем для каждой улицы
надо хранить сведения двух видов: ее название и максимальную цену бензина марки <i>M</i>. Поэтому мы можем либо завести
массив из 30 элементов-записей с двумя полями, либо два массива: один содержащий названия улиц, а другой &#151;
максимальные цены. Учитывая, что в конце программы нам потребуется выполнять сортировку полученных данных,
целесообразнее использовать массив записей, поскольку это позволит записать алгоритм сортировки
в более компактной форме.
</p>
<p>Определим запись <code>Street</code> с двумя полями <code>name</code> и <code>max</code> и опишем массив <code>s</code>
из 30 элементов типа <code>Street</code>.
Следует также завести переменную <code>ns</code>, в которой будет храниться количество заполненных элементов массива <code>s</code>.
</p>
<p>При обработке каждой строки с исходными данными нам будут нужны прежде всего сведения о марке бензина.
Если марка бензина не равна <code>M</code>, то оставшуюся часть строки обрабатывать не требуется, и можно сразу перейти
к разбору следующей строки. Если марка бензина равна <code>M</code>, то необходимо узнать название улицы <code>s0</code> и цену бензина <code>p</code>.
Заметим, что название компании для решения задачи не требуется, однако его необходимо прочесть, чтобы определить
следующий элемент данных &#151; цену бензина.
</p>
<p>Если улица с названием <code>s0</code> еще не была включена в массив <code>s</code>, то ее необходимо включить в массив, присвоив
полю <code>max</code> значение <code>p</code>. Если же улица уже присутствует в массиве, то необходимо сравнить поле <code>max</code> для данной улицы
и значение <code>p</code>, изменив при необходимости поле <code>max</code> (здесь мы используем базовый алгоритм нахождения
максимального значения).
</p>
<p>Для ввода названий улиц и компаний в нашем случае удобно организовать <i>посимвольное</i> чтение строковых данных;
признаком завершения такого чтения будет обнаружение пробельного символа.
</p>
<p>После обработки набора исходных данных необходимо проверить, найдена ли хотя бы одна улица с АЗС,
предлагающей марку бензина <code>M</code> (для этого достаточно сравнить значение <code>ns</code> с нулем). Если ни одна улица
не найдена, то надо вывести строку &laquo;Нет&raquo;; в противном случае требуется выполнить сортировку
массива <code>s</code> по указанному набору ключей и вывести полученные данные в требуемом порядке. Поскольку размер
массива невелик, для его сортировки вполне допустимо использовать один из простых алгоритмов,
например, алгоритм <i>пузырьковой сортировки</i>.
</p>
<p>Приведем один из вариантов правильного решения задачи:
</p>
<blockquote><code><pre><b>uses</b> PT4Exam;
<b>type</b>
Street = <b>record</b>
name: string;
max: integer;
<b>end</b>;
<b>var</b>
m, n, ns, i, j, k, p: integer;
s: array[1..30] of Street;
s0: string;
x: Street;
c: char;
<b>begin</b>
Task('ExamTaskC53');
readln(m); <i>{ m - марка бензина }</i>
readln(n);
ns := 0;
<b>for</b> i := 1 <b>to</b> n <b>do</b>
<b>begin</b>
read(k);
<b>if</b> k &lt;&gt; m <b>then</b>
readln <i>{ пропускаем оставшуюся часть строки }</i>
<b>else</b>
<b>begin</b>
s0 := '';
read(c); <i>{ пропускаем пробел после первого числа }</i>
read(c); <i>{ читаем первый символ названия улицы }</i>
<b>while</b> c &lt;&gt; ' ' <b>do</b>
<b>begin</b>
s0 := s0 + c;
read(c);
<b>end</b>;
read(c); <i>{ читаем первый символ названия компании }</i>
<b>while</b> c &lt;&gt; ' ' <b>do</b>
read(c); <i>{ название компании не сохраняем }</i>
readln(p); <i>{ читаем цену бензина и переходим на новую строку }</i>
<i>{ Обработка прочитанной информации }</i>
k := 0;
<b>for</b> j := 1 <b>to</b> ns <b>do</b>
<b>if</b> s[j].name = s0 <b>then</b> <i>{ улица уже содержится в массиве s }</i>
<b>begin</b>
k := 1;
<b>if</b> s[j].max &lt; p <b>then</b>
s[j].max := p;
break;
<b>end</b>;
<b>if</b> k = 0 <b>then</b> <i>{ улица еще не содержится в массиве s }</i>
<b>begin</b>
Inc(ns);
s[ns].name := s0;
s[ns].max := p;
<b>end</b>;
<b>end</b>;
<b>end</b>;
<b>if</b> ns = 0 <b>then</b> <i>{ ни одной улицы не найдено }</i>
writeln('Нет')
<b>else</b>
<b>begin</b>
<i>{ Сортировка по возрастанию максимальной цены,</i>
<i> а для одинаковых цен - по названиям улиц }</i>
<b>for</b> k := 1 <b>to</b> ns - 1 <b>do</b>
<b>for</b> i := 1 <b>to</b> ns - k <b>do</b>
<b>if</b> (s[i].max &gt; s[i + 1].max) <b>or</b>
(s[i].max = s[i + 1].max) <b>and</b>
(s[i].name &gt; s[i + 1].name) <b>then</b>
<b>begin</b>
x := s[i];
s[i] := s[i + 1];
s[i + 1] := x;
<b>end</b>;
<i>{ Вывод результатов в требуемом порядке }</i>
<b>for</b> i := 1 <b>to</b> ns <b>do</b>
writeln(s[i].max,' ',s[i].name);
<b>end</b>;
<b>end</b>.
</pre></code></blockquote>

View file

@ -0,0 +1,343 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title></title>
<link rel="StyleSheet" href="../../default.css">
</head>
<body>
<H1>Задание на обработку файлов</H1>
<hr>
<h3>Создание программы-заготовки и знакомство с заданием</h3>
<p>В качестве примера задания на обработку файлов рассмотрим задание File48.</p>
<p>Напомним, что программу-заготовку для решения этого задания можно создать с помощью
команды
меню &laquo;Модули | Создать шаблон программы&raquo;, кнопки
<img border="0" src="gif/Load.gif" width="16" height="17"> или клавиатурной
комбинации <b>Shift+Ctrl+L</b>. Эта заготовка будет иметь следующий вид:
</p>
<blockquote>
<code><pre>
<b>uses</b> PT4;
<b>begin</b>
Task('File48');
<b>end</b>.</pre></code>
</blockquote>
<p>После запуска данной программы на экране появится <a href="../PT4/window.html">окно задачника</a>:</p>
<blockquote>
<img border="0" src="gif/file48-1.png">
</blockquote>
<p>В первой строке раздела исходных данных указаны имена трех исходных файлов (S<sub>A</sub>, S<sub>B</sub>
и S<sub>C</sub>) и одного результирующего (S<sub>D</sub>). В последующих строках раздела исходных данных
показано содержимое исходных файлов.
Элементы файлов отображаются бирюзовым цветом, чтобы подчеркнуть их отличие от обычных исходных данных (желтого цвета)
и комментариев (светло-серого цвета).</p>
<p>Поскольку размер файлов, как правило, превышает количество элементов,
которое может уместиться на одной экранной строке,
для отображения содержимого файла может отводиться
более одной экранной строки. Слева от каждой строки с содержимым файла указывается порядковый номер
файлового элемента, значение которого указано первым в этой строке (элементы нумеруются от 1).</p>
<p>Запуск нашей программы признан <i>ознакомительным</i> (и поэтому правильность решения не анализировалась),
так как в ходе ее выполнения не было введено ни одного элемента исходных данных.
При ознакомительном запуске раздел результатов не отображается, однако приводится
<i>пример верного решения</i>, т.&nbsp;е. те числа,
которые должны содержаться в результирующем файле при правильной обработке исходных файлов.</p>
</p>
<hr>
<h3>Ввод части исходных данных</h3>
<p>Добавим в программу фрагмент, позволяющий ввести имена исходных файлов и связать с этими файлами соответствующие
файловые переменные. Поскольку мы собираемся работать с четырьмя файлами одного типа, удобно предусмотреть <i>массив</i>
для хранения всех файловых переменных:</p>
<blockquote>
<code><pre>
<b>uses</b> PT4;
<b>var</b>
i: integer;
s: string;
f: <b>array </b>[1..4] <b>of</b> <b>file</b> <b>of</b> integer;
<b>begin</b>
Task('File48');
<b>for</b> i := 1 <b>to</b> 3 <b>do</b>
<b>begin</b>
read(s);
Assign(f[i], s);
<b>end</b>;
<b>end</b>. </pre></code>
</blockquote>
<p>Мы намеренно ограничились <i>тремя</i> итерациями цикла, оставив непрочитанным имя результирующего файла.
Считывание имен файлов производится в одну и ту же переменную <code>s</code>, поскольку после связывания файла,
имеющего имя <code>s</code>,
с соответствующей файловой переменной (процедурой <code>Assign</code>) все остальные действия
с данным файлом в нашей программе
будут осуществляться с использованием файловой переменной, без обращения к имени файла.</p>
<p>Запуск нового варианта программы уже не будет считаться ознакомительным, поскольку в программе
выполняется ввод исходных данных. Так как имя результирующего файла осталось непрочитанным, этот вариант
решения будет признан неверным и приведет к сообщению &laquo;<i>Введены не все требуемые исходные данные</i>&raquo;:</p>
<blockquote>
<img border="0" src="gif/file48-2.png">
</blockquote>
<p>При этом на экране появится раздел результатов (кроме комментария он пока ничего не содержит),
а также панель индикаторов. Первый из индикаторов
(индикатор ввода) показывает
количество введенных исходных данных. Обратите внимание на то, что второй индикатор
(индикатор вывода) является неактивным: он выделяется серым цветом более светлого
оттенка и не содержит текстового заголовка.
Это объясняется тем, что индикатор вывода показывает количество результирующих данных,
полученных задачником от программы, а в нашем случае программа
не должна передавать задачнику никакие данные; вместо этого ей необходимо создать файл и заполнить его
требуемыми значениями. Для заданий подобного типа (обычно это задания, связанные с обработкой файлов)
индикатор вывода не используется.
</p>
<hr>
<h3>Ввод всех исходных данных без создания требуемого файла</h3>
<p>Изменим программу, заменив в заголовке цикла число <code>3</code> на <code>4</code>, и вновь запустим программу. Теперь все данные,
необходимые для выполнения задания, введены в программу (это видно по индикатору ввода). Однако задание не выполнено, поскольку результирующий файл
не создан. Поэтому решение опять признано ошибочным с диагностикой &laquo;<i>Результирующий файл не найден</i>&raquo;:</p>
<blockquote>
<img border="0" src="gif/file48-3.png">
</blockquote>
<hr>
<h3>Пример программы, приводящей к ошибке времени выполнения</h3>
<p>Добавим в тело цикла после процедуры <code>Assign</code> вызов процедуры <code>Reset</code>, обеспечивающий открытие существующего файла:</p>
<blockquote>
<code><pre>
<b>uses</b> PT4;
<b>var</b>
i: integer;
s: string;
f: <b>array </b>[1..4] <b>of</b> <b>file</b> <b>of</b> integer;
<b>begin</b>
Task('File48');
<b>for</b> i := 1 <b>to</b> 4 <b>do</b>
<b>begin</b>
read(s);
Assign(f[i], s);
Reset(f[i]);
<b>end</b>;
<b>end</b>. </pre></code>
</blockquote>
<p>Теперь запуск программы приведет к сообщению об ошибке &laquo;<i>Error System.IO.FileNotFoundException</i>&raquo;:</p>
<blockquote>
<img border="0" src="gif/file48-4.png">
</blockquote>
<p>Сообщение, начинающееся со слова <i>Error</i>, означает, что при работе программы произошла <i>ошибка времени выполнения</i>
(Runtime Error). После слова <i>Error</i> указывается имя этой ошибки (в данном случае <i>System.IO.FileNotFoundException</i>,
то есть ошибка ввода-вывода, связанная с тем, что файл не найден)
и краткое ее описание на английском языке.</p>
<p>Сообщение об ошибке времени выполнения появится и в разделе &laquo;Список ошибок&raquo;
окна <b>PascalABC.NET</b>:</p>
<blockquote>
<img border="0" src="gif/file48-5.png">
</blockquote>
<hr>
<h3>Создание пустого результирующего файла</h3>
<p>Для того чтобы избежать ошибки времени выполнения, отсутствующий файл результатов следует открыть
не процедурой <code>Reset</code>, а процедурой <code>Rewrite</code>, которая
и обеспечит создание этого файла. Далее, после завершения работы с файлами, открытыми в программе,
их необходимо закрыть процедурой <code>Close</code>. Добавим в программу соответствующие операторы:</p>
<blockquote>
<code><pre>
<b>uses</b> PT4;
<b>var</b>
i: integer;
s: string;
f: <b>array </b>[1..4] <b>of file of</b> integer;
<b>begin</b>
Task('File48');
<b>for</b> i := 1 <b>to</b> 4 <b>do</b>
<b>begin</b>
read(s);
Assign(f[i], s);
<b>if</b> i &lt; 4 <b>then</b> Reset(f[i])
<b>else</b> Rewrite(f[i]);
<b>end</b>;
{ * }
<b>for</b> i := 1 <b>to</b> 4 <b>do</b>
Close(f[i]);
<b>end</b>. </pre></code>
</blockquote>
<p>Комментарий <code>{ * }</code> расположен в том месте программы, в котором можно выполнять операции ввода-вывода для всех
четырех файлов: они уже открыты процедурами <code>Reset</code> или <code>Rewrite</code> и еще не закрыты процедурой <code>Close</code>.</p>
<p>Запуск этого варианта программы не приведет к ошибке времени выполнения; более того, результирующий файл будет создан.
Однако созданный файл останется пустым, то есть не содержащим ни одного элемента. Поэтому при запуске программы
на информационной панели появится сообщение &laquo;<i>Ошибочное решение</i>&raquo;,
а в строке, которая должна содержать элементы результирующего файла, появится текст <code>EOF:</code> (особое значение EOF для
указателя текущей файловой позиции означает, что данный файл существует, но не содержит ни одного элемента):</p>
<blockquote>
<img border="0" src="gif/file48-6.png">
</blockquote>
<hr>
<h3>Пример программы, использующей неправильные типы для файловых данных</h3>
<p>Во всех ранее рассмотренных вариантах программы мы не использовали операции ввода-вывода для файлов.
Поэтому тип файлов не играл никакой роли: вместо типа <code><b>file of</b> integer</code> мы могли использовать любой другой файловый тип,
например, <code><b>file of</b> real</code>, и результат выполнения программы был бы тем же самым.</p>
<p>Тип файловых элементов становится принципиально важным, если в программе используются операции ввода-вывода
для данного файла. Чтобы продемонстрировать это на примере нашей программы, внесем в нее следующие изменения:
в описании массива <code>f</code> файловых переменных тип <code>integer</code> заменим на <code>real</code>, в раздел описаний добавим описание
переменной <code>a</code> типа <code>real</code>, в раздел операторов (в позицию, помеченную комментарием <code>{ * }</code>)
добавим следующий фрагмент:</p>
<blockquote>
<code><pre>
<b>for</b> i := 1 <b>to</b> 3 <b>do</b>
<b>begin</b>
read(f[i], a);
write(f[4], a);
<b>end</b>;
</pre></code>
</blockquote>
<p>Данный фрагмент обеспечивает считывание <i>одного</i> элемента для каждого из трех исходных файлов
и запись этих элементов в результирующий файл (в требуемом порядке). Подчеркнем, что мы <i>неправильно</i> указали
типы файлов; тем не менее, компиляция программы пройдет успешно, а после ее запуска не произойдет
ошибок времени выполнения.</p>
<p>Результат работы программы будет неожиданным:</p>
<blockquote>
<img border="0" src="gif/file48-7.png">
</blockquote>
<p>Судя по экранной строке с содержимым результирующего файла, в него будут записаны не три, а <i>шесть элементов</i>,
по два начальных элемента из каждого исходного файла. Объясняется это тем, что после связывания файлов
с файловыми переменными типа <code><b>file of</b> real</code> элементами файлов стали считаться <i>вещественные числа</i>
(занимающие в памяти по 8 байтов), тогда как &laquo;на самом деле&raquo;, то есть по условию задания, элементами файлов
являются целые числа (занимающие в памяти по 4 байта). Поэтому считывание из файла и последующая запись в файл
одного &laquo;вещественного элемента&raquo; фактически приводит к считыванию и записи блока данных размером 8 байтов,
содержащего <i>два</i> последовательных целочисленных элемента исходного файла.</p>
<p>Итак, мы выяснили, что ошибки, связанные с несоответствием типов файлов, не выявляются при компиляции
и не всегда приводят к ошибкам времени выполнения. Это следует иметь в виду, и при появлении &laquo;странных&raquo;
результирующих данных начинать поиск ошибки с проверки типов файловых переменных.</p>
<hr>
<h3>Исправление ошибки, связанной с неверными типами файловых данных</h3>
<p>Заменим в нашей программе все описания <code>real</code> на <code>integer</code>:</p>
<blockquote>
<code><pre>
<b>uses</b> PT4;
<b>var</b>
i: integer;
s: string;
f: <b>array </b>[1..4] <b>of file of</b> integer;
a: integer;
<b>begin</b>
Task('File48');
<b>for</b> i := 1 <b>to</b> 4 <b>do</b>
<b>begin</b>
read(s);
Assign(f[i], s);
<b>if</b> i &lt; 4 <b>then</b> Reset(f[i])
<b>else</b> Rewrite(f[i]);
<b>end</b>;
<b>for</b> i := 1 <b>to</b> 3 <b>do</b>
<b>begin</b>
read(f[i], a);
write(f[4], a);
<b>end</b>;
<b>for</b> i := 1 <b>to</b> 4 <b>do</b>
Close(f[i]);
<b>end</b>. </pre></code>
</blockquote>
<p>Мы получим все еще неверное, но вполне &laquo;понятное&raquo; решение: первые три элемента результирующего файла
совпадают с контрольными (то есть &laquo;правильными&raquo;), а прочие элементы отсутствуют:</p>
<blockquote>
<img border="0" src="gif/file48-8.png">
</blockquote>
<hr>
<h3>Верное решение</h3>
<p>Приведем, наконец, верное решение задания
<code>File48</code>:</p>
<blockquote>
<code><pre>
<b>uses</b> PT4;
<b>var</b>
i, a: integer;
s: string;
f: <b>array </b>[1..4] <b>of file of</b> integer;
<b>begin</b>
Task('File48');
<b>for</b> i := 1 <b>to</b> 4 <b>do</b>
<b>begin</b>
read(s);
Assign(f[i], s);
<b>if</b> i &lt; 4 <b>then</b> Reset(f[i])
<b>else</b> Rewrite(f[i]);
<b>end</b>;
<b>while</b> <b>not</b> Eof(f[1]) <b>do</b>
<b>for</b> i := 1 <b>to</b> 3 <b>do</b>
<b>begin</b>
read(f[i], a);
write(f[4], a);
<b>end</b>;
<b>for</b> i := 1 <b>to</b> 4 <b>do</b>
Close(f[i]);
<b>end</b>. </pre></code>
</blockquote>
<p>От предыдущего варианта данное решение отличается добавлением заголовка цикла <code><b>while not</b> Eof(f[1]) <b>do</b></code>,
который обеспечивает считывание всех элементов из исходных файлов (напомним, что по условию задания все исходные
файлы имеют <i>одинаковый размер</i>) и запись их в результирующий файл в нужном порядке.
После запуска этого варианта мы получим сообщение &laquo;<i>Верное решение. Тест номер 1 (из 5)</i>&raquo;,
а после пяти подобных запусков &#151; сообщение &laquo;<i>Задание выполнено!</i>&raquo;:</p>
<blockquote>
<img border="0" src="gif/file48-9.png">
</blockquote>
<hr>
<h3>Просмотр результатов выполнения задания</h3>
<p>Щелкнув мышью на метке &laquo;Результаты (F2)&raquo;, расположенной в правом верхнем
углу окна задачника, или нажав клавишу <b>F2</b>, мы можем вывести на экран <i>окно результатов</i>,
в котором будет перечислены все наши попытки решения задачи:</p>
<blockquote>
<code><pre>
File48 a08/09 12:43 Ознакомительный запуск.
File48 a08/09 12:50 Введены не все требуемые исходные данные.
File48 a08/09 12:52 Результирующий файл не найден.
File48 a08/09 12:53 Error System.IO.FileNotFoundException.
File48 a08/09 12:57 Ошибочное решение.--3
File48 a08/09 13:06 Задание выполнено!
</pre></code>
</blockquote>
<p>Для закрытия окна результатов достаточно нажать клавишу <b>Esc</b>.
Окно результатов можно отобразить на экране и после закрытия окна задачника и возврата в среду PascalABC.NET.
Для этого надо использовать команду меню &laquo;Модули | Просмотреть результаты&raquo;, кнопку
<img border="0" src="gif/Results.gif" width="16" height="17"> или клавиатурную
комбинацию <b>Shift+Ctrl+R</b>.
</p>
</body>
</html>

View file

@ -0,0 +1,535 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title></title>
<link rel="StyleSheet" href="../../default.css">
</head>
<body>
<H1>Задания на указатели и динамические структуры данных</H1>
<hr>
<H2>Пример 1. Анализ существующей динамической структуры</H2>
<hr>
<p>В заданиях группы Dynamic мы встречаемся с двумя новыми видами данных: это <i>динамические структуры</i>,
реализованные в виде цепочек связанных друг
с другом записей типа <code>TNode</code>, и <i>указатели</i> типа <code>PNode</code> на записи <code>TNode</code>:
<code>PNode&nbsp;=&nbsp;^TNode</code>. Типы <code>TNode</code> и <code>PNode</code> не являются стандартными типами языка Паскаль;
они определены в задачнике Programming Taskbook следующим образом (приводятся только те поля записи <code>TNode</code>, которые
используются при выполнении заданий группы Dynamic):</p>
<blockquote>
<code><pre>
<b>type</b>
PNode = ^TNode;
TNode = <b>record</b>
Data: integer;
Next: PNode;
Prev: PNode;
. . .
<b>end</b>;
</pre></code>
</blockquote>
<p>На примере задания Dynamic2 рассмотрим особенности, связанные с
использованием этих новых типов данных.</p>
<hr>
<h3>Создание программы-заготовки и знакомство с заданием</h3>
<p>Программа-заготовка для задания Dynamic2, созданная с помощью команды
меню &laquo;Модули | Создать шаблон программы&raquo;, кнопки
<img border="0" src="gif/Load.gif" width="16" height="17"> или клавиатурной
комбинации <b>Shift+Ctrl+L</b>, имеет следующий вид:</p>
<blockquote>
<code><pre>
<b>uses</b> PT4;
<b>begin</b>
Task('Dynamic2');
<b>end</b>.
</pre></code>
</blockquote>
<p>После запуска данной программы на экране появится <a href="../PT4/window.html">окно задачника</a>:</p>
<blockquote>
<img border="0" src="gif/Dynamic2-1.png">
</blockquote>
<p>Это окно содержит в качестве исходных и результирующих данных новые элементы: динамические структуры и указатели.</p>
<p>Начнем с описания того, как отображается на экране <i>динамическая структура</i>. Для ее вывода используются две
экранные строки; в первой строке отображаются имена указателей, связанных с данной структурой,
а во второй &#151; содержимое элементов этой структуры, то есть значения их полей <code>Data</code> и способ связи
между ними. Вся информация о динамической структуре отображается бирюзовым цветом (подобно информации об элементах файлов).</p>
<p>Рассмотрим в качестве примера динамическую структуру, указанную на рисунке:</p>
<blockquote>
<code><pre>
P<sub>1</sub>
75 - 65 - 22 - 26 - 10 >nil
</pre></code>
</blockquote>
<p>Этот текст означает, что структура состоит из 5 элементов, причем ее первый элемент имеет поле <code>Data</code>,
равное 75, и связан с помощью своего поля <code>Next</code> со вторым элементом, поле <code>Data</code>
которого равно 65, и так далее до последнего, пятого элемента, поле <code>Data</code> которого равно 10,
а поле <code>Next</code> равно <code>nil</code>, что является признаком завершения структуры.
Таким образом, текст, описывающий данную динамическую структуру, является максимально упрощенным вариантом
следующей схемы:</p>
<blockquote>
<img border="0" src="gif/Dynamic2-2.png">
</blockquote>
<p>Поскольку эта структура указана в разделе исходных данных, следовательно, после инициализации задания
она <i>уже существует</i> и размещается в некоторой области динамической памяти (подобно тому, как исходные файлы
после инициализации задания размещаются в каталоге учащегося).</p>
<p>Как получить доступ к этой существующей динамической структуре? Здесь также уместна аналогия с файлами.
Для доступа к внешнему файлу необходимо знать его <i>имя</i>, и в любом задании на обработку файлов
имена исходных файлов входят в набор исходных данных. Для доступа к данным,
размещенным в динамической памяти, необходимо знать их <i>адрес</i>, и поэтому в любом задании на
обработку динамических структур в набор исходных данных входят <i>указатели</i>, содержащие адреса этих структур.</p>
<p>Из текста, описывающего динамическую структуру, видно, что на ее первый элемент указывает указатель
с именем <code>P<sub>1</sub></code>, который также содержится в наборе исходных данных. Описание этого указателя имеет вид</p>
<blockquote>
<code><pre>
P<sub>1</sub> = ptr
</pre></code>
</blockquote>
<p>Здесь текст <code>P<sub>1</sub> =</code> является <i>комментарием</i> и выделяется, как обычный комментарий,
светло-серым цветом, а текст <code>ptr</code> означает, что этот элемент исходных данных является <i>указателем</i>,
который надо ввести в программу с помощью процедуры ввода <code>read</code>.</p>
<p><b>Замечание.</b> Может возникнуть вопрос: почему вместо условного текста &laquo;ptr&raquo; не отображается &laquo;настоящее&raquo; значение указателя
(то есть некоторый четырехбайтный адрес)? Это связано с тем, что, даже выведя это значение на экран,
мы не сможем определить, с какими данными связан этот адрес, поэтому подобная информация на экране будет излишней.</p>
<p>Итак, слово <code>ptr</code> в разделе исходных или результирующих данных означает, что соответствующий элемент данных
является <i>указателем</i>, причем непустым (для пустого указателя используется слово <code><b>nil</b></code>).
Определить, с каким элементом динамической структуры данных связан непустой указатель, можно по экранной
информации об этой динамической структуре.
Разумеется, при чтении указателя программа учащегося получит &laquo;настоящий&raquo; адрес, с помощью которого она сможет
обратиться к исходной динамической структуре.</p>
<p>Аналогично, создав (или преобразовав) некоторую динамическую
структуру, программа учащегося должна передать задачнику некоторый адрес,
связанный в этой структурой (используя процедуру вывода <code>write</code>).
Зная этот адрес, задачник сможет проверить правильность созданной структуры.</p>
<hr>
<h3>Приступаем к решению</h3>
<p>Вернемся к заданию
Dynamic2. В нем не требуется ни создавать, ни преобразовывать исходную структуру данных;
ее необходимо лишь проанализировать,
а именно, определить значения всех ее элементов, подсчитать количество элементов и, кроме того,
вывести указатель на последний элемент этой структуры.</p>
<p>Приведем вначале неполное решение задачи, выводящее все необходимые данные, кроме указателя на последний элемент:</p>
<blockquote>
<code><pre>
<b>uses</b> PT4;
<b>var</b>
p1: PNode;
n: integer;
<b>begin</b>
Task('Dynamic2');
read(p1);
n := 0;
<b>while</b> p1 &lt;&gt; nil <b>do</b>
<b>begin</b>
write(p1^.Data);
n := n + 1;
p1 := p1^.Next;
<b>end</b>;
write(n);
<b>end</b>.
</pre></code>
</blockquote>
<p>После запуска программы можно убедиться, что все числовые результирующие данные найдены правильно,
однако из-за того, что не выведен указатель
на последний элемент, решение признано ошибочным с диагностикой &laquo;<i>Выведены не все результирующие данные</i>&raquo;:</p>
<blockquote>
<img border="0" src="gif/Dynamic2-3.png">
</blockquote>
<p>Добавим в конец программы оператор</p>
<blockquote>
<code><pre>
write(p1);
</pre></code>
</blockquote>
<p>После запуска нового варианта программы все требуемые данные будут выведены, однако результирующее значение
указателя будет равно <code>nil</code>. Это связано
с тем, что после завершения цикла <code><b>while</b></code> в переменной <code>p1</code> содержится <i>нулевой указатель</i>,
а не указатель на последний элемент динамической структуры:</p>
<blockquote>
<img border="0" src="gif/Dynamic2-4.png">
</blockquote>
<hr>
<h3>Правильное решение</h3>
<p>Для того чтобы получить правильное решение, опишем вспомогательную переменную <code>p2</code>,
в которой будем сохранять адрес элемента, <i>предшествующего</i> элементу с адресом <code>p1</code>.
После завершения цикла <code><b>while</b></code> в этой переменной будет храниться адрес последнего элемента
динамической структуры:</p>
<blockquote><code><pre>
<b>uses</b> PT4;
<b>var</b>
p1,p2: PNode;
n: integer;
<b>begin</b>
Task('Dynamic2');
read(p1);
n := 0;
<b>while</b> p1 &lt;&gt; nil <b>do</b>
<b>begin</b>
write(p1^.Data);
n := n + 1;
p2 := p1; { сохраняем адрес текущего элемента }
p1 := p1^.Next; { и переходим к следующему элементу }
<b>end</b>;
write(n, p2);
<b>end</b>.
</pre></code></blockquote>
<p>Запустив эту программу три раза, мы получим сообщение &laquo;<i>Задание выполнено!</i>&raquo;:</p>
<blockquote>
<img border="0" src="gif/Dynamic2-5.png">
</blockquote>
<hr>
<H2>Пример 2. Добавление элемента к динамической структуре</H2>
<hr>
<h3>Знакомство с заданием</h3>
<p>Рассмотрим простейшее задание, связанное с добавлением элемента к динамической структуре-стеку:
Dynamic3.</p>
<p>При ознакомительном запуске этого задания мы обнаружим новое обозначение в тексте, описывающем результирующий стек,
а именно, точки, обрамляющие первый элемент стека:</p>
<blockquote>
<img border="0" src="gif/Dynamic3-1.png">
</blockquote>
<p>Точки обозначают элементы динамической структуры, память для которых <i>должна быть выделена программой учащегося</i>
(в отличие от тех элементов, которые размещаются в памяти самим задачником).</p>
<hr>
<h3>Приступаем к решению</h3>
<p>Что произойдет, если динамическая структура будет создана с ошибками? Для того чтобы это выяснить, вернем в программе, решающей задание
Dynamic3, указатель на прежнюю вершину стека, не добавляя к ней новый элемент:</p>
<blockquote><code><pre>
<b>uses</b> PT4;
<b>var</b>
d: integer;
p1: PNode;
<b>begin</b>
Task('Dynamic3');
read(d, p1);
write(p1);
<b>end</b>.
</pre></code></blockquote>
<p>После запуска данной программы окно задачника примет вид:</p>
<blockquote>
<img border="0" src="gif/Dynamic3-2.png">
</blockquote>
<p>Скобки вокруг каждого элемента результирующего стека означают, что эти элементы созданы самим задачником, но <i>располагаются
не на тех позициях, на которых они должны находиться при правильном решении</i>. Действительно, тот элемент,
который в решении является первым, должен (после добавления нового элемента) оказаться вторым и т.&nbsp;д. Итак,
наличие скобок в тексте результирующей динамической структуры означает, что ее элементы располагаются не в том порядке,
который требуется.</p>
<hr>
<h3>Правильное решение</h3>
<p>Для получения правильного решения задания Dynamic3 необходимо явно выделить память для нового элемента,
используя процедуру <code>New</code>, и заполнить поля этого элемента, связав его с текущей вершиной стека
(в результате сам этот элемент станет новой вершиной, адрес которой и следует вывести):</p>
<blockquote><code><pre>
<b>uses</b> PT4;
<b>var</b>
d: integer;
p1, p2: PNode;
<b>begin</b>
Task('Dynamic3');
read(d, p1);
New(p2);
p2^.Data := D;
p2^.Next := p1;
write(p2);
<b>end</b>.
</pre></code></blockquote>
<p>Приведем вид окна задачника при первом запуске этой программы:</p>
<blockquote>
<img border="0" src="gif/Dynamic3-3.png">
</blockquote>
<hr>
<H2>Пример 3. Удаление элемента из динамической структуры</H2>
<hr>
<h3>Знакомство с заданием</h3>
<p>Рассмотрим простейшее задание на удаление элемента из динамической структуры &#151;
Dynamic5.
В нем требуется удалить из стека вершину и вернуть указатель на новую вершину, то есть на элемент,
расположенный непосредственно за удаленным.</p>
<p>Особенность заданий на удаление элементов из динамических структур заключается в том, что удаляемый элемент
необходимо не только &laquo;отсоединить&raquo;
от исходной динамической структуры, но и полностью &laquo;уничтожить&raquo;, то есть <i>освободить память, занимаемую этим элементом</i>.</p>
<p>Для того чтобы напомнить учащемуся о необходимости уничтожения некоторых элементов исходной динамической
структуры, эти элементы выделяются на экране синим цветом меньшей яркости, чем обычные элементы (на рисунке
таким способом выделен элемент 15):</p>
<blockquote>
<img border="0" src="gif/Dynamic5-1.png">
</blockquote>
<hr>
<h3>Приступаем к решению</h3>
<p>Вначале приведем неправильный вариант решения, в котором
не освобождается память, занимаемая удаленным из стека элементом:</p>
<blockquote><code><pre>
<b>uses</b> PT4;
<b>var</b> p1: PNode;
<b>begin</b>
Task('Dynamic5');
read(p1);
write(p1^.Data, p1^.Next);
<b>end</b>.
</pre></code></blockquote>
<p>Несмотря на то что все результирующие данные будут совпадать с контрольными
(то есть текст в разделах &laquo;Полученные результаты&raquo; и &laquo;Пример верного решения&raquo; будет одинаковым), на
информационной панели появится сообщение об ошибке &laquo;<i>Не освобождена динамическая память</i>&raquo;,
а в разделе исходных данных будет выделен красным цветом тот элемент, который требовалось удалить:</p>
<blockquote>
<img border="0" src="gif/Dynamic5-2.png">
</blockquote>
<hr>
<h3>Правильное решение</h3>
<p>Для получения правильного решения достаточно добавить в конец программы оператор вызова
процедуры <code>Dispose</code>, освобождающий память, на которую указывает указатель <code>p1</code>:</p>
<blockquote><code><pre>
<b>uses</b> PT4;
<b>var</b> p1: PNode;
<b>begin</b>
Task('Dynamic5');
read(p1);
write(p1^.Data, p1^.Next);
Dispose(p1);
<b>end</b>.
</pre></code></blockquote>
<p>Приведем вид окна задачника при первом запуске этой программы:</p>
<blockquote>
<img border="0" src="gif/Dynamic5-3.png">
</blockquote>
<hr>
<H2>Пример 4. Двусвязные динамические структуры</H2>
<hr>
<h3>Знакомство с заданием</h3>
<p>Особенности работы с двусвязными динамическими структурами рассмотрим на примере задания
Dynamic30,
в котором требуется преобразовать исходную односвязную структуру в двусвязную. Запустив программу-заготовку,
созданную для этого задания, мы увидим в области исходных данных информацию об &laquo;обычной&raquo; односвязной структуре,
подобной рассмотренным в предыдущих примерах:</p>
<blockquote>
<img border="0" src="gif/Dynamic30-1.png">
</blockquote>
<p>Динамическая структура, приведенная в разделе результатов, имеет две особенности:
во-первых, ее элементы связаны символом <code>=</code>, а во-вторых, перед первым элементом присутствует текст
<code>nil&lt;</code>.</p>
<p>Это означает, что результирующая структура является <i>двусвязной</i>, то есть каждый ее элемент связан не
только с последующим элементом (с помощью поля <code>Next</code>, как в односвязной структуре), но и с
предыдущим элементом (с помощью нового поля <code>Prev</code>), а поле <code>Prev</code> первого элемента имеет
значение <code>nil</code>:</p>
<blockquote>
<img border="0" src="gif/Dynamic30-2.png">
</blockquote>
<hr>
<h3>Приступаем к решению</h3>
<p>Для преобразования исходной односвязной структуры в двусвязную необходимо задать правильные значения для
полей <code>Prev</code> всех элементов структуры, перебирая в цикле пары соседних элементов:</p>
<blockquote><code><pre>
<b>uses</b> PT4;
<b>var</b>
p1, p: PNode;
<b>begin</b>
Task('Dynamic30');
read(p1);
p := p1^.Next;
<b>while</b> p &lt;&gt; nil <b>do</b>
<b>begin</b>
p^.Prev := p1;
p1 := p1^.Next;
p := p^.Next;
<b>end</b>;
write(p1); <i>{ вывод указателя на последний элемент }</i>
<b>end</b>.
</pre></code></blockquote>
<p>В этой программе мы определили поля <code>Prev</code> для всех элементов, кроме первого. Поэтому решение будет считаться ошибочным
(обратите внимание на то, что перед первым элементом полученного списка отсутствует текст <code>nil&lt;</code>):</p>
<blockquote>
<img border="0" src="gif/Dynamic30-3.png">
</blockquote>
<p><b>Замечание.</b> При анализе ошибочного решения часто оказывается полезным и специальное обозначение &laquo;<code>=</code>&raquo; для двойной связи.
Предположим, например, что информация
о результирующей двусвязной структуре, созданной программой, имеет вид:</p>
<blockquote><code><pre>
P<sub>2</sub>
nil&lt; 33 = 64 - 78 = 12 = 51 >nil
</pre></code></blockquote>
<p>Это означает, что между вторым и третьим элементом структуры имеется не двойная, а <i>одинарная</i> связь
(поле <code>Next</code> второго элемента содержит адрес третьего элемента, а поле <code>Prev</code> третьего элемента
<i>не содержит</i> адрес второго).</p>
<hr>
<h3>Правильное решение</h3>
<p>Для получения правильного решения достаточно добавить в программу перед циклом <code>while</code>
следующий оператор:</p>
<blockquote><code><pre>
p1^.Prev := nil;
</pre></code></blockquote>
<p>Приведем вид окна задачника при первом запуске исправленной программы:</p>
<blockquote>
<img border="0" src="gif/Dynamic30-4.png">
</blockquote>
<p><b>Замечание.</b> Для задания Dynamic30 возможен более короткий вариант решения,
в котором не требуется особо обрабатывать первый элемент списка:
</p>
<blockquote><code><pre>
<b>uses</b> PT4;
<b>var</b>
p1, p: PNode;
<b>begin</b>
Task('Dynamic30');
p := nil;
read(p1);
<b>while</b> p1 &lt;&gt; nil <b>do</b>
<b>begin</b>
p1^.Prev := p;
p := p1;
p1 := p1^.Next;
<b>end</b>;
write(p);
<b>end</b>.
</pre></code></blockquote>
<hr>
<H2>Пример 5. Циклические динамические структуры</H2>
<hr>
<h3>Знакомство с заданием</h3>
<p>Динамическая структура называется <i>циклической</i>, если она замкнута в &laquo;кольцо&raquo;, то есть ее последний элемент
связан полем <code>Next</code> с первым (в случае двусвязной структуры требуется также, чтобы ее первый элемент
был связан полем <code>Prev</code>
с последним элементом). Простейшим заданием на циклические структуры является
Dynamic55, в котором требуется
преобразовать обычный двусвязный список
в циклический.</p>
<p>Запустив программу-заготовку для этого задания, мы увидим
на экране изображение двух динамических структур, причем исходная структура является &laquo;обычным&raquo; двусвязным списком,
а результирующая структура &#151; циклическим двусвязным списком:</p>
<blockquote>
<img border="0" src="gif/Dynamic55-1.png">
</blockquote>
<p>Обозначения <code>&lt;&lt; =</code> и <code>= &gt;&gt;</code> позволяют отличить циклический список от обычного
(напомним, что у обычного двусвязного списка поле <code>Prev</code> первого элемента и поле <code>Next</code> последнего
элемента равны <code><b>nil</b></code>).</p>
<p>Таким образом, экранный текст, описывающий циклический двусвязный список, является упрощенным вариантом
следующей схемы:</p>
<blockquote>
<img border="0" src="gif/Dynamic55-2.png">
</blockquote>
<hr>
<h3>Приступаем к решению</h3>
<p>Для решения задания Dynamic55 достаточно найти последний элемент исходного списка и связать его с
первым элементом:</p>
<blockquote><code><pre>
<b>uses</b> PT4;
<b>var</b>
p1, p2: PNode;
<b>begin</b>
Task('Dynamic55');
read(p1);
p2 := p1;
<b>while</b> p2^.Next &lt;&gt; <b>nil</b> <b>do</b>
p2 := p2^.Next;
p2^.Next := p1;
write(p2);
<b>end</b>.
</pre></code></blockquote>
<p>В данном варианте решения мы &laquo;забыли&raquo; о том, что надо связать не только последний элемент с первым,
но и первый с последним (поскольку наш список &#151; двусвязный). Поэтому решение оказалось ошибочным
(обратите внимание на то, что после последнего элемента полученного списка изображена одинарная, а не двойная черта):</p>
<blockquote>
<img border="0" src="gif/Dynamic55-3.png">
</blockquote>
<hr>
<h3>Правильное решение</h3>
<p>Для получения правильного решения достаточно добавить в программу перед процедурой вывода <code>write</code>
следующий оператор:</p>
<blockquote><code><pre>
p1^.Prev := p2;
</pre></code></blockquote>
<p>Приведем вид окна задачника при первом запуске исправленной программы:</p>
<blockquote>
<img border="0" src="gif/Dynamic55-4.png">
</blockquote>
<hr>
<h3>Просмотр результатов выполнения заданий</h3>
<p>Щелкнув мышью на метке &laquo;Результаты (F2)&raquo;, расположенной в правом верхнем
углу окна задачника, или нажав клавишу <b>F2</b>, мы можем вывести на экран <i>окно результатов</i>,
в котором будет перечислены все наши попытки решения задачи:</p>
<blockquote><code><pre>
Dynamic2 a08/09 13:11 Ознакомительный запуск.
Dynamic2 a08/09 13:15 Выведены не все результирующие данные.
Dynamic2 a08/09 13:17 Ошибочное решение.
Dynamic2 a08/09 13:20 Задание выполнено!
Dynamic3 a08/09 13:21 Ознакомительный запуск.
Dynamic3 a08/09 13:24 Ошибочное решение.
Dynamic3 a08/09 13:28 Задание выполнено!
Dynamic5 a08/09 13:29 Ознакомительный запуск.
Dynamic5 a08/09 13:30 Не освобождена динамическая память.
Dynamic5 a08/09 13:31 Задание выполнено!
Dynamic30 a08/09 13:34 Ознакомительный запуск.
Dynamic30 a08/09 13:42 Ошибочное решение.
Dynamic30 a08/09 13:43 Задание выполнено!
Dynamic55 a08/09 13:54 Ознакомительный запуск.
Dynamic55 a08/09 13:57 Ошибочное решение.
Dynamic55 a08/09 13:58 Задание выполнено!
</pre></code></blockquote>
<p>Для закрытия окна результатов достаточно нажать клавишу <b>Esc</b>.
Окно результатов можно отобразить на экране и после закрытия окна задачника и возврата в среду PascalABC.NET.
Для этого надо использовать команду меню &laquo;Модули | Просмотреть результаты&raquo;, кнопку
<img border="0" src="gif/Results.gif" width="16" height="17"> или клавиатурную
комбинацию <b>Shift+Ctrl+R</b>.
</p>
</body>
</html>

View file

@ -0,0 +1,215 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title></title>
<link rel="StyleSheet" href="../../default.css">
</head>
<body>
<H1>Задание на обработку строк</H1>
<hr>
<h3>Создание программы-заготовки и знакомство с заданием</h3>
<p>В качестве примера задания на обработку строк рассмотрим задание String9.</p>
<p>Программу-заготовку для решения этого задания можно создать с помощью
команды
меню &laquo;Модули | Создать шаблон программы&raquo;, кнопки
<img border="0" src="gif/Load.gif" width="16" height="17"> или клавиатурной
комбинации <b>Shift+Ctrl+L</b>. Эта заготовка будет иметь следующий вид:</p>
<blockquote><code><pre>
<b>uses</b> PT4;
<b>begin</b>
Task('String9');
<b>end</b>.
</pre></code></blockquote>
<p>После запуска данной программы на экране появится <a href="../PT4/window.html">окно задачника</a>:</p>
<blockquote>
<img border="0" src="gif/string9-1.png">
</blockquote>
<p>Данные типа <code>char</code> и <code>string</code> в окне задачника заключаются в <i>апострофы</i>; это позволяет, в частности,
отличить числовые данные (например, <code>9</code>) от символьных и строковых данных, содержащих цифры
(например, <code>'9'</code>).
Кроме того, апострофы дают возможность увидеть <i>пробелы</i>, находящиеся в начале или конце строк.
<hr>
<h3>Ввод исходных данных</h3>
<p>Добавим в программу фрагмент, обеспечивающий ввод исходных данных
(мы намеренно ввели данные не в том порядке, в котором они указаны в окне задачника):
</p>
<blockquote>
<code><pre>
<b>uses</b> PT4;
<b>var</b>
n: integer;
c1, c2: char;
<b>begin</b>
Task('String9');
read(c1, c2, n);
<b>end</b>.
</pre></code></blockquote>
<p>Запуск нового варианта программы уже не будет считаться ознакомительным, поскольку в программе
выполняется ввод исходных данных. Так как порядок ввода исходных данных является ошибочным,
этот вариант решения будет признан неверным и приведет к сообщению
&laquo;<i>Неверно указан тип при вводе исходных данных</i>&raquo;:</p>
<blockquote>
<img border="0" src="gif/string9-2.png">
</blockquote>
<p>Общее правило, определяющее порядок ввода и вывода данных для задачника <b>Programming Taskbook</b>
гласит:
<i>ввод и вывод данных производится по строкам (слева направо), а строки просматриваются сверху вниз</i>.
Иными словами,
данные, отображаемые в окне задачника, вводятся и выводятся в том порядке, в котором читается обычный
текст.</p>
<p>На панели индикаторов, расположенной под информационной панелью,
отмечено, что введен всего один элемент исходных данных (из трех), хотя в процедуре <code>read</code> нашей программы
были
указаны три переменные. Это объясняется тем, что при вводе первой из этих переменных (<code>с1</code>)
была обнаружена ошибка несоответствия типа, поэтому задачник не стал анализировать остальные данные,
которые программа пыталась ввести. Здесь проявляется еще одно правило задачника
<b>Programming Taskbook</b>: <i>при обнаружении первой ошибки ввода-вывода
анализ оставшихся исходных данных и результатов не проводится</i>.
</p>
<p>Исправим нашу программу, изменив порядкок параметров в процедуре ввода:</p>
<blockquote>
<code><pre>
read(n, c1, c2);
</pre></code></blockquote>
<p>Теперь с вводом данных проблем не возникает, однако из-за того что в программе отсутствует вывод результирующих
данных, решение по-прежнему считается ошибочным:</p>
<blockquote>
<img border="0" src="gif/string9-3.png">
</blockquote>
<p>Данная ошибка, в отличие от предыдущей, связана не с вводом исходных данных, а с выводом результатов.
Это отмечается в окне задачника двумя способами: цветной маркер ошибки располагается рядом с индикатором вывода,
и этим же цветом выделяется заголовок раздела результатов (который в данном случае не содержит никаких данных).
</p>
<hr>
<h3>Формирование и вывод требуемой строки</h3>
<p>Для формирования нужной строки воспользуемся операцией <code>+</code> (<i>сцепления</i> строк):</p>
<blockquote>
<code><pre>
<b>uses</b> PT4;
<b>var</b>
n, i: integer;
c1, c2: char;
s: string;
<b>begin</b>
Task('String9');
read(n, c1, c2);
s := '';
<b>for</b> i := 1 <b>to</b> n <b>do</b>
s := s + c1 + c2;
write(s);
<b>end</b>.
</pre></code></blockquote>
<p>Заметим, что в операторе <code>s := ''</code> нет необходимости, так как все глобальные переменные в Паскале автоматически
инициализируются &laquo;нулевыми&raquo; значениями (для числовых данных это обычные нули, для символов &#151; это
символ <code>#0</code>, для
строк &#151; пустая строка <code>''</code>).</p>
<p>Результат выполнения этой программы будет следующим:</p>
<blockquote>
<img border="0" src="gif/string9-4.png">
</blockquote>
<p>Красная звездочка, расположенная в конце выведенной строки, означает, что длина полученной строки превышает
длину верной строки. Для того чтобы увидеть на экране всю полученную строку, достаточно подвести курсор мыши
к строке со звездочкой; при этом полный текст строки появится во всплывающей подсказке:</p>
<blockquote>
<img border="0" src="gif/string9-5.png">
</blockquote>
<p><b>Замечание.</b> Красная звездочка может появиться и при выводе ошибочных числовых данных. Например, если ожидается
целое число в диапазоне от <code>1</code> до <code>99</code>, а получено число <code>10000</code>, то на экране изобразится первая цифра этого большого
числа, за которой будет указана красная звездочка: <code>1<font color=red>*</font></code>.</p>
<hr>
<h3>Верное решение</h3>
<p>Ошибка в предыдущей программе возникла из-за неверного указания количества итераций цикла. Действительно,
на каждой итерации к строке добавляется по <i>два</i> символа, поэтому после <code>n</code> итераций
строка будет содержать <code>2*n</code> символов (а не <code>n</code>, как требуется в задании).
<p>Для исправления ошибки достаточно вдвое
уменьшить число итераций:</p>
<blockquote>
<code><pre>
<b>uses</b> PT4;
<b>var</b>
n, i: integer;
c1, c2: char;
s: string;
<b>begin</b>
Task('String9');
read(n, c1, c2);
s := '';
<b>for</b> i := 1 <b>to</b> n <b>div</b> 2 <b>do</b>
s := s + c1 + c2;
write(s);
<b>end</b>.
</pre></code></blockquote>
<p>После запуска этого варианта мы получим сообщение &laquo;<i>Верное решение. Тест номер 1 (из 5)</i>&raquo;,
а после пяти подобных запусков &#151; сообщение &laquo;<i>Задание выполнено!</i>&raquo;:</p>
<blockquote>
<img border="0" src="gif/string9-6.png">
</blockquote>
<p><b>Замечание.</b> Приведем другой, более быстрый, способ решения задания String9,
в котором результирующая строка заполняется <i>посимвольно</i>, как обычный массив:</p>
<blockquote>
<code><pre>
<b>uses</b> PT4;
<b>var</b>
n, i: integer;
c1, c2: char;
s: string;
<b>begin</b>
Task('String9');
read(n, c1, c2);
SetLength(s, n);
<b>for</b> i := 1 <b>to</b> n <b>div</b> 2 <b>do</b>
<b>begin</b>
s[2 * i - 1] := c1;
s[2 * i] := c2;
<b>end</b>;
write(s);
<b>end</b>.
</pre></code></blockquote>
<p>Обратите внимание на процедуру <code>SetLength(s, n)</code>, которая обеспечивает правильную настройку <i>длины</i> результирующей
строки <code>s</code>. Без вызова этой процедуры программа работала бы неверно, так как любая
глобальная строковая переменная инициализируется пустой строкой, а при работе с отдельными символами строки
корректировка ее длины не производится.</p>
<hr>
<h3>Просмотр результатов выполнения задания</h3>
<p>Щелкнув мышью на метке &laquo;Результаты (F2)&raquo;, расположенной в правом верхнем
углу окна задачника, или нажав клавишу <b>F2</b>, мы можем вывести на экран <i>окно результатов</i>,
в котором будет перечислены все наши попытки решения задачи:</p>
<blockquote>
<code><pre>
String9 a08/09 11:17 Ознакомительный запуск.
String9 a08/09 11:18 Неверно указан тип при вводе исходных данных.
String9 a08/09 11:21 Выведены не все результирующие данные.
String9 a08/09 11:26 Ошибочное решение.
String9 a08/09 11:29 Задание выполнено!
</pre></code>
</blockquote>
<p>Для закрытия окна результатов достаточно нажать клавишу <b>Esc</b>.
Окно результатов можно отобразить на экране и после закрытия окна задачника и возврата в среду <b>PascalABC.NET</b>.
Для этого надо использовать команду меню &laquo;Модули | Просмотреть результаты&raquo;, кнопку
<img border="0" src="gif/Results.gif" width="16" height="17"> или клавиатурную
комбинацию <b>Shift+Ctrl+R</b>.
</p>
</body>
</html>

View file

@ -0,0 +1,314 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title></title>
<link rel="StyleSheet" href="../../default.css">
</head>
<body>
<a name="main"></a>
<h1>Задания на обработку деревьев
</h1>
<hr>
<h2>Пример 1. Анализ бинарного дерева
</h2>
<hr>
<p>В заданиях группы Tree, как и в заданиях группы Dynamic, мы встречаемся с двумя новыми видами данных:
это <i>древовидные динамические структуры</i>, реализованные в виде наборов связанных друг с
другом записей типа <code>TNode</code>, и <i>указатели</i> типа <code>PNode</code> на записи <code>TNode</code>: <code>PNode =
^TNode</code>. <a href="..\PT4\IO.html#node">Типы <code>TNode</code> и <code>PNode</code></a> не являются стандартными типами языка Паскаль; они
определены в задачнике Programming Taskbook.
</p>
<p>Особенности, связанные с использованием новых типов данных, рассмотрим на
примере задания Tree2.
</p>
<p class="task">Tree2&#176;.
Дан адрес <i>P</i><sub>1</sub> записи типа TNode &#151; корня дерева.
Эта запись связана полями Left и Right с другими записями того же типа (дочерними вершинами),
они, в свою очередь, &#151; со своими дочерними вершинами, и так далее до записей,
поля Left и Right которых равны nil (у некоторых вершин может быть равно nil одно из полей Left или Right).
Вывести количество вершин дерева.
</p>
<hr>
<h3>Создание программы-заготовки и знакомство с заданием</h3>
<p>Напомним, что программу-заготовку для решения этого задания можно создать с помощью
команды
меню &laquo;Модули | Создать шаблон программы&raquo;, кнопки
<img border="0" src="gif/Load.gif" width="16" height="17"> или клавиатурной
комбинации <b>Shift+Ctrl+L</b>. Приведем текст созданной заготовки:
</p>
<blockquote><code><pre>
<b>uses</b> PT4;
<b>begin</b>
Task('Tree2');
<b>end</b>.
</pre></code></blockquote>
<p>После запуска программы на экране появится <a href="../PT4/window.html">окно задачника</a>:
</p>
<blockquote>
<img border="0" src="gif/Tree2-1.png">
</blockquote>
<p>Это окно содержит в качестве исходных и результирующих данных новые
элементы: бинарные деревья и указатели.
</p>
<p>Начнем с описания того, как отображается на экране <i>дерево</i>. Для его вывода используется
несколько экранных строк. На каждой строке изображаются вершины дерева,
находящиеся на определенном уровне (номер уровня указывается слева от изображения дерева).
Для каждой вершины выводится ее значение, т.&nbsp;е. значение поля Data соответствующей записи типа TNode.
Любая вершина соединяется линиями со своими дочерними вершинами, расположенными на следующем уровне дерева;
левая дочерняя вершина изображается слева от родительской вершины, а правая &#151; справа.
Отсутствие у вершины одной или обеих дочерних вершин означает, что ее поля <code>Left</code> и/или <code>Right</code> равны <code>nil</code>.
</p>
<p>
Рассмотрим в качестве примера дерево, приведенное на рисунке.
Корень этого дерева имеет значение 15, левая дочерняя вершина корня равна 58,
правая дочерняя вершина равна 42, глубина дерева равна 4. Все листья дерева находятся на уровнях
3 и 4; листья на уровне 3 имеют значения 15 и 11, листья на уровне 4 &#151; значения 38 и 84.
Некоторые из внутренних вершин дерева имеют по две
дочерние вершины (это корень и вершины со значениями 55 и 20), некоторые по одной:
левой (вершины 42, 87 и 60) или правой (вершина 58).
</p>
<p>Поскольку это дерево указано в разделе исходных данных, следовательно, после инициализации
задания оно уже существует и размещается в некоторой области динамической памяти.
Для доступа к данным, размещенным в динамической памяти,
необходимо знать их адрес, поэтому в любом задании на обработку деревьев в набор исходных данных входят
<i>указатели</i>, содержащие адреса каких-либо вершин этих деревьев (как правило, указывается адрес корня дерева).
</p>
<p>Работа с исходными и результирующими
данными типа указателя подробно обсуждается в разделе, посвященном
<a href="ctpointer.html">линейным динамическим структурам</a>.
</p>
</p>
<hr>
<h3>Решение задачи</h3>
<p>В задании Tree2 не требуется ни создавать, ни
преобразовывать исходное дерево;
его необходимо лишь проанализировать, а именно определить количество его вершин.
</p>
<p>Для выполнения этого задания, как и для подавляющего большинства других заданий на обработку деревьев,
следует воспользоваться вспомогательной <i>рекурсивной</i> подпрограммой (функцией или процедурой).
Рекурсивная природа алгоритмов,
связанных с обработкой деревьев (в частности, бинарных деревьев), объясняется тем, что сами
определения деревьев общего вида и бинарных деревьев являются рекурсивными.
Так, дать словесное описание функции <code>NodeCount(P)</code>, подсчитывающей число вершин дерева с корнем,
с которым связан указатель <code>P</code>, можно следующим образом: если указатель <code>P</code> равен <code>nil</code>,
то следует вернуть значение <code>0</code>; в противном случае следует вернуть значение
<code>1 + NodeCount(P^.Left) + NodeCount(P^.Right)</code>
(в этом выражении первое слагаемое соответствует корню дерева, второе &#151;
его левому поддереву, а третье &#151; его правому поддереву; при этом не требуется проверять,
что указанные поддеревья существуют, так как при их отсутствии соответствующее слагаемое просто будет равно нулю).
</p>
<p>Таким образом, решение задачи будет иметь следующий вид:
</p>
<blockquote><code><pre>
<b>uses</b> PT4;
<b>function</b> NodeCount(P: PNode): integer;
begin
<b>if</b> P = nil <b>then</b>
result := 0
<b>else</b>
result := 1 + NodeCount(P^.Left) + NodeCount(P^.Right);
<b>end</b>;
<b>var</b> P1: PNode;
<b>begin</b>
Task('Tree2');
read(P1);
write(NodeCount(P1));
<b>end</b>.
</pre></code></blockquote>
<p>Цепочка рекурсивных вызовов функции <code>NodeCount</code> завершается при достижении терминальной вершины (листа),
у которой поля <code>Left</code> и <code>Right</code> равны <code>nil</code>. Благодаря наличию функции <code>NodeCount</code>,
раздел операторов программы является очень кратким: в нем считывается адрес <code>P1</code> корня исходного дерева,
после чего вызывается функция <code>NodeCount(P1)</code>, возвращаемое значение которой сразу выводится процедурой write.
</p>
<p>Запустив эту программу пять раз, мы получим сообщение &laquo;<i>Задание
выполнено!</i>&raquo;.
</p>
<hr>
<a name="parent"></a>
<h2>Пример 2. Бинарные деревья с обратной связью
</h2>
<hr>
<p>Рассмотренная выше реализация бинарных деревьев позволяет легко переходить от родительских вершин
к их дочерним вершинам, но не допускает обратного перехода. В то же время, для некоторых задач,
связанных с обработкой деревьев, возможность обратного перехода от потомков к их предку позволяет
получить более простое решение. Ясно, что для обеспечения возможности обратного перехода
каждую вершину дерева надо снабдить еще одним полем связи, в котором должна храниться ссылка на
ее родительскую вершину. Это поле связи естественно назвать <code>Parent</code>. Поскольку корень дерева
предка не имеет, его поле <code>Parent</code> должно быть равно <code>nil</code>.
</p>
<p>Деревья, вершины которых содержат информацию о своих родителях, будем называть <i>деревьями с обратной связью</i>.
Особенности работы с подобными деревьями рассмотрим на примере задания Tree49.
</p>
<p class="task">Tree49&#176;.
Дан указатель <i>P</i><sub>1</sub> на корень дерева, вершинами которого являются записи типа TNode,
связанные между собой с помощью полей Left и Right. Используя поле Parent записи TNode,
преобразовать исходное дерево в <i>дерево с обратной связью</i>, в котором каждая вершина
связана не только со своими дочерними вершинами (полями Left и Right), но и с родительской
вершиной (полем Parent). Поле Parent корня дерева положить равным nil.
</p>
<p>Запустив программу-заготовку, созданную для задания Tree49,
мы увидим в области исходных данных изображение &laquo;обычного&raquo; бинарного дерева,
в то время как в области результатов будет изображено дерево с обратной связью,
вершины которого связаны не одинарными, а двойными линиями.
</p>
<blockquote>
<img border="0" src="gif/Tree49-1.png">
</blockquote>
<p>Обратите также внимание на то, что в области результатов отсутствуют какие-либо данные, кроме
измененного дерева. Это означает, что в программе, решающей задачу, не требуется использовать
процедуры вывода; достаточно лишь преобразовать исходное дерево требуемым образом.
Поскольку при таком преобразовании адрес корня дерева <i>P</i><sub>1</sub>
не изменится, задачник сможеть получить доступ к
этому дереву и проверить его правильность.
</p>
<p>Для преобразования исходного дерева в дерево с обратной связью необходимо задать правильные значения
для полей <code>Parent</code> всех вершин дерева, перебирая эти вершины с помощью подходящей рекурсивной процедуры.
В эту процедуру удобно передавать в качестве параметров не только указатель <code>P</code> на текущую вершину,
но и указатель <code>Par</code> на предка этой вершины:
</p>
<blockquote><code><pre>
<b>uses</b> PT4;
<b>procedure</b> SetParent(P, Par: PNode);
<b>begin</b>
<b>if</b> P = nil <b>then</b>
exit;
P^.Parent := Par;
SetParent(P^.Left, P);
SetParent(P^.Right, P);
<b>end</b>;
<b>var</b> P1: PNode;
<b>begin</b>
Task('Tree49');
read(P1);
SetParent(P1, nil);
<b>end</b>.
</pre></code></blockquote>
<p>При стартовом запуске рекурсивной процедуры <code>SetParent</code> в качестве
второго параметра указывается <code>nil</code>.
</p>
<p>
<b>Примечание.</b> Обозначение для двойной связи может оказаться полезным при анализе ошибочного решения.
Так, если в изображении дерева с обратной связью имеется вершина, соединенная со своей родительским
вершиной не двойной, а одинарной линией, значит, у этой вершины поле <code>Parent</code> содержит ошибочное значение
(например, равно <code>nil</code>).
</p>
<hr>
<a name="general"></a>
<h2>Пример 3. Деревья общего вида
</h2>
<hr>
<p>С помощью связанных записей типа <code>TNode</code> можно моделировать не только бинарные деревья,
но и произвольные упорядоченные деревья, вершины которых имеют любое число непосредственных потомков
(будем называть такие деревья <i>деревьями общего вида</i>; для них также используется название
&laquo;деревья с множественным ветвлением&raquo;).
Рассмотрим задание Tree86 &#151; первое из заданий, связанных с деревьями общего вида, в котором
описываются особенности подобных деревьев.
</p>
<p class="task">Tree86&#176;.
<i>Дерево общего вида</i> (каждая вершина которого может иметь произвольное число дочерних вершин,
расположенных в фиксированном порядке в направлении слева направо) реализуется с помощью набора
связанных записей типа TNode следующим образом: для каждой внутренней вершины ее поле Left
содержит указатель на ее первую (т.&nbsp;е. левую) дочернюю вершину, а поле Right &#151; указатель на ее
правую <i>сестру</i>, т.&nbsp;е. вершину, имеющую в дереве общего вида того же родителя.
Поле Right корня дерева общего вида всегда равно nil, так как корень сестер не имеет.
Дан указатель <i>P</i><sub>1</sub> на корень непустого бинарного дерева. Создать дерево общего вида,
соответствующее исходному бинарному дереву, и вывести указатель <i>P</i><sub>2</sub> на его корень.
</p>
<p>Приведем пример дерева общего вида, которое реализовано с помощью связанных
записей типа <code>TNode</code> (аналогичным образом деревья общего вида изображаются в окне задачника):
</p>
<blockquote>
<img border="0" src="gif/Tree86-1.png">
</blockquote>
<p>Корень этого дерева (со значением 13) имеет три дочерние вершины (71, 73 и 29),
причем вершина 71 не имеет потомков, вершина 73 имеет три непосредственных потомка (18, 93 и 92),
а вершина 29 &#151; два (24 и 84). На последнем уровне располагается вершина 46, являющаяся
единственной дочерней вершиной вершины 93.
</p>
<p>При ознакомительном запуске задания Tree86 на экране появится окно, подобное следующему.
</p>
<blockquote>
<img border="0" src="gif/Tree86-2.png">
</blockquote>
<p>Обратите внимание на то, как выглядит одно и то же дерево в двух различных представлениях:
вариант, соответствующий обычному бинарному дереву, приводится в разделе исходных данных,
а вариант, соответствующий дереву общего вида, &#151; в разделе результатов.
При переходе от бинарного дерева к дереву общего вида часть информации о структуре бинарного дерева
теряется, поскольку в случае, если некоторая вершина дерева общего вида имеет только одного
непосредственного потомка, нельзя определить, каким был этот потомок в исходном бинарном дереве &#151; левым или правым.
</p>
<p>Напомним, что точки, обрамляющие значения вершин в разделе результатов, означают, что
все эти вершины должны быть созданы программой учащегося (в отличие от вершин исходного дерева, созданных
самим задачником при инициализации задания).
</p>
<p>При формировании нового дерева будем использовать рекурсивную функцию <code>CreateNode(P)</code>.
Параметр <code>P</code> содержит указатель на вершину исходного дерева, копия которой создается при вызове функции.
Возвращаемым значением функции является указатель на созданную вершину (как обычно, если <code>P = nil</code>,
то функция не выполняет никаких действий и возвращает <code>nil</code>). Для создания дочерних вершин выполняется
рекурсивный вызов этой функции. Заметим, что цепочка дочерних вершин может быть пустой
(если вершина <code>P</code> является листом), содержать один элемент (если вершина <code>P</code> имеет только одного
непосредственного потомка) или два элемента. Перед формированием цепочки дочерних вершин удобно
занести адреса дочерних вершин вершины <code>P</code> во вспомогательные переменные <code>P1</code> и <code>P2</code>. При этом в случае,
если вершина <code>P</code> имеет только одного потомка (неважно, левого или правого), адрес этого потомка
заносится в переменную <code>P1</code>, а переменная <code>P2</code> остается равной <code>nil</code>. Благодаря использованию
переменных <code>P1</code> и <code>P2</code>, фрагмент кода, отвечающий за формирование списка дочерних вершин,
удается сделать более кратким. Приведем текст программы, решающей задачу Tree86.
</p>
<blockquote><code><pre>
<b>uses</b> PT4;
<b>function</b> CreateNode(P: PNode): PNode;
<b>var</b> P1, P2: PNode;
<b>begin</b>
<b>if</b> P = nil <b>then</b>
<b>begin</b>
result := nil;
exit;
<b>end</b>;
New(result);
result^.Data := P^.Data;
result^.Right := nil;
P1 := P^.Left;
P2 := P^.Right;
<b>if</b> P1 = nil <b>then</b>
<b>begin</b>
P1 := P2;
P2 := nil;
<b>end</b>;
<i>{ формирование списка дочерних вершин }</i>
result^.Left := CreateNode(P1);
<b>if</b> P1 &lt;&gt; nil <b>then</b>
result^.Left^.Right := CreateNode(P2);
<b>end</b>;
<b>var</b> P1: PNode;
<b>begin</b>
Task('Tree86');
read(P1);
write(CreateNode(P1));
end.
</pre></code></blockquote>
<p>
<b>Примечание.</b> Фрагмент дерева общего вида, содержащий все дочерние вершины некоторой вершины,
можно рассматривать как <i>односвязный список</i>, элементы которого связаны между собой
с помощью поля <code>Right</code> (у последнего элемента списка поле <code>Right</code> равно <code>nil</code>).
Каждый элемент подобного списка может содержать &laquo;подсписок&raquo; своих дочерних элементов;
адрес начала этого подсписка хранится в поле <code>Left</code> данного элемента.
Поэтому в алгоритмах, связанных с обработкой вершин деревьев общего вида,
для перебора непосредственных потомков некоторой вершины удобно использовать <i>цикл</i>
(как при переборе элементов списка), в то время как для обработки каждой дочерней вершины следует,
как обычно, использовать <i>рекурсию</i>.
</p>

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 383 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 805 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 B

View file

@ -0,0 +1,99 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title></title>
</head>
<link rel="StyleSheet" href="../../default.css">
<body>
<H1>Что такое проверяемые задания</H1>
<hr>
<p>Задания, проверяемые автоматически, являются мечтой любого
преподавателя. Несомненно, что при автоматической проверке можно проверить
только сам факт выполнения задания, но не те знания, которые получил ученик.
Поэтому крайне желательно, чтобы выполнение проверяемых заданий проходило под
контролем преподавателя.</p>
<p>Опыт авторов системы <b>PascalABC.NET</b> и
<a href="../PT4/About.html">электронного задачника
Programming Taskbook</a> свидетельствует, что обучение программированию с помощью проверяемых заданий,
сочетаемое с другими методиками (обучение на примерах, поиск ошибок в
программах, ручная и автоматическая трассировка, создание творческих программных
проектов и т.&nbsp;д.), позволяет существенно ускорить сам процесс обучения и облегчить
труд преподавателя.</p>
<p>Итак, что такое <font color="#008000"><i><b>проверяемые
задания</b></i></font> и как их выполнять в системе <b>PascalABC.NET</b>?
Для того чтобы это узнать, проще всего ознакомиться с несколькими примерами
выполнения типовых заданий.
</p>
<p><a href="checkedtasks1.html">Пример 1. Задание Begin3
из электронного задачника <b>Programming Taskbook</b>.</a></p>
<p>Выполняя задание <code>Begin3</code>,
следует обратить внимание на
одну важную особенность работы с электронным задачником:
при его подключении процедуры ввода-вывода <code>read</code> и
<code>write</code> начинают работать иначе:
процедура read получает исходные данные непосредственно от задачника
(который генерирует их, используя датчик случайных чисел и учитывая
особенности выполняемого задания), а процедура write пересылает
результаты задачнику для проверки их правильности. Исходные данные, подготовленные задачником,
и результаты, полученные программой, отображаются в соответствующих разделах
окна задачника; ученик не должен заботиться об их форматировании и поясняющих
подписях, поскольку за эти действия отвечает сам задачник.
Важно учитывать, что при каждом запуске программы учащегося ей
будут предлагаться <i>различные варианты исходных данных</i>, поэтому для
решения задания необходимо разработать алгоритм,
правильно обрабатывающий любые наборы допустимых исходных данных.
</p>
<p><a href="checkedtasks2.html">Пример 2. Задание a1 для исполнителя
Робот.</a></p>
<p>Исполнитель Робот является бесценным источником заданий для быстрого обучения
основным конструкциям программирования школьников средних классов. </p>
<p><a href="ctstring.html">Пример 3. Задание String9
из электронного задачника <b>Programming Taskbook</b>.</a></p>
<p>Данное задание знакомит с особенностями выполнения заданий на обработку символов
и строк. Следует обратить внимание на диагностику ошибки, связанной с выводом строки, длина которой превышает длину
строки &#151; правильного решения.</p>
<p><a href="ctfile.html">Пример 4. Задание File48
из электронного задачника <b>Programming Taskbook</b>.</a></p>
<p>Это задание знакомит с особенностями выполнения заданий
на обработку типизированных файлов. Исходные файлы при вызове
задания создаются на диске, после чего могут обрабатываться по стандартным
правилам. Содержимое файлов, созданных в процессе выполнения задания,
проверяется электронным задачником; после проверки исходные и результирующие
файлы автоматически удаляются. Следует обратить внимание на то, как содержимое
файлов отображается в окне задачника, а также на обработку ошибок времени
выполнения, возникающих при выполнении заданий. В примере описаны типичные ошибки при
работе с файлами и способы их устранения.&nbsp;&nbsp; </p>
<p><a href="ctpointer.html">Пример 5. Задания группы Dynamic
из электронного задачника <b>Programming Taskbook</b>.</a></p>
<p>В данном примере описываются задания из раздела, посвященного указателям и линейным динамическим
структурам данных. При вызове задания в динамической памяти создаются все
исходные структуры данных (в виде односвязных или двусвязных списков), а
указатели на элементы этих структур выступают в качестве входных данных задания.
Содержимое всех структур данных отображается в окне задачника в наглядном виде.
Созданные программой ученика структуры данных анализируются задачником и после
анализа все структуры данных удаляются из памяти. </p>
<p><a href="cttree.html">Пример 6. Задания группы Tree
из электронного задачника <b>Programming Taskbook</b>.</a></p>
<p>В данном примере описываются задания на обработку иерархических структур данных &#151;
деревьев. Подобные структуры, как и линейные динамические структуры, рассмотренные
в предыдущем примере, создаются задачником автоматически и в наглядном виде отображаются
в его окне. Для доступа к ним также используются указатели.
</p>
<p><a href="ctexam.html">Пример 7. Задания групп ExamBegin и ExamTaskC
из электронного задачника <b>Programming Taskbook</b>.</a></p>
<p>Пример содержит описание процесса выполнения заданий, связанных с ЕГЭ
по информатике. Основной особенностью этих заданий является то, что
при их выполнении требуется использовать стандартные процедуры ввода-вывода языка
Pascal (а не их специальные модификации, реализованные для задачника <b>Programming Taskbook</b>).
Рассматриваются задания из группы ExamBegin, посвященные базовым алгоритмам,
и задания из группы ExamTaskC, посвященные обработке сложных наборов данных.
</p>
<p>Все примеры, связанные с электронным задачником <b>Programming Taskbook</b>, иллюстрируются
изображениями окна задачника
в <a href="..\PT4\window.html#dynmode">режиме с динамической компоновкой</a>, появившемся в версии 4.11.
</p>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 927 B

View file

@ -0,0 +1,71 @@
<html>
<head>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="Keyword" value="Чертежник">
<param name="Keyword" value="Drawman">
<param name="Keyword" value="ToPoint">
<param name="Keyword" value="OnVector">
<param name="Keyword" value="PenUp">
<param name="Keyword" value="PenDown">
<param name="Keyword" value="Task">
<param name="Keyword" value="Field">
<param name="Keyword" value="StandardField">
</object>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title></title>
<link rel="StyleSheet" href="../../default.css">
</head>
<body>
<H1>Исполнитель Чертежник</H1>
Исполнитель Чертежник
предназначен для построения рисунков и чертежей на плоскости с координатами.
Чертежник имеет перо, которое он может поднимать, опускать и перемещать.
При перемещении опущенного пера за ним остается след.
<p>Исполнитель Чертежник и поле, на котором он работает, отображаются на экране следующим
образом:</p>
<p><img border="0" src="DMa1.png" width="381" height="213"></p>
<p>Здесь маленький квадрат изображает Чертежника, красным цветом изображены
отрезки, которые надо нарисовать, а синим &#151; уже нарисованные Чертежником
отрезки. Когда перо Чертежника опущено, он изображается квадратом меньшего
размера.</p>
<p>Команды исполнителя Чертежник
содержатся в модуле <code>Drawman</code>:
</p>
<blockquote>
<code>ToPoint(x,y)</code>
перемещает перо Чертежника в точку <code>(x,y)</code>;<code><br>
OnVector(a,b)</code> перемещает перо
Чертежника на вектор <code>(a,b)</code>;<code><br>
PenUp</code> поднимает перо Чертежника;<code><br>
PenDown</code> опускает перо Чертежника.</p>
</blockquote>
<p style="margin-top: 6pt">Для вызова задания для исполнителя Чертежник
используется следующий шаблон программы:</p>
<blockquote>
<code><b>uses</b> Drawman;<br>
<b>begin</b><br>
&nbsp; <a name="Task">Task</a>('c1');<br>
<b>end</b>. </code>
</blockquote>
<p>В конце программы перо Чертежника должно быть поднято и находиться в начале
координат.</p>
<p>Здесь <code>Task</code> ¦&#151; процедура,
содержащаяся в модуле <code>Drawman</code> и вызывающая
задание с указанным именем.</p>
<p>Имеются следующие группы заданий для исполнителя
Чертежник:</p>
<blockquote>
<code>a</code> вводные задания;<code><br>
c</code> цикл с параметром;<code><br>
cc</code> вложенные циклы;<code><br>
p</code> процедуры без параметров;<code><br>
pp</code> процедуры с параметрами.
</blockquote>
<p>Для создания произвольного поля размера 20 x 30
используется процедура <code><a name="StandardField">StandardField</a></code> без параметров, а для создания
поля размера N x M &#151; процедура <code><a name="Field">Field</a>(N,M)</code>.</p>
</body>
</html>

View file

@ -0,0 +1,34 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title></title>
<link rel="StyleSheet" href="../../default.css">
</head>
<body>
<H1>Что такое исполнители</H1>
<p><b>Исполнителем</b> будем называть устройство, способное выполнять
определенный набор команд. Обычно с исполнителем связана некоторая среда, в
которой он работает.
</p>
<p>Традиционно концепция исполнителей используется для
быстрого обучения основным конструкциям языка программирования при проведении
занятий в средних классах школы. В <b>PascalABC.NET</b> реализованы исполнители
<a href="robotstart.html">Робот</a> и
<a href="dmstart.html">Чертежник</a>, описанные в учебнике А.&nbsp;Г.&nbsp;Кушниренко, Г.&nbsp;В.&nbsp;Лебедева
и Я.&nbsp;Н.&nbsp;Зайдельмана
&laquo;Информатика 7&#150;9 классы&raquo;, М., 2001. Следует отметить, что
данный учебник уже не используется для обучения в школе, однако
он является наиболее удачным и по интеграции исполнителей в процесс обучения
начальному программированию, и по набору задач. </p>
<p>Кроме того, исполнители в <b>PascalABC.NET</b>
активно используются в <a href="../CheckedTasks/index.html">системе проверяемых заданий</a> &#151; одной из
ключевых учебных особенностей системы <b>PascalABC.NET</b>.</p>
<p>См. также <a href="../CheckedTasks/checkedtasks2.html">пример выполнения задания a1 для
исполнителя
Робот.</a></p>
</body>
</html>

View file

@ -0,0 +1,114 @@
<html>
<head>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="Keyword" value="Ðîáîò">
<param name="Keyword" value="Robot">
<param name="Keyword" value="Left">
<param name="Keyword" value="Right">
<param name="Keyword" value="Up">
<param name="Keyword" value="Down">
<param name="Keyword" value="Paint">
<param name="Keyword" value="WallFromLeft">
<param name="Keyword" value="WallFromRight">
<param name="Keyword" value="WallFromUp">
<param name="Keyword" value="WallFromDown">
<param name="Keyword" value="FreeFromLeft">
<param name="Keyword" value="FreeFromRight">
<param name="Keyword" value="FreeFromUp">
<param name="Keyword" value="FreeFromDown">
<param name="Keyword" value="CellIsPainted">
<param name="Keyword" value="CellIsFree">
<param name="Keyword" value="Task">
<param name="Keyword" value="Field">
<param name="Keyword" value="StandardField">
</object>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title></title>
<link rel="StyleSheet" href="../../default.css">
</head>
<body>
<H1>Èñïîëíèòåëü Ðîáîò</H1>
<p >Èñïîëíèòåëü Ðîáîò
äåéñòâóåò íà ïðÿìîóãîëüíîì êëåòî÷íîì ïîëå. Ìåæäó íåêîòîðûìè êëåòêàìè, à
òàêæå ïî ïåðèìåòðó ïîëÿ íàõîäÿòñÿ <i>ñòåíû</i>. Îñíîâíàÿ öåëü Ðîáîòà ¦&#151; çàêðàñèòü
óêàçàííûå êëåòêè è ïåðåìåñòèòüñÿ â êîíå÷íóþ êëåòêó.</p>
<p>Èñïîëíèòåëü Ðîáîò è ïîëå, íà êîòîðîì îí ðàáîòàåò, îòîáðàæàþòñÿ ñëåäóþùèì
îáðàçîì:</p>
<p><img border="0" src="../CheckedTasks/gif/RBa1-1.png"></p>
<p>Çäåñü áîëüøîé æåëòûé êâàäðàò èçîáðàæàåò Ðîáîòà, ìàëåíüêèé
æåëòûé êâàäðàò â ëåâîì âåðõíåì óãëó êëåòêè &#151; êîíå÷íîå ïîëîæåíèå Ðîáîòà, ÷åðíûìè òî÷êàìè ïîìå÷åíû êëåòêè, êîòîðûå íàäî çàêðàñèòü.</p>
<p>Êîìàíäû èñïîëíèòåëÿ Ðîáîò ñîäåðæàòñÿ â
ìîäóëå <code>Robot</code>:
</p>
<blockquote>
<code>Right</code>
ïåðåìåùàåò Ðîáîòà âïðàâî;<code><br>
Left</code> ïåðåìåùàåò Ðîáîòà âëåâî;<code><br>
Up</code> ïåðåìåùàåò Ðîáîòà ââåðõ;
<code><br>
Down</code> ïåðåìåùàåò Ðîáîòà âíèç;
<code><br>
Paint</code> çàêðàøèâàåò òåêóùóþ ÿ÷åéêó;<code><br>
WallFromLeft</code> âîçâðàùàåò <code>True</code>
åñëè ñëåâà îò Ðîáîòà ñòåíà;
<code><br>
WallFromRight</code> âîçâðàùàåò <code>True</code>
åñëè ñïðàâà îò Ðîáîòà ñòåíà;
<code><br>
WallFromUp</code> âîçâðàùàåò <code>True</code>
åñëè ñâåðõó îò Ðîáîòà ñòåíà;
<code><br>
WallFromDown</code> âîçâðàùàåò <code>True</code>
åñëè ñíèçó îò Ðîáîòà ñòåíà;
<code><br>
FreeFromLeft</code> âîçâðàùàåò <code>True</code>
åñëè ñëåâà îò Ðîáîòà ñâîáîäíî;
<code><br>
FreeFromRight</code> âîçâðàùàåò <code>True</code>
åñëè ñïðàâà îò Ðîáîòà ñâîáîäíî;
<code><br>
FreeFromUp</code> âîçâðàùàåò <code>True</code>
åñëè ñâåðõó îò Ðîáîòà ñâîáîäíî;
<code><br>
FreeFromDown</code> âîçâðàùàåò <code>True</code>
åñëè ñíèçó îò Ðîáîòà ñâîáîäíî;
<code><br>
CellIsPainted</code> âîçâðàùàåò <code>True</code>
åñëè ÿ÷åéêà, â êîòîðîé íàõîäèòñÿ Ðîáîò, çàêðàøåíà;
<code><br>
CellIsFree</code> âîçâðàùàåò <code>True</code>
åñëè ÿ÷åéêà, â êîòîðîé íàõîäèòñÿ Ðîáîò, íå çàêðàøåíà.
</blockquote>
<p>Äëÿ âûçîâà çàäàíèÿ äëÿ èñïîëíèòåëÿ Ðîáîò èñïîëüçóåòñÿ
ñëåäóþùèé øàáëîí ïðîãðàììû:</p>
<blockquote>
<code><b>uses</b> Robot;<br>
<b>begin</b> <br>
&nbsp;
Task('c1'); <br>
<b>end</b>. </code>
</blockquote>
<p>Çäåñü <code>Task</code> &#151; ïðîöåäóðà,
ñîäåðæàùàÿñÿ â ìîäóëå <code>Robot</code> è âûçûâàþùàÿ
çàäàíèå ñ óêàçàííûì èìåíåì.</p>
<p>Èìåþòñÿ ñëåäóþùèå ãðóïïû çàäàíèé äëÿ èñïîëíèòåëÿ Ðîáîò:</p>
<blockquote>
<code>a</code> ââîäíûå çàäàíèÿ;<code><br>
c</code> öèêë ñ ïàðàìåòðîì;<code><br>
if</code> ëîãè÷åñêèå âûðàæåíèÿ;<code><br>
w</code> öèêëû ñ óñëîâèåì;<code><br>
ñif</code> öèêëû + ëîãè÷åñêèå âûðàæåíèÿ;<code><br>
count</code> ïåðåìåííûå-ñ÷åò÷èêè;<code><br>
cc</code> âëîæåííûå öèêëû;<code><br>
p</code> ïðîöåäóðû áåç ïàðàìåòðîâ;<code><br>
pp</code> ïðîöåäóðû ñ ïàðàìåòðàìè.
</blockquote>
<p>Äëÿ ñîçäàíèÿ ñòàíäàðòíîãî ïîëÿ ðàçìåðà 9 x 11
èñïîëüçóåòñÿ ïðîöåäóðà <code><a name="StandardField">StandardField</a></code> áåç ïàðàìåòðîâ, à äëÿ ñîçäàíèÿ
ïîëÿ ðàçìåðà N x M &#151; ïðîöåäóðà <code><a name="Field">Field</a>(N,M)</code>.
Ðîáîò ïðè ýòîì ïîìåùàåòñÿ â öåíòð ïîëÿ.</p>
</body>
</html>

View file

@ -0,0 +1,108 @@
<html>
<head>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="Keyword" value="TaskProcType">
<param name="Keyword" value="DrawmanField">
<param name="Keyword" value="DoToPoint">
<param name="Keyword" value="DoOnVector">
<param name="Keyword" value="DoPenUp">
<param name="Keyword" value="DoPenDown">
<param name="Keyword" value="TaskText">
<param name="Keyword" value="RegisterTask">
<param name="Keyword" value="RegisterGroup">
</object>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title></title>
<link rel="StyleSheet" href="../../default.css">
</head>
<body>
<H1>Ìîäóëü </span>DMTaskMaker</H1>
<hr>
<table border="0" width="100%" id="table3" style="border-width: 0px" cellpadding="8">
<tr height=20pt>
<td style="border-style:none; border-width:medium; background-color: #99CCFF">
<b><font size="2" color="#800080"><span lang="ru">Òèïû</span> ìîäóëÿ </font></b>
<font size="2" color="#800080"><b>DMTaskMaker</b></font></td>
</tr>
</table>
<blockquote>
<p><code><b>type</b> TaskProcType<span lang="ru"> </span>=<b><span lang="ru">
</span>procedure</b>;</code></p>
</blockquote>
<p>Òèï ïðîöåäóðû, ãåíåðèðóþùåé êîíêðåòíîå çàäàíèå.
Êàæäîå çàäàíèå ðåàëèçóåòñÿ â âèäå îòäåëüíîé ïðîöåäóðû; äëÿ ñâÿçûâàíèÿ ýòîé ïðîöåäóðû
ñ èìåíåì çàäàíèÿ íåîáõîäèìî èñïîëüçîâàòü ïðîöåäóðó <code>RegisterTask</code>, îïèñûâàåìóþ íèæå.
</p>
<table border="0" width="100%" id="table4" style="border-width: 0px" cellpadding="8">
<tr height=20pt>
<td style="border-style:none; border-width:medium; background-color: #99CCFF">
<b><font size="2" color="#800080">Ïðîöåäóðû ìîäóëÿ </font></b>
<font size="2" color="#800080"><b>DMTaskMaker</b></font></td>
</tr>
</table>
<blockquote>
<p><code><b>procedure</b> Field(szx,szy: integer); </code></p>
</blockquote>
<p><span lang="ru">Çàäàåò ïîëå ×åðòåæíèêà ðàçìåðà </span><code>szx</code>
<span lang="ru">íà </span><code>szy</code> <span lang="ru">êëåòîê</span>.</p>
<blockquote>
<p><code><b>procedure</b> DoToPoint(x,y: integer); </code></p>
</blockquote>
<p><span lang="ru">Ïåðåìåùàåò ïåðî ×åðòåæíèêà-ïîñòàíîâùèêà çàäàíèé â òî÷êó ñ
êîîðäèíàòàìè </span> <code>(x</code>,<span lang="ru"> </span><code>y)</code><span lang="ru">.</span></p>
<blockquote>
<p><code><b>procedure</b> DoOnVector(dx,dy: integer); </code></p>
</blockquote>
<p><span lang="ru">Ïåðåìåùàåò ïåðî ×åðòåæíèêà-ïîñòàíîâùèêà çàäàíèé â òî÷êó ñ
êîîðäèíàòàìè </span> <code>(x</code>,<span lang="ru"> </span><code>y)</code><span lang="ru">.</span></p>
<blockquote>
<p><code><b>procedure</b> DoPenUp; </code></p>
</blockquote>
<p><span lang="ru">Ïîäíèìàåò ïåðî ×åðòåæíèêà-ïîñòàíîâùèêà çàäàíèé.</span></p>
<blockquote>
<p><code><b>procedure</b> DoPenDown; </code></p>
</blockquote>
<p><span lang="ru">Îïóñêàåò ïåðî ×åðòåæíèêà-ïîñòàíîâùèêà çàäàíèé.</span></p>
<blockquote>
<p><code><b>procedure</b> TaskText(s: string); </code></p>
</blockquote>
<p><span lang="ru">Çàäàåò èìÿ è ôîðìóëèðîâêó çàäàíèÿ â ñòðîêå </span><code>s</code><span lang="ru">.
</span></p>
<blockquote>
<p><code><b>procedure</b> RegisterGroup(name,description,unitname: string; count: integer); </code></p>
</blockquote>
<p>Îáåñïå÷èâàåò àâòîìàòè÷åñêóþ ðåãèñòðàöèþ íîâîé ãðóïïû çàäàíèé â ïðîãðàììíîì ìîäóëå <b>PT4Load</b>.
 ðåçóëüòàòå èìÿ äàííîé ãðóïïû áóäåò îòîáðàæàòüñÿ â îêíå ìîäóëÿ <b>PT4Load</b> â ñïèñêå ãðóïï, ñâÿçàííûõ ñ èñïîëíèòåëåì
×åðòåæíèê,
÷òî ïîçâîëèò ñîçäàòü ïðîãðàììó-çàãîòîâêó äëÿ âûïîëíåíèÿ ëþáîãî çàäàíèÿ ýòîé ãðóïïû.
 êà÷åñòâå ïàðàìåòðîâ ïðîöåäóðû óêàçûâàåòñÿ èìÿ ãðóïïû <code>name</code>,
êðàòêîå îïèñàíèå ãðóïïû <code>description</code>,
èìÿ ìîäóëÿ <code>unitname</code>, â êîòîðîì îïèñàíà ãðóïïà, è êîëè÷åñòâî çàäàíèé <code>count</code>.
Èìÿ ãðóïïû çàäàíèé äîëæíî ñîäåðæàòü íå áîëåå 7 ñèìâîëîâ (öèôð è ëàòèíñêèõ áóêâ) è íå äîëæíî îêàí÷èâàòüñÿ öèôðîé,
êîëè÷åñòâî çàäàíèé íå äîëæíî ïðåâûøàòü 999.
Ïðîöåäóðà <code>RegisterGroup</code> äîëæíà
âûçûâàòüñÿ â ñåêöèè èíèöèàëèçàöèè ìîäóëÿ, ñîäåðæàùåãî ðåàëèçàöèþ íîâîé ãðóïïû çàäàíèé äëÿ ×åðòåæíèêà.
</p>
<blockquote>
<p><code><b>procedure</b> RegisterTask(name: string; p: TaskProcType);</code>
</blockquote>
<p>Ñâÿçûâàåò èìÿ çàäàíèÿ <code>name</code> ñ ïðîöåäóðîé <code>p</code>, â êîòîðîé ðåàëèçîâàíî äàííîå çàäàíèå.
Äàííóþ ïðîöåäóðó ñëåäóåò âûçûâàòü äëÿ <i>êàæäîãî</i> çàäàíèÿ.
Ïîäîáíî îïèñàííîé âûøå ïðîöåäóðå <code>RegisterGroup</code>, ïðîöåäóðà <code>RegisterTask</code> äîëæíà âûçûâàòüñÿ â ñåêöèè èíèöèàëèçàöèè
ìîäóëÿ, ñîäåðæàùåãî ðåàëèçàöèþ íîâîé ãðóïïû çàäàíèé äëÿ ×åðòåæíèêà. Ïîðÿäîê âûçîâà ýòèõ ïðîöåäóð ìîæåò áûòü ïðîèçâîëüíûì.
</p>
</body>
</html>

View file

@ -0,0 +1,130 @@
<html>
<head>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="Keyword" value="">
</object>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title></title>
<link rel="StyleSheet" href="../../default.css">
</head>
<body>
<H1>Ñîçäàíèå çàäàíèé äëÿ èñïîëíèòåëÿ <span lang="ru">×åðòåæíèê</span></H1>
<hr>
<p><span lang="ru">Îïèøåì ïîñëåäîâàòåëüíîñòü ñîçäàíèÿ ãðóïïû çàäàíèé äëÿ
èñïîëíèòåëÿ ×åðòåæíèê. Ñîçäàäèì ìîäóëü </span><span lang="en-us">DM</span>Tasks.pas ñî ñëåäóþùè<span lang="ru">ì
òåêñòîì:</span></p>
<blockquote>
<p><code><b>unit</b> <span lang="en-us">DM</span>Tasks;</code></p>
<p><code><b>interface</b></code></p>
<p><code><b>uses</b> DMTaskMaker;</code></p>
<p><code><b>implementation</b></code></p>
<p><code><b>procedure</b> First<span lang="en-us">DM</span>;<br>
<b>var</b> i,a: integer;<br>
<b>begin</b><br>
&nbsp; TaskText('Çàäàíèå mydm1. Íà÷åðòèòå, èñïîëüçóÿ öèêë');<br>
&nbsp; Field(14,8);<br>
&nbsp; DoToPoint(7,7);<br>
&nbsp; a:=6;<br>
&nbsp; <b>for</b> i:=1 <b>to</b> 6 <b>do</b><br>
&nbsp; <b>begin</b><br>
&nbsp;&nbsp;&nbsp; DoPenDown;<br>
&nbsp;&nbsp;&nbsp; DoOnVector(a,-a);<br>
&nbsp;&nbsp;&nbsp; DoOnVector(-a,a);<br>
&nbsp;&nbsp;&nbsp; DoOnVector(-a,-a);<br>
&nbsp;&nbsp;&nbsp; DoOnVector(a,a);<br>
&nbsp;&nbsp;&nbsp; Dec(a);<br>
&nbsp;&nbsp;&nbsp; DoPenUp;<br>
&nbsp;&nbsp;&nbsp; DoOnVector(0,-1);<br>
&nbsp; <b>end</b>;<br>
<b>end</b>;</code></p>
<p><code><b>begin</b><br>
&nbsp; </span>RegisterGroup('mydm','Ìîè çàäàíèÿ äëÿ ×åðòåæíèêà','DMTasks',2);<br>
&nbsp; </span>RegisterTask('mydm1',FirstDM);<br>
<b>end</b>.</code></p>
</blockquote>
<p><span lang="ru">Íàáåðåì è çàïóñòèì îñíîâíóþ ïðîãðàììó (ñîõðàíÿòü åå â êàêîì-ëèáî ôàéëå íå òðåáóåòñÿ):</span></p>
<blockquote>
<p><code><b>uses</b> <span lang="en-us">Drawman</span>, <span lang="en-us">
DM</span>Tasks;<br>
<b>begin</b><br>
&nbsp; Task('my<span lang="en-us">dm</span>1');<br>
<b>end</b>.</code></p>
</blockquote>
<p>Áóäåò âûâåäåíî ñëåäóþùåå çàäàíèå äëÿ <span lang="ru">×åðòåæíèêà</span>:</p>
<p><img border="0" src="images/dmmake1.PNG"></p>
<p>Äîáàâèì çàäàíèå íà ðàçðàáîòêó ïðîöåäóðû:</p>
<blockquote>
<p><code><b>procedure</b> DoCross;<br>
<b>begin</b><br>
&nbsp; DoPenDown;<br>
&nbsp; DoOnVector(1,0); DoOnVector(0,-1);<br>
&nbsp; DoOnVector(1,0); DoOnVector(0,-1);<br>
&nbsp; DoOnVector(-1,0); DoOnVector(0,-1);<br>
&nbsp; DoOnVector(-1,0); DoOnVector(0,1);<br>
&nbsp; DoOnVector(-1,0); DoOnVector(0,1);<br>
&nbsp; DoOnVector(1,0); DoOnVector(0,1);<br>
&nbsp; DoPenUp;<br>
<b>end</b>;</code></p>
<p><code><b>procedure</b> SecondDM;<br>
<b>begin</b><br>
&nbsp; TaskText('Çàäàíèå mydm2. Íà÷åðòèòå, èñïîëüçóÿ ïðîöåäóðó Cross');<br>
&nbsp; Field(18,12);<br>
&nbsp; DoToPoint(3,8);<br>
&nbsp; DoCross;<br>
&nbsp; DoToPoint(8,4);<br>
&nbsp; DoCross;<br>
&nbsp; DoToPoint(12,11);<br>
&nbsp; DoCross;<br>
&nbsp; DoToPoint(15,6);<br>
&nbsp; DoCross;<br>
<b>end</b>;</code></p>
</blockquote>
<p>Äîáàâèì âûçîâ ïðîöåäóðû ðåãèñòðàöèè äëÿ äàííîãî çàäàíèÿ; â ðåçóëüòàòå ñåêöèÿ èíèöèàëèçàöèè ïðèìåò ñëåäóþùèé âèä:</p>
<blockquote>
<p><code><b>begin</b><br>
&nbsp; RegisterGroup('mydm','Ìîè çàäàíèÿ äëÿ ×åðòåæíèêà','DMTasks',2);<br>
&nbsp; RegisterTask('mydm1',FirstDM);<br>
&nbsp; RegisterTask('mydm2',SecondDM);<br>
<b>end</b>.</code></p>
</blockquote>
<p><span lang="ru">Èçìåíèì îñíîâíóþ ïðîãðàììó:</span></p>
<blockquote>
<p><code><b>uses</b> <span lang="en-us">Drawman</span>, <span lang="en-us">
DM</span>Tasks;<br>
<b>begin</b><br>
&nbsp; Task('my<span lang="en-us">dm2</span>');<br>
<b>end</b>.</code></p>
</blockquote>
<p>Ïðè çàïóñêå ýòîé ïðîãðàììû â îêíå èñïîëíèòåëÿ ×åðòåæíèê áóäåò âûâåäåíî íîâîå çàäàíèå:</p>
<p><img border="0" src="images/dmmake2.PNG"></p>
<p>
Ïðè ïåðâîì çàïóñêå ïðîãðàììû ñ ïîäêëþ÷åííûì ìîäóëåì <code>DMTasks</code> ñîçäàííàÿ íàìè ãðóïïà áûëà àâòîìàòè÷åñêè çàðåãèñòðèðîâàíà
â ìàñòåðå ïî ñîçäàíèþ ïðîãðàìì-çàãîòîâîê <b>PT4Load</b>.
Åñëè òåïåðü íàæàòü êíîïêó&nbsp;<img border="0" src="images/load.gif" width="16" height="17">&nbsp;è â ïîÿâèâøåìñÿ îêíå
<b>PT4Load</b> ââåñòè ïðåôèêñ
</span><span lang="en-us"><code>DM</code></span><span lang="ru"> â ïîëå &laquo;Çàäàíèå&raquo;, òî îêíî ïðèìåò ñëåäóþùèé âèä:
&nbsp;</span></p>
<p><img border="0" src="images/dmmake3.PNG">
&nbsp;</p>
<p>Ìû âèäèì, ÷òî ãðóïïà çàäàíèé mydm ïîÿâèëàñü â ñïèñêå äîñòóïíûõ ãðóïï äëÿ èñïîëíèòåëÿ ×åðòåæíèê. Íàáåðåì èìÿ çàäàíèÿ
<span lang="en-us"><code>mydm1</code></span>:</p>
<p>
<img border="0" src="images/dmmake4.PNG">
</p>
<p>Ïîñëå íàæàòèÿ êëàâèøè <span lang="en-us"><b>Enter</b> </span>â ðàáî÷åì êàòàëîãå áóäåò ñîçäàí
íîâûé ôàéë <span lang="en-us">DMmydm1.pas </span>ñî ñëåäóþùèì ñîäåðæèìûì:</p>
<blockquote>
<p><code><b>uses</b> <span lang="en-us">Drawman</span>, <span lang="en-us">
DM</span>Tasks;<br>
<br>
<b>begin</b><br>
&nbsp; Task('my<span lang="en-us">dm</span>1');<br>
<br>
<b>end</b>.</code></p>
</blockquote>
<p>Ìîæíî ïîïûòàòüñÿ ðåøèòü :)</p>
</body>
</html>

View file

@ -0,0 +1,131 @@
<html>
<head>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="Keyword" value="TaskProcType">
<param name="Keyword" value="Field">
<param name="Keyword" value="HorizontalWall">
<param name="Keyword" value="VerticalWall">
<param name="Keyword" value="RobotBegin">
<param name="Keyword" value="RobotEnd">
<param name="Keyword" value="RobotBeginEnd">
<param name="Keyword" value="Tag">
<param name="Keyword" value="TagRect">
<param name="Keyword" value="MarkPainted">
<param name="Keyword" value="TaskText">
<param name="Keyword" value="RegisterTask">
<param name="Keyword" value="RegisterGroup">
</object>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title></title>
<link rel="StyleSheet" href="../../default.css">
</head>
<body>
<H1>Ìîäóë<span lang="ru">ü </span>RobotTaskMaker</H1>
<hr>
<table border="0" width="100%" id="table1" style="border-width: 0px" cellpadding="8">
<tr height=20pt>
<td style="border-style:none; border-width:medium; background-color: #99CCFF">
<b><font size="2" color="#800080"><span lang="ru">Òèïû</span> ìîäóëÿ </font></b>
<font size="2" color="#800080"><b>RobotTaskMaker</b></font></td>
</tr>
</table>
<blockquote>
<p><code><b>type</b> TaskProcType<span lang="ru"> </span>=<b><span lang="ru">
</span>procedure</b>;</code></p>
</blockquote>
<p>Òèï ïðîöåäóðû, ãåíåðèðóþùåé êîíêðåòíîå çàäàíèå.
Êàæäîå çàäàíèå ðåàëèçóåòñÿ â âèäå îòäåëüíîé ïðîöåäóðû; äëÿ ñâÿçûâàíèÿ ýòîé ïðîöåäóðû
ñ èìåíåì çàäàíèÿ íåîáõîäèìî èñïîëüçîâàòü ïðîöåäóðó <code>RegisterTask</code>, îïèñûâàåìóþ íèæå.
</p>
<table border="0" width="100%" id="table2" style="border-width: 0px" cellpadding="8">
<tr height=20pt>
<td style="border-style:none; border-width:medium; background-color: #99CCFF">
<b><font size="2" color="#800080">Ïðîöåäóðû ìîäóëÿ </font></b>
<font size="2" color="#800080"><b>RobotTaskMaker</b></font></td>
</tr>
</table>
<blockquote>
<p><code><b>procedure</b> Field(szx,szy: integer); </code></p>
</blockquote>
<p><span lang="ru">Çàäàåò ïîëå Ðîáîòà ðàçìåðà </span><code>szx</code>
<span lang="ru">íà </span><code>szy</code> <span lang="ru">êëåòîê</span>.</p>
<blockquote>
<p><code><b>procedure</b> HorizontalWall(x,y,len: integer); </code></p>
</blockquote>
<p><span lang="ru">Ñîçäàåò ãîðèçîíòàëüíóþ ñòåíó äëèíû </span><code>len</code><span lang="ru">
è êîîðäèíàòàìè ëåâîãî âåðõíåãî óãëà (</span><code>x</code>,<span lang="ru">
</span><code>y</code>)<span lang="ru">.</span></p>
<blockquote>
<p><code><b>procedure</b> VerticalWall(x,y,len: integer); </code></p>
</blockquote>
<p><span lang="ru">Ñîçäàåò âåðòèêàëüíóþ ñòåíó äëèíû </span><code>len</code><span lang="ru">
è êîîðäèíàòàìè ëåâîãî âåðõíåãî óãëà (</span><code>x</code>,<span lang="ru">
</span><code>y</code>)<span lang="ru">.</span></p>
<blockquote>
<p><code><b>procedure</b> RobotBegin(x,y: integer); </code></p>
</blockquote>
<p><span lang="ru">Çàäàåò íà÷àëüíîå ïîëîæåíèå Ðîáîòà â êëåòêå ñ êîîðäèíàòàìè (</span><code>x</code>,<span lang="ru">
</span><code>y</code>)<span lang="ru">.</span></p>
<blockquote>
<p><code><b>procedure</b> RobotEnd(x,y: integer); </code></p>
</blockquote>
<p><span lang="ru">Çàäàåò êîíå÷íîå ïîëîæåíèå Ðîáîòà â êëåòêå ñ êîîðäèíàòàìè (</span><code>x</code>,<span lang="ru">
</span><code>y</code>)<span lang="ru">.</span></p>
<blockquote>
<p><code><b>procedure</b> RobotBeginEnd(x,y,x1,y1: integer); </code></p>
</blockquote>
<p><span lang="ru">Çàäàåò íà÷àëüíîå ïîëîæåíèå Ðîáîòà â êëåòêå ñ êîîðäèíàòàìè (</span><code>x</code>,<span lang="ru">
</span><code>y</code>)<span lang="ru"> è êîíå÷íîå â êëåòêå ñ êîîðäèíàòàìè (</span><code>x<span lang="ru">1</span></code>,<span lang="ru">
</span><code>y<span lang="ru">1</span></code>)<span lang="ru">.</span></p>
<blockquote>
<p><code><b>procedure</b> Tag(x,y: integer); </code></p>
</blockquote>
<p><span lang="ru">Ïîìå÷àåò êëåòêó (</span><code>x</code>,<span lang="ru">
</span><code>y</code>)<span lang="ru"> äëÿ çàêðàøèâàíèÿ.</span></p>
<blockquote>
<p><code><b>procedure</b> TagRect(x,y,x1,y1: integer); </code></p>
</blockquote>
<p><span lang="ru">Ïîìå÷àåò ïðÿìîóãîëüíèê èç êëåòîê, çàäàâàåìûé êîîðäèíàòàìè
ïðîòèâîïîëîæíûõ âåðøèí ïðÿìîóãîëüíèêà (</span><code>x</code>,<span lang="ru">
</span><code>y</code>)<span lang="ru"> è (</span><code>x<span lang="ru">1</span></code>,<span lang="ru">
</span><code>y<span lang="ru">1</span></code>)<span lang="ru">, äëÿ
çàêðàøèâàíèÿ.</span></p>
<blockquote>
<p><code><b>procedure</b> MarkPainted(x,y: integer); </code></p>
</blockquote>
<p><span lang="ru">Çàêðàøèâàåò êëåòêó (</span><code>x</code>,<span lang="ru">
</span><code>y</code>)<span lang="ru"> (â çàäàíèè íåêîòîðûå êëåòêè ìîãóò áûòü
óæå çàêðàøåíû).</span></p>
<blockquote>
<p><code><b>procedure</b> TaskText(s: <b>string</b>); </code></p>
</blockquote>
<p><span lang="ru">Çàäàåò ôîðìóëèðîâêó òåêñòà çàäàíèÿ â ñòðîêå </span><code>s</code><span lang="ru">.</span></p>
<blockquote>
<p><code><b>procedure</b> RegisterGroup(name,description,unitname: string; count: integer); </code></p>
</blockquote>
<p>Îáåñïå÷èâàåò àâòîìàòè÷åñêóþ ðåãèñòðàöèþ íîâîé ãðóïïû çàäàíèé â ïðîãðàììíîì ìîäóëå <b>PT4Load</b>.
 ðåçóëüòàòå èìÿ äàííîé ãðóïïû áóäåò îòîáðàæàòüñÿ â îêíå ìîäóëÿ <b>PT4Load</b> â ñïèñêå ãðóïï, ñâÿçàííûõ ñ èñïîëíèòåëåì Ðîáîò,
÷òî ïîçâîëèò ñîçäàòü ïðîãðàììó-çàãîòîâêó äëÿ âûïîëíåíèÿ ëþáîãî çàäàíèÿ ýòîé ãðóïïû.
 êà÷åñòâå ïàðàìåòðîâ ïðîöåäóðû óêàçûâàåòñÿ èìÿ ãðóïïû <code>name</code>,
êðàòêîå îïèñàíèå ãðóïïû <code>description</code>,
èìÿ ìîäóëÿ <code>unitname</code>, â êîòîðîì îïèñàíà ãðóïïà, è êîëè÷åñòâî çàäàíèé <code>count</code>.
Èìÿ ãðóïïû çàäàíèé äîëæíî ñîäåðæàòü íå áîëåå 7 ñèìâîëîâ (öèôð è ëàòèíñêèõ áóêâ) è íå äîëæíî îêàí÷èâàòüñÿ öèôðîé,
êîëè÷åñòâî çàäàíèé íå äîëæíî ïðåâûøàòü 999.
Ïðîöåäóðà <code>RegisterGroup</code> äîëæíà
âûçûâàòüñÿ â ñåêöèè èíèöèàëèçàöèè ìîäóëÿ, ñîäåðæàùåãî ðåàëèçàöèþ íîâîé ãðóïïû çàäàíèé äëÿ Ðîáîòà.
</p>
<blockquote>
<p><code><b>procedure</b> RegisterTask(name: string; p: TaskProcType);</code>
</blockquote>
<p>Ñâÿçûâàåò èìÿ çàäàíèÿ <code>name</code> ñ ïðîöåäóðîé <code>p</code>, â êîòîðîé ðåàëèçîâàíî äàííîå çàäàíèå.
Äàííóþ ïðîöåäóðó ñëåäóåò âûçûâàòü äëÿ <i>êàæäîãî</i> çàäàíèÿ.
Ïîäîáíî îïèñàííîé âûøå ïðîöåäóðå <code>RegisterGroup</code>, ïðîöåäóðà <code>RegisterTask</code> äîëæíà âûçûâàòüñÿ â ñåêöèè èíèöèàëèçàöèè
ìîäóëÿ, ñîäåðæàùåãî ðåàëèçàöèþ íîâîé ãðóïïû çàäàíèé äëÿ Ðîáîòà. Ïîðÿäîê âûçîâà ýòèõ ïðîöåäóð ìîæåò áûòü ïðîèçâîëüíûì.
</p>
</body>
</html>

View file

@ -0,0 +1,114 @@
<html>
<head>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="Keyword" value="">
</object>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title></title>
<link rel="StyleSheet" href="../../default.css">
</head>
<body>
<H1>Ñîçäàíèå çàäàíèé äëÿ èñïîëíèòåëÿ Ðîáîò</H1>
<hr>
<p><span lang="ru">Îïèøåì ïîñëåäîâàòåëüíîñòü ñîçäàíèÿ ãðóïïû çàäàíèé äëÿ
èñïîëíèòåëÿ Ðîáîò. Ñîçäàäèì ìîäóëü </span>RobTasks.pas ñî ñëåäóþùè<span lang="ru">ì
òåêñòîì:</span></p>
<blockquote>
<p><code><b>unit</b> RobTasks;</code></p>
<p><code><b>interface</b></code></p>
<p><code><b>uses</b> RobotTaskMaker;</code></p>
<p><code><b>implementation</b></code></p>
<p><code><b>procedure</b> FirstRob;<br>
<b>begin</b><br>
<span lang="ru">&nbsp; </span>TaskText('Çàäàíèå myrob1. Çàêðàñèòü ïîìå÷åííûå êëåòêè');<br>
<span lang="ru">&nbsp; </span>Field(10,6);<br>
<span lang="ru">&nbsp; </span>HorizontalWall(0,3,4);<br>
<span lang="ru">&nbsp; </span>VerticalWall(4,3,2);<br>
<span lang="ru">&nbsp; </span>RobotBegin(1,4);<br>
<span lang="ru">&nbsp; </span>VerticalWall(5,1,5);<br>
<span lang="ru">&nbsp; </span>HorizontalWall(5,1,4);<br>
<span lang="ru">&nbsp; </span>RobotEnd(6,2);<br>
<span lang="ru">&nbsp; </span>Tag(6,2);<br>
<b>end</b>;</code></p>
<p><code><b>begin</b><br>
&nbsp; RegisterGroup('myrob','Ìîè çàäàíèÿ äëÿ Ðîáîòà','RobTasks',2);<br>
&nbsp; RegisterTask('myrob1',FirstRob);<br>
<b>end</b>.</code></p>
</blockquote>
<p><span lang="ru">Íàáåðåì è çàïóñòèì îñíîâíóþ ïðîãðàììó (ñîõðàíÿòü åå â êàêîì-ëèáî ôàéëå íå òðåáóåòñÿ):</span></p>
<blockquote>
<p><code><b>uses</b> Robot, RobTasks;<br>
<b>begin</b><br>
&nbsp; Task('myrob1');<br>
<b>end</b>.</code></p>
</blockquote>
<p>Áóäåò âûâåäåíî ñëåäóþùåå çàäàíèå äëÿ Ðîáîòà:
</p>
<p><img border="0" src="images/rbmake1.PNG"></p>
<p><span lang="ru">
Äîáàâèì çàäàíèå, â êîòîðîì êîíôèãóðàöèÿ ïîëÿ ñëó÷àéíà:</span></p>
<blockquote>
<p><code><b>procedure</b> SecondRob;<br>
<b>var</b> n,i: integer;<br>
<b>begin</b><br>
<span lang="ru">&nbsp; </span>TaskText('Çàäàíèå myrob2. Çàêðàñèòü êëåòêè ïîä çàêðàøåííûìè');<br>
<span lang="ru">&nbsp; </span>n:=Random(4)+7;<br>
<span lang="ru">&nbsp; </span>Field(n,4);<br>
<span lang="ru">&nbsp; </span>RobotBeginEnd(1,3,n,3);<br>
<span lang="ru">&nbsp; </span>MarkPainted(n,2);<br>
<span lang="ru">&nbsp; </span>Tag(n,3);<br>
<span lang="ru">&nbsp; </span><b>for</b> i:=2 <b>to</b> n-1 <b>do</b><br>
<span lang="ru">&nbsp;&nbsp;&nbsp; </span><b>if</b> Random(3)=1 <b>then</b><br>
<span lang="ru">&nbsp;&nbsp;&nbsp; </span><b>begin</b><br>
<span lang="ru">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>MarkPainted(i,2);<br>
<span lang="ru">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Tag(i,3);<br>
<span lang="ru">&nbsp;&nbsp;&nbsp; </span><b>end</b>;<br>
<b>end</b>;</code></p>
</blockquote>
<p>Äîáàâèì âûçîâ ïðîöåäóðû ðåãèñòðàöèè äëÿ äàííîãî çàäàíèÿ; â ðåçóëüòàòå ñåêöèÿ èíèöèàëèçàöèè ïðèìåò ñëåäóþùèé âèä:</p>
<blockquote>
<p><code><b>begin</b><br>
&nbsp; RegisterGroup('myrob','Ìîè çàäàíèÿ äëÿ Ðîáîòà','RobTasks',2);<br>
&nbsp; RegisterTask('myrob1',FirstRob);<br>
&nbsp; RegisterTask('myrob2',SecondRob);<br>
<b>end</b>.</code></p>
</blockquote>
<p><span lang="ru">Èçìåíèì îñíîâíóþ ïðîãðàììó:</span></p>
<blockquote>
<p><code><b>uses</b> Robot, RobTasks;<br>
<b>begin</b><br>
&nbsp; Task('myrob<span lang="ru">2</span>');<br>
<b>end</b>.</code></p>
</blockquote>
<p><span lang="ru">Ïðè çàïóñêå ýòîé ïðîãðàììû â îêíå èñïîëíèòåëÿ Ðîáîò áóäåò âûâåäåíî íîâîå çàäàíèå:</p>
<p><img border="0" src="images/rbmake2.PNG"></p>
<p>
Ïðè ïåðâîì çàïóñêå ïðîãðàììû ñ ïîäêëþ÷åííûì ìîäóëåì <code>DMTasks</code> ñîçäàííàÿ íàìè ãðóïïà áûëà àâòîìàòè÷åñêè çàðåãèñòðèðîâàíà
â ìàñòåðå ïî ñîçäàíèþ ïðîãðàìì-çàãîòîâîê <b>PT4Load</b>.
Åñëè òåïåðü íàæàòü êíîïêó&nbsp;<img border="0" src="images/load.gif" width="16" height="17">&nbsp;è â ïîÿâèâøåìñÿ îêíå
<b>PT4Load</b> ââåñòè ïðåôèêñ
</span><span lang="en-us"><code>RB</code></span><span lang="ru"> â ïîëå &laquo;Çàäàíèå&raquo;, òî îêíî ïðèìåò ñëåäóþùèé âèä:
&nbsp;</span></p>
<p><img border="0" src="images/rbmake3.PNG">
&nbsp;</p>
<p>Ìû âèäèì, ÷òî ãðóïïà çàäàíèé myrob ïîÿâèëàñü â ñïèñêå äîñòóïíûõ ãðóïï äëÿ èñïîëíèòåëÿ Ðîáîò. Íàáåðåì èìÿ çàäàíèÿ
<span lang="en-us"><code>myrob1</code></span>:</p>
<p><img border="0" src="images/rbmake4.PNG">
&nbsp;</p>
<p>Ïîñëå íàæàòèÿ <span lang="en-us">Enter </span>â ðàáî÷åì êàòàëîãå áóäåò ñîçäàí
íîâûé ôàéë <span lang="en-us">RBmyrob1.pas </span>ñî ñëåäóþùèì ñîäåðæèìûì:</p>
<blockquote>
<p><code><b>uses</b> Robot, RobTasks;<br>
<br>
<b>begin</b><br>
&nbsp; Task('myrob1');<br>
<br>
<b>end</b>.</code></p>
</blockquote>
<p>Ìîæíî ïðèñòóïàòü ê ðåøåíèþ ñîáñòâåííîðó÷íî ðàçðàáîòàííîé çàäà÷è :)</p>
</body>
</html>

View file

@ -0,0 +1,241 @@
BODY,
TABLE,
TD {
font-family: Arial, sans-serif;
background-color: #ffffff;
font-size: small;
}
code {
color: #000080;
font-size: small;
text-align: left
}
pre {
color: #000080;
font-size: small;
text-align: left
text-indent: 30pt;
margin-left: 30pt;
margin-top: 3pt;
margin-bottom: 0pt;
}
code.codeit {
color: #000000;
font-family: Times;
font-style: italic;
font-size: small;
text-align: left
}
H1 {
font-family: Arial, sans-serif;
font-weight: bold;
margin-top: 6pt;
margin-bottom: 6pt;
font-size: large;
color: #000080;
text-align: left
}
H2 {
font-family: Arial, sans-serif;
font-weight: bold;
font-style: italic;
margin-bottom: 2pt;
margin-top: 6pt;
font-size: medium;
color: #000080;
text-align: left
}
H3 {
font-family: Arial, sans-serif;
margin-bottom: 2pt;
margin-top: 6pt;
font-size: medium;
color: #000080;
text-align: left
}
H4 {
font-weight: bold;
margin-top: 6pt;
margin-bottom: 2pt;
font-size: small;
text-align: left
}
H5 {
font-size: 10.0pt;
}
H6 {
font-size: 10.0pt;
}
P {
margin-top: 3pt;
margin-bottom: 0pt;
font-family: Arial, sans-serif;
font-size: small;
text-indent: 30pt;
text-align: justify
}
P.task {
margin-top: 3pt;
margin-bottom: 0pt;
margin-left: 0pt;
margin-right: 0pt;
font-family: Arial, sans-serif;
font-size: small;
text-indent: 30pt;
text-align: justify;
border-style: solid;
border-width: 1pt;
}
P.remark {
margin-top: 3pt;
margin-bottom: 0pt;
margin-left: 30pt;
margin-right: 0pt;
font-family: Arial, sans-serif;
font-size: small;
text-indent: 0pt;
text-align: justify;
}
P.ris {
font-family: Arial;
margin-top: 3pt;
margin-bottom: 0pt;
font-family: Arial, sans-serif;
font-size: small;
color: #000080;
text-indent: 0pt;
text-align: center
}
H1.part {
color: #000000;
margin-top: 20pt;
margin-bottom: 20pt;
text-align: center
}
H1.part1 {
color: #000000;
margin-top: 80pt;
margin-bottom: 20pt;
text-align: center
}
H1.part2{
color: #000000;
font-size: medium;
margin-top: 0pt;
margin-bottom: 20pt;
text-align: center
}
H3.tit {
color: #000000;
margin-top: 10pt;
margin-bottom: 10pt;
text-align: center
}
H2.subpart {
color: #000000;
margin-bottom: 80pt;
margin-top: 20pt;
text-align: center
}
P.author {
margin-top: 0pt;
margin-bottom: 0pt;
font-family: Arial, sans-serif;
font-size: 9pt;
color: #000000;
text-indent: 0pt;
text-align: right
}
P.refs {
margin-top: 0pt;
margin-bottom: 3pt;
font-family: Arial, sans-serif;
font-size: 10pt;
color: #000000;
text-indent: 0pt;
text-align: center
}
P.foot {
margin-top: 0pt;
margin-bottom: 0pt;
font-family: Arial, sans-serif;
font-size: 9pt;
font-style: italic;
color: #000000;
text-indent: 0pt;
text-align: right
}
OL,
UL {
margin-top: 3pt;
margin-bottom: 0pt;
font-size: small;
font-family: Arial, sans-serif;
text-align: justify
}
SPAN.tsktitle
{
font-family: Arial, sans-serif;
font-weight: bold;
font-size: small;
}
P.tsk{text-align:justify;text-indent:-50;margin-top:5; margin-left:60;}
P.hnt{text-align:justify;margin-left:60;}
P.hntc{text-align:justify;margin-left:60;text-indent:0;margin-top:0;}
P.hntq{text-align:justify;margin-left: 60;margin-top:0;}
P.cmt{text-align:justify;margin-top:5;}
P.ttt{text-align:left;}
P.cnt{text-align:center;}
P.qte{
color: #000080;
font-size: small;
text-indent:0;
text-align:left;margin-left:120;margin-top:0;margin-bottom:0;}
blockquote{font-family: Arial, sans-serif;text-align:justify;margin-left:100;margin-top:0; margin-bottom:0;}
P.cmtc{text-align:justify;}
P.cmtq{text-align:justify;}
SUB{font-family: Arial, sans-serif;;font-size:x-small;}
SUP{font-family: Arial, sans-serif;;font-size:x-small;}

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Some files were not shown because too many files have changed in this diff Show more