adding working-tree-encoding attribute (#3325)

This commit is contained in:
samuraiGH 2025-11-07 16:12:31 +03:00 committed by GitHub
parent 9c3ffea1c4
commit cf1fd2982e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
456 changed files with 16882 additions and 16877 deletions

5
PABCNetHelp/.gitattributes vendored Normal file
View file

@ -0,0 +1,5 @@
*.html text working-tree-encoding=CP1251
*.hhp text working-tree-encoding=CP1251
*.hhk text working-tree-encoding=CP1251
*.hhc text working-tree-encoding=CP1251

View file

@ -7,78 +7,78 @@
</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>Стандартный модуль <a href="../LangGuide/PABCSystemUnit/_main.html">PABCSystem</a>, автоматически подключаемый к любой программе,
содержит огромное количество стандартных типов и подпрограмм, позволяющих писать
ясные и компактные программы. </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>
<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>Модуль растровой графики <a href="../PABCUnits/GraphWPF/index.html">GraphWPF</a> и модуль векторных графических объектов
<a href="../PABCUnits/WPFObjects/index.html">WPFObjects</a> и модуль трёхмерной
графики <a href="../PABCUnits/Graph3D/index.html">Graph3D</a> могут быть использованы для создания простейших графических. а также
интерактивных анимационных приложений, управляемых событиями.</p>
<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>Стандартный модуль <a href="../LangGuide/PABCSystemUnit/_main.html">PABCSystem</a>, автоматически подключаемый к любой программе,
содержит огромное количество стандартных типов и подпрограмм, позволяющих писать
ясные и компактные программы. </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>
<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>Модуль растровой графики <a href="../PABCUnits/GraphWPF/index.html">GraphWPF</a> и модуль векторных графических объектов
<a href="../PABCUnits/WPFObjects/index.html">WPFObjects</a> и модуль трёхмерной
графики <a href="../PABCUnits/Graph3D/index.html">Graph3D</a> могут быть использованы для создания простейших графических. а также
интерактивных анимационных приложений, управляемых событиями.</p>
</body>
</html>

View file

@ -7,118 +7,118 @@
</head>
<body>
<h1>Что такое .NET</h1>
<p>Платформа <b>Microsoft .NET</b> - это комплекс
программ, устанавливаемый поверх операционной системы и обеспечивающий
выполнение программ, написанных специально для .NET.
.NET-программы компактны, пользуются единым набором типов
данных и библиотек. Компания Microsoft активно развивает платформу
.NET, выпуская новые версии с расширенными
возможностями. На момент начала 2019 г. последней версией является
<h1>Что такое .NET</h1>
<p>Платформа <b>Microsoft .NET</b> - это комплекс
программ, устанавливаемый поверх операционной системы и обеспечивающий
выполнение программ, написанных специально для .NET.
.NET-программы компактны, пользуются единым набором типов
данных и библиотек. Компания Microsoft активно развивает платформу
.NET, выпуская новые версии с расширенными
возможностями. На момент начала 2019 г. последней версией является
.NET 4.7.1.</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>
<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#,
<li>Платформа .NET поддерживает множество
.NET-языков. В их числе C#,
Visual Basic.NET, <span lang="en-us">F</span>#,
управляемый C++,
управляемый 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>
<li>Любой .NET-язык содержит самые современные
языковые возможности: классы, свойства, полиморфизм, исключения, перегрузка
операций, легкое создание библиотек.</li>
<li>.NET-языки легко сочетаются друг с другом,
похожи друг на друга по синтаксическим конструкциям и системе типов.</li>
<li>Имеется обширная библиотека стандартных классов FCL.</li>
<li>.NET-приложения компактны.</li>
<li>Платформа .NET активно развивается фирмой
Microsoft, добавляются как новые языковые возможности,
так и новые библиотеки.</li>
<li>Компилятор .NET-языка создать значительно проще,
чем компилятор обычного языка.</li>
</ol>
<h2>Недостатки платформы .NET</h2>
<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>
<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>
<p>Отметим, что достоинства платформы .NET
многократно перекрывают ее недостатки.</p>
</body>
</html>

View file

@ -7,100 +7,100 @@
</head>
<body>
<H1>Отличия языка PascalABC.NET от Delphi</H1>
<h3>Добавлено</h3>
<H1>Отличия языка PascalABC.NET от Delphi</H1>
<h3>Добавлено</h3>
<ol>
<li>Операции <code>+=</code> <code>-=</code> для событий .NET и для процедурных
переменных.</li>
<li>Операции <code>+=</code> <code>-=</code> <code>*=</code> для целых и&nbsp;
<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>
для вещественных.</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>,
<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 :=
<li>Инициализация переменных: <code><b>var</b> a: integer :=
1</code>;</li>
<li>Инициализация переменных: <code><b>var</b> a :=
<li>Инициализация переменных: <code><b>var</b> a :=
1</code>;</li>
<li>Объявление локальных переменных в блоке.</li>
<li>Объявление параметра цикла в заголовке цикла: <code><b>for</b> <b>var</b>
<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>
<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>
<h3>Изменено</h3>
<ol>
<li>Только сокращенное вычисление логических выражений.</li>
<li>Другой синтаксис <code><b>foreach</b></code>.</li>
<li>Интерфейсы <code><b>interface</b></code> в стиле .NET.</li>
<li>Другой синтаксис перегрузки операций.</li>
<li>Статические методы классов вместо классовых методов. Отсутствие типа
<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>
<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>
<li>Запрет использования указателей на управляемую память.</li>
<li>Процедурные переменные (делегаты) вместо <code><b>procedure of</b>
object</code>.</li>
<li>С бестиповыми файлами <b><code>file</code></b>
можно работать с помощью процедур <code>Read</code>,
<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>
<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>
<h3>Отсутствует</h3>
<ol>
<li>Ключевые слова и директивы <code><b>packed threadvar inline asm exports unsafe resourcestring dispinterface in out absolute dynamic
<li>Ключевые слова и директивы <code><b>packed threadvar inline asm exports unsafe resourcestring dispinterface in out absolute dynamic
local platform requires 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>
и связанные с ними возможности.</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>
<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>Методы, связанные с сообщениями (<code><b>message</b></code>).</li>
<li>Вложенные определения классов.</li>
</ol>
</body>

View file

@ -14,265 +14,265 @@
<param name="Text" value="">
</OBJECT>
<H1>Коротко о главном</H1>
<p>Данный текст содержит краткий <b>обзор </b>
<b>особенностей</b> PascalABC.NET. </p>
<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 и Oxygene.</li>
<li>Мнение, что язык Паскаль устарел и утрачивает свои
позиции, основано на представлении о старом Паскале и старых средах
программирования (например, <span lang="en-us">Free Pascal </span>с его
несовременной консольной оболочкой). К сожалению, масса отечественной учебной литературы
<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>
<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 и Oxygene.</li>
<li>Мнение, что язык Паскаль устарел и утрачивает свои
позиции, основано на представлении о старом Паскале и старых средах
программирования (например, <span lang="en-us">Free Pascal </span>с его
несовременной консольной оболочкой). К сожалению, масса отечественной учебной литературы
<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>
<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> Переменные могут описываться внутри блока
<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), возвращающая случайное целое в диапазоне
и инициализироваться при описании. Это крайне удобно для промежуточных
переменных, а в 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>
Процедуру 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>
<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 работают именно с Unicode. Для совместимости функции
OrdAnsi и ChrAnsi работают в однобайтовой кодировке Windows.</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><b><a href="JavaScript:exam.TCard(212,0)">CharFunc.pas</a>.</b> Символы Char хранят Unicode и поэтому занимают 2 байта.
Функции Ord и Chr работают именно с Unicode. Для совместимости функции
OrdAnsi и ChrAnsi работают в однобайтовой кодировке Windows.</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>
<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
<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>
<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 и пространстве имен
<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(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, созданной на
полноценный .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>
<li><b><a href="JavaScript:exam.TCard(233,0)">CallNative.pas</a>.</b> PascalABC.NET позволяет легко вызывать функции
из обычных dll. </li>
</ol>
<p><b>Стандартные графические библиотеки</b></p>
<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>
<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>
<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 в классе или
записи, мы получаем возможность выводить их значения в процедуре
<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# и
<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><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>
<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>
<p><b>Стандартная </b><b>библиотека .NET</b></p>
<ol start=48>
<li><b><a href="JavaScript:exam.TCard(248,0)">DateTime.pas</a>.</b> Данный пример иллюстрирует применение класса DateTime из стандартной библиотеки
<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>
<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>

View file

@ -21,97 +21,97 @@
<param name="Text" value="">
</OBJECT>
<H1>Система PascalABC.NET</H1>
<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>
<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
<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>
<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
<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),
<a href="../LangGuide/Types/sequences.html">последовательности</a>,
<a href="../LangGuide/Types/tuples.html">кортежи</a>,
<a href="../LangGuide/Operations_Expressions/Slice.html">срезы</a>,
<a href="../LangGuide/FuncProgramming/lambdas.html">лямбда-выражения</a> и др.</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-сайт
<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),
<a href="../LangGuide/Types/sequences.html">последовательности</a>,
<a href="../LangGuide/Types/tuples.html">кортежи</a>,
<a href="../LangGuide/Operations_Expressions/Slice.html">срезы</a>,
<a href="../LangGuide/FuncProgramming/lambdas.html">лямбда-выражения</a> и др.</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>

View file

@ -8,9 +8,9 @@
<body>
<H1>Анимация без мерцания</H1>
Данная программа иллюстрирует применение процедур <code>LockDrawing</code> и
<code>Redraw</code> для реализации анимации без мерцания:
<H1>Анимация без мерцания</H1>
Данная программа иллюстрирует применение процедур <code>LockDrawing</code> и
<code>Redraw</code> для реализации анимации без мерцания:
<blockquote>
<pre>
<code><b>uses</b> GraphABC;
@ -28,13 +28,13 @@
</pre>
</blockquote>
<p>Основная идея состоит в следующем: отключим рисование на экране, вызвав <code>
LockDrawing</code> (рисование будет осуществляться только во внеэкранном
буфере), после чего будем всякий раз формировать новый кадр изображения и
выводить его целиком на экран, вызывая <code>Redraw</code>. При вызове <code>
Redraw</code> перерисовывается все графическое окно,
поэтому скорость анимации ограничена скоростью вывода внеэкранного буфера на
экран.</p>
<p>Основная идея состоит в следующем: отключим рисование на экране, вызвав <code>
LockDrawing</code> (рисование будет осуществляться только во внеэкранном
буфере), после чего будем всякий раз формировать новый кадр изображения и
выводить его целиком на экран, вызывая <code>Redraw</code>. При вызове <code>
Redraw</code> перерисовывается все графическое окно,
поэтому скорость анимации ограничена скоростью вывода внеэкранного буфера на
экран.</p>
</body>

View file

@ -8,8 +8,8 @@
<body>
<H1>Рисование мышью в графическом окне</H1>
Данная программа осуществляет рисование мышью в графическом окне:
<H1>Рисование мышью в графическом окне</H1>
Данная программа осуществляет рисование мышью в графическом окне:
<blockquote>
<pre>
<code><b>uses</b> GraphABC;<b>
@ -25,7 +25,7 @@
<b>end</b>;
<b><span style="font-size: 4pt">
</span>begin
</b> // Привязка обработчиков к событиям
</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>

View file

@ -7,8 +7,8 @@
</head>
<body>
<H1>Перемещение окна с помощью клавиатуры</H1>
Данная программа осуществляет перемещение графического окна с помощью клавиатуры:
<H1>Перемещение окна с помощью клавиатуры</H1>
Данная программа осуществляет перемещение графического окна с помощью клавиатуры:
<blockquote>
<pre>
@ -25,7 +25,7 @@
<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>

View file

@ -8,9 +8,9 @@
<body>
<H1>Пример использования таймера</H1>
Данная программа выводит 1 каждые 100 миллисекунд<span lang="en-us"> </span>в
течение 3 секунд:<blockquote>
<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">
@ -28,9 +28,9 @@
</pre>
</blockquote>
<p>Вызов <code>Sleep</code><span lang="en-us"> </span>здесь обязателен, иначе
программа после создания таймера сразу закончится, и обработчик таймера ни разу
не сработает.</p>
<p>Вызов <code>Sleep</code><span lang="en-us"> </span>здесь обязателен, иначе
программа после создания таймера сразу закончится, и обработчик таймера ни разу
не сработает.</p>
</body>

View file

@ -6,43 +6,43 @@
<link rel="StyleSheet" href="../../default.css">
</head>
<body>
<H1>Задание Begin3 из электронного задачника Programming Taskbook</H1>
<H1>Задание Begin3 из электронного задачника Programming Taskbook</H1>
<hr>
<p>Задание Begin3 относится к самой первой группе задачника, посвященной
знакомству с вводом-выводом и оператором присваивания.
Приведем формулировку этого задания.
<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>Далее по шагам опишем сценарий выполнения задания в системе
<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>
<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>Заметим, что эту программу не обязательно набирать вручную. Для автоматической генерации данной программы
выполним следующие действия. Нажмем кнопку
<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>
<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>
@ -52,14 +52,14 @@
<p>Запуск нашей программы был признан <i>ознакомительным</i> (и поэтому правильность решения не анализировалась),
так как в ходе ее выполнения не было совершено ни одной операции ввода-вывода.
<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><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>
@ -67,7 +67,7 @@
&nbsp; read(a, b);<br>
<b>end</b>.</code>
</blockquote>
<p>После запуска этого вариант программы окно задачник примет вид:</p>
<p>После запуска этого вариант программы окно задачник примет вид:</p>
<blockquote>
<img border="0" src="gif/Begin3-2.png">
@ -75,36 +75,36 @@
<p>Как видим, исходные данные поменялись и появилось сообщение
об ошибке &#151; переменные <code>a</code> и <code>b</code> должны быть объявлены как
вещественные. Если запуск программы не является ознакомительным, то в окне задачника
появляется раздел с полученными результатами
(в нашем случае он не содержит ни одного числа), а также панель индикаторов,
показывающих количество введенных и выведенных данных, а также число успешных тестовых запусков
программы.
<p>Как видим, исходные данные поменялись и появилось сообщение
об ошибке &#151; переменные <code>a</code> и <code>b</code> должны быть объявлены как
вещественные. Если запуск программы не является ознакомительным, то в окне задачника
появляется раздел с полученными результатами
(в нашем случае он не содержит ни одного числа), а также панель индикаторов,
показывающих количество введенных и выведенных данных, а также число успешных тестовых запусков
программы.
</p>
<hr>
<p><font color="#0000FF"><b><i>Шаг 3.</i> </b></font>Исправим тип исходных данных:</p>
<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>
<p>Вновь запустим программу:</p>
<blockquote>
<img border="0" src="gif/Begin3-3.png">
</blockquote>
<p>Электронный задачник предупреждает, что не выведен результат.
Обратите внимание на то, что для сообщений о различных видах ошибок используются
разные цвета (например, фиолетовый для ошибок, связанных с несоответствием типов,
и оранжевый для ошибок, связанных с вводом/выводом недостаточного числа данных).
<p>Электронный задачник предупреждает, что не выведен результат.
Обратите внимание на то, что для сообщений о различных видах ошибок используются
разные цвета (например, фиолетовый для ошибок, связанных с несоответствием типов,
и оранжевый для ошибок, связанных с вводом/выводом недостаточного числа данных).
</p>
<hr>
<p><font color="#0000FF"><b><i>Шаг 4.</i> </b></font>Проведем
вычисления и выведем результирующие данные, но в неверном порядке:</p>
<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>
@ -114,49 +114,49 @@
&nbsp; write(P, S)<br>
<b>end</b>.</code>
</blockquote>
<p>Вновь запустим программу:</p>
<p>Вновь запустим программу:</p>
<blockquote>
<img border="0" src="gif/Begin3-4.png">
</blockquote>
<p>Мы видим, что все требуемые исходные данные введены, все результаты выведены,
однако полученные результаты имеют неверные значения.
В случае ошибочного решения окно задачника всегда содержит раздел с примером
верного решения, чтобы можно было сравнить полученные и правильные результаты.</p>
<p>Мы видим, что все требуемые исходные данные введены, все результаты выведены,
однако полученные результаты имеют неверные значения.
В случае ошибочного решения окно задачника всегда содержит раздел с примером
верного решения, чтобы можно было сравнить полученные и правильные результаты.</p>
<hr>
<p><font color="#0000FF"><b><i>Шаг 5.</i> </b></font>Исправим
ошибку:</p>
<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>
<p>После запуска программы увидим следующее окно:</p>
<blockquote>
<img border="0" src="gif/Begin3-5.png">
</blockquote>
<p>Если решение является правильным, то дополнительный раздел с примером правильного
решения в окне не выводится.</p>
<p>Если решение является правильным, то дополнительный раздел с примером правильного
решения в окне не выводится.</p>
<hr>
<p><font color="#0000FF"><b><i>Шаг 6.</i> </b></font>Чтобы задание считалось выполненным, запустим
программу еще два раза. В результате в окне задачника появится сообщение «Задание
выполнено!»: </p>
<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>Поздравляем! Задание <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>

View file

@ -6,74 +6,74 @@
<link rel="StyleSheet" href="../../default.css">
</head>
<body>
<H1>Задание a1 для исполнителя Робот</H1>
<H1>Задание a1 для исполнителя Робот</H1>
<hr>
<p>Задание a1 относится к вводным заданиям, посвященным
знакомству с основными командами исполнителя Робот.
Приведем формулировку этого задания.
<p>Задание a1 относится к вводным заданиям, посвященным
знакомству с основными командами исполнителя Робот.
Приведем формулировку этого задания.
</p>
<p><b>a1</b>. Закрасить помеченные клетки.</p>
<p><b>a1</b>. Закрасить помеченные клетки.</p>
<blockquote>
<img border="0" src="gif/RBa1-1.png">
</blockquote>
<p>Опишем сценарий решения задания.</p>
<p>Опишем сценарий решения задания.</p>
<hr>
<p><font color="#0000FF"><b><i>Шаг 1.</i> </b></font>Подключим
к программе модуль <code>Robot</code> и вызовем в
начале программы процедуру <code>Task</code>, передав ей в
качестве параметра имя задания:</p>
<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>
<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>
<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>
<p>Запустим программу, после чего нажмем <b>Enter</b> или кнопку
«Пуск» чтобы Робот начал выполнять
заложенную в него программу:</p>
<blockquote>
<img border="0" src="gif/RBa1-3.png">
</blockquote>
<p>После окончания движения Робота осуществляется проверка, все
ли помеченные клетки закрашены и находится ли Робот в конечной клетке.
Если проверка дает отрицательный ответ, то задание не считается выполненным.</p>
<p>После окончания движения Робота осуществляется проверка, все
ли помеченные клетки закрашены и находится ли Робот в конечной клетке.
Если проверка дает отрицательный ответ, то задание не считается выполненным.</p>
<hr>
<p><font color="#0000FF"><b><i>Шаг 3.</i> </b></font>
Выполним неверную команду, в результате которой Робот врежется в
стенку:</p>
<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>
<p>После запуска программы и нажатия <b>Enter</b>
получим следующее окно:</p>
<blockquote>
<img border="0" src="gif/RBa1-4.png">
</blockquote>
<p>Заметим, что квадратный индикатор состояния Робота окрасился в красный цвет, а
последняя команда <code>Left</code> не выполнилась, так как
после фатальной ошибки Робот прекратил выполнение задания.</p>
<p>Заметим, что квадратный индикатор состояния Робота окрасился в красный цвет, а
последняя команда <code>Left</code> не выполнилась, так как
после фатальной ошибки Робот прекратил выполнение задания.</p>
<hr>
<p><font color="#0000FF"><b><i>Шаг 4.</i> </b></font>
Исправим ошибку и выполним задание до конца:</p>
<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>
@ -90,9 +90,9 @@
<blockquote>
<img border="0" src="gif/RBa1-5.png">
</blockquote>
<p>Последний рисунок не нуждается в комментариях.</p>
<p>Заметим, что сведения о выполненных заданиях
можно просмотреть, нажав кнопку
<p>Последний рисунок не нуждается в комментариях.</p>
<p>Заметим, что сведения о выполненных заданиях
можно просмотреть, нажав кнопку
<img border="0" src="../PT4/gif/results.gif" width="16" height="17">.</p>
<p>&nbsp;</p>

View file

@ -9,33 +9,33 @@
<body>
<a name="main"></a>
<h1>Задания, связанные с ЕГЭ по информатике
<h1>Задания, связанные с ЕГЭ по информатике
</h1>
<hr>
<h2>Пример 1. Простая задача на реализацию базовых алгоритмов
<h2>Пример 1. Простая задача на реализацию базовых алгоритмов
</h2>
<hr>
<p>Группа заданий ExamBegin посвящена базовым алгоритмическим задачам,
включенным в кодификатор ЕГЭ по информатике. Процесс выполнения подобных заданий мы рассмотрим на примере
одной из простых задач, связанных с нахождением максимумов и минимумов из двух, трех или четырех чисел
без использования массивов и циклов.
<p>Группа заданий ExamBegin посвящена базовым алгоритмическим задачам,
включенным в кодификатор ЕГЭ по информатике. Процесс выполнения подобных заданий мы рассмотрим на примере
одной из простых задач, связанных с нахождением максимумов и минимумов из двух, трех или четырех чисел
без использования массивов и циклов.
</p>
<p class="task">ExamBegin2&#176;. На вход подаются три вещественных числа; числа расположены в одной строке.
Вывести вначале минимальное, а затем максимальное из них. Каждое число должно выводиться на новой строке
и снабжаться комментарием: &#171;MIN=&#187; для минимального, &#171;MAX=&#187;
для максимального.
<p class="task">ExamBegin2&#176;. На вход подаются три вещественных числа; числа расположены в одной строке.
Вывести вначале минимальное, а затем максимальное из них. Каждое число должно выводиться на новой строке
и снабжаться комментарием: &#171;MIN=&#187; для минимального, &#171;MAX=&#187;
для максимального.
</p>
<hr>
<h3>Создание программы-заготовки и знакомство с заданием
<h3>Создание программы-заготовки и знакомство с заданием
</h3>
<p>Напомним, что программу-заготовку для решения этого задания можно создать с помощью
команды
меню &laquo;Модули | Создать шаблон программы&raquo;, кнопки
<img border="0" src="gif/Load.gif" width="16" height="17"> или клавиатурной
комбинации <b>Shift+Ctrl+L</b>. Приведем текст созданной заготовки:
<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;
@ -44,54 +44,54 @@
<b>end</b>.
</pre></code></blockquote>
<p>После запуска программы на экране появится <a href="../PT4/window.html">окно задачника</a>:
<p>После запуска программы на экране появится <a href="../PT4/window.html">окно задачника</a>:
</p>
<blockquote>
<img border="0" src="gif/ExamBegin2-1.png">
</blockquote>
<p>Обсудим особенности программы-заготовки и окна задачника.
<p>Обсудим особенности программы-заготовки и окна задачника.
</p>
<p>В программе-заготовке вместо модуля <code>PT4</code>
подключается модуль <code>PT4Exam</code>, специально предназначенный для использования при выполнении
заданий групп Exam. Данный модуль содержит реализацию единственной процедуры <code>Task</code>,
инициализирующей задание. Никакие дополнительные процедуры, связанные с вводом-выводом, в него не включены.
Это обусловлено тем, что ввод-вывод при выполнении заданий групп Exam надо выполнять, используя
<i>стандартные процедуры языка Pascal</i>.
<p>В программе-заготовке вместо модуля <code>PT4</code>
подключается модуль <code>PT4Exam</code>, специально предназначенный для использования при выполнении
заданий групп Exam. Данный модуль содержит реализацию единственной процедуры <code>Task</code>,
инициализирующей задание. Никакие дополнительные процедуры, связанные с вводом-выводом, в него не включены.
Это обусловлено тем, что ввод-вывод при выполнении заданий групп Exam надо выполнять, используя
<i>стандартные процедуры языка Pascal</i>.
</p>
<p>Основной особенностью окна задачника является то, что в разделе исходных данных отсутствуют данные,
выделенные желтым цветом (напомним, что желтый цвет используется для выделения данных, которые необходимо
вводить с помощью специальных процедур ввода задачника). Вместо этого в окне отображается
строка бирюзового цвета, содержащая числовые данные. Вид строки подчеркивает то обстоятельство,
что вводить данные требуется не с помощью специальных процедур ввода, имеющихся в задачнике,
а с помощью стандартных процедур языка Pascal. Отметим, что бирюзовый цвет используется в окне задачника
для отображения &laquo;внешних&raquo; данных (содержащихся в файлах или динамических структурах), доступ к которым
должен осуществляться с помощью стандартных средств используемого языка программирования.
<p>Основной особенностью окна задачника является то, что в разделе исходных данных отсутствуют данные,
выделенные желтым цветом (напомним, что желтый цвет используется для выделения данных, которые необходимо
вводить с помощью специальных процедур ввода задачника). Вместо этого в окне отображается
строка бирюзового цвета, содержащая числовые данные. Вид строки подчеркивает то обстоятельство,
что вводить данные требуется не с помощью специальных процедур ввода, имеющихся в задачнике,
а с помощью стандартных процедур языка Pascal. Отметим, что бирюзовый цвет используется в окне задачника
для отображения &laquo;внешних&raquo; данных (содержащихся в файлах или динамических структурах), доступ к которым
должен осуществляться с помощью стандартных средств используемого языка программирования.
</p>
<p>Пример верного решения выделяется серым цветом
(в отличие от &laquo;настоящих&raquo; результатов, выведенных программой учащегося, которые, как и входные данные,
выделяются бирюзовым цветом), однако <i>представление</i> выходных данных совпадает с
представлением входных: это набор строк,
содержащих числовые данные (дополненные комментариями). Вид данных в разделе результатов показывает,
что для их вывода, как и для ввода исходных данных, необходимо использовать стандартные процедуры языка Pascal.
<p>Пример верного решения выделяется серым цветом
(в отличие от &laquo;настоящих&raquo; результатов, выведенных программой учащегося, которые, как и входные данные,
выделяются бирюзовым цветом), однако <i>представление</i> выходных данных совпадает с
представлением входных: это набор строк,
содержащих числовые данные (дополненные комментариями). Вид данных в разделе результатов показывает,
что для их вывода, как и для ввода исходных данных, необходимо использовать стандартные процедуры языка Pascal.
</p>
<p>
<b>Примечание.</b>
Если вы уже выполняли задания, связанные с обработкой файлов, то можете заметить, что отображение данных
в заданиях групп Exam
в точности соответствует способу отображения содержимого <i>текстовых файлов</i>. Это совпадение не случайно.
На самом деле во всех заданиях групп Exam все исходные данные хранятся в специальном входном текстовом файле,
а все результаты должны записываться в специальный выходной текстовый файл. Однако при этом не требуется
выполнять особых действий, связанных с определением имен этих файлов, связыванием файлов с файловыми
переменными, открытием и закрытием файлов (все эти действия выполняются задачником автоматически).
Для программы, выполняющей задание, эти файлы играют роль <i>стандартных потоков ввода-вывода</i>,
поэтому для доступа к ним достаточно использовать обычные процедуры ввода-вывода языка Pascal.
<b>Примечание.</b>
Если вы уже выполняли задания, связанные с обработкой файлов, то можете заметить, что отображение данных
в заданиях групп Exam
в точности соответствует способу отображения содержимого <i>текстовых файлов</i>. Это совпадение не случайно.
На самом деле во всех заданиях групп Exam все исходные данные хранятся в специальном входном текстовом файле,
а все результаты должны записываться в специальный выходной текстовый файл. Однако при этом не требуется
выполнять особых действий, связанных с определением имен этих файлов, связыванием файлов с файловыми
переменными, открытием и закрытием файлов (все эти действия выполняются задачником автоматически).
Для программы, выполняющей задание, эти файлы играют роль <i>стандартных потоков ввода-вывода</i>,
поэтому для доступа к ним достаточно использовать обычные процедуры ввода-вывода языка Pascal.
</p>
<hr>
<h3>Ввод исходных данных и их обработка
<h3>Ввод исходных данных и их обработка
</h3>
<p>Приступим к выполнению задания. В данном случае следует использовать алгоритм, не требующий
применения массивов, поэтому опишем три простые переменные вещественного типа и введем в них исходные данные:
<p>Приступим к выполнению задания. В данном случае следует использовать алгоритм, не требующий
применения массивов, поэтому опишем три простые переменные вещественного типа и введем в них исходные данные:
</p>
<blockquote><code><pre><b>uses</b> PT4Exam;
<b>var</b>
@ -101,36 +101,36 @@
read(a, b, c);
<b>end</b>.
</pre></code></blockquote>
<p>Мы воспользовались стандартной процедурой ввода <code>read</code>, введя все три исходных числа за один ее вызов.
Этого же результата мы могли бы добиться и с помощью процедуры <code>readln</code>:
<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>Заметим, что использование <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>В этом случае уже после ввода первого числа произойдет автоматический переход на следующую строку
с исходными данными. Поэтому оставшиеся в первой строке числа будут пропущены, а поскольку
во второй строке &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>Приведенный пример показывает, что при организации ввода данных в заданиях групп Exam необходимо учитывать особенности
стандартных процедур <code>read</code> и <code>readln</code>.
</p>
<p>При запуске приведенного выше варианта программы вид окна не изменится, поскольку мы не вывели никаких данных.
В заданиях групп Exam запуск программы считается ознакомительным до тех пор, пока программа не выведет
хотя бы один элемент результирующих данных. Кроме того, задачник не контролирует,
каким образом программа читает исходные данные (например, мы могли бы ввести всю исходную строку
в переменную типа <code>string</code>, а затем &laquo;разобрать&raquo; эту строку, выделив из нее три числа
и преобразовав их к типу <code>real</code>). Отмеченные особенности характерны именно для заданий групп Exam,
в которых для ввода данных не используются специальные средства задачника.
<p>При запуске приведенного выше варианта программы вид окна не изменится, поскольку мы не вывели никаких данных.
В заданиях групп Exam запуск программы считается ознакомительным до тех пор, пока программа не выведет
хотя бы один элемент результирующих данных. Кроме того, задачник не контролирует,
каким образом программа читает исходные данные (например, мы могли бы ввести всю исходную строку
в переменную типа <code>string</code>, а затем &laquo;разобрать&raquo; эту строку, выделив из нее три числа
и преобразовав их к типу <code>real</code>). Отмеченные особенности характерны именно для заданий групп Exam,
в которых для ввода данных не используются специальные средства задачника.
</p>
<p>Реализуем алгоритм нахождения минимального и максимального элемента. Для этого опишем еще две
переменные <code>min</code> и <code>max</code> типа <code>real</code> и добавим в конец программы следующие операторы:
<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>
@ -148,63 +148,63 @@ readln(c);
<b>if</b> c &gt; max <b>then</b>
max := c;
</pre></code></blockquote>
<p>Таким образом, для одновременного нахождения минимального и максимального из трех чисел требуется
не более трех операций сравнения и не более трех операций присваивания.
<p>Таким образом, для одновременного нахождения минимального и максимального из трех чисел требуется
не более трех операций сравнения и не более трех операций присваивания.
</p>
<hr>
<h3>Вывод результатов и их форматирование
<h3>Вывод результатов и их форматирование
</h3>
<p>Осталось вывести полученные результаты. Вывод, как и ввод, следует выполнять с помощью стандартных процедур
языка Pascal, учитывая их особенности.
<p>Осталось вывести полученные результаты. Вывод, как и ввод, следует выполнять с помощью стандартных процедур
языка Pascal, учитывая их особенности.
</p>
<p>Вначале, в качестве примера, организуем вывод, не соответствующий условиям задачи. Для этого добавим в конец программы
следующий оператор:
<p>Вначале, в качестве примера, организуем вывод, не соответствующий условиям задачи. Для этого добавим в конец программы
следующий оператор:
</p>
<blockquote><code><pre>writeln(min, max);
</pre></code></blockquote>
<p>Приведем вид окна задачника при запуске полученной программы:
<p>Приведем вид окна задачника при запуске полученной программы:
</p>
<blockquote>
<img border="0" src="gif/ExamBegin2-2.png">
</blockquote>
<p>Мы видим, что минимум и максимум найдены правильно, однако выведены не в том формате,
который требовался (требуемый формат приводится в разделе с примером верного решения).
Мы допустили при выводе три ошибки: во-первых, вывели оба числа в одной строке
(при этом они &laquo;слились&raquo;, поскольку мы не предусмотрели вывод пробела-разделителя), во-вторых,
не снабдили числа комментариями и, в-третьих, не настроили их отображение в формате
с двумя дробными знаками (первое число было выведено с единственным знаком после точки).
<p>Мы видим, что минимум и максимум найдены правильно, однако выведены не в том формате,
который требовался (требуемый формат приводится в разделе с примером верного решения).
Мы допустили при выводе три ошибки: во-первых, вывели оба числа в одной строке
(при этом они &laquo;слились&raquo;, поскольку мы не предусмотрели вывод пробела-разделителя), во-вторых,
не снабдили числа комментариями и, в-третьих, не настроили их отображение в формате
с двумя дробными знаками (первое число было выведено с единственным знаком после точки).
</p>
<p>
<b>Примечание.</b> Следует обратить внимание на панель индикаторов, которая отображается между информационной панелью
и разделом с формулировкой задания в случае, если запуск программы не является
ни демонстрационным, ни ознакомительным. Обычно на этой панели выводятся три индикатора: первый указывает
количество введенных исходных данных, второй &#151; количество выведенных результатов, а третий &#151;
количество успешно пройденных тестовых испытаний. При выполнении заданий, связанных с ЕГЭ, первые два
индикатора являются неактивными, поскольку, как было отмечено выше, для получения исходных данных
и записи результатов не используются средства задачника, и поэтому он не в состоянии
проконтролировать каждую операцию ввода-вывода.
<b>Примечание.</b> Следует обратить внимание на панель индикаторов, которая отображается между информационной панелью
и разделом с формулировкой задания в случае, если запуск программы не является
ни демонстрационным, ни ознакомительным. Обычно на этой панели выводятся три индикатора: первый указывает
количество введенных исходных данных, второй &#151; количество выведенных результатов, а третий &#151;
количество успешно пройденных тестовых испытаний. При выполнении заданий, связанных с ЕГЭ, первые два
индикатора являются неактивными, поскольку, как было отмечено выше, для получения исходных данных
и записи результатов не используются средства задачника, и поэтому он не в состоянии
проконтролировать каждую операцию ввода-вывода.
</p>
<p>Для исправления первых двух ошибок достаточно изменить вывод следующим образом:
<p>Для исправления первых двух ошибок достаточно изменить вывод следующим образом:
</p>
<blockquote><code><pre>writeln('MIN=', min);
writeln('MAX=', max);
</pre></code></blockquote>
<p>Однако в этом случае числа по-прежнему могут содержать неверное число дробных знаков.
Для исправления этой последней ошибки проще всего использовать
<i>атрибуты форматирования</i>, начинающиеся с символа &laquo;:&raquo; (двоеточие):
<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>Первый атрибут определяет <i>ширину поля вывода</i> (если ширина равна 0, то используется минимально
необходимое поле вывода). Наличие второго атрибута (допустимого только для вещественных чисел) означает,
что число надо вывести в формате с фиксированной точкой, причем его значение равно количеству дробных знаков.
</p>
<p>При запуске исправленной программы будет выведено сообщение о верном решении, а после трех
запусков &#151; сообщение о том, что задание выполнено:
<p>При запуске исправленной программы будет выведено сообщение о верном решении, а после трех
запусков &#151; сообщение о том, что задание выполнено:
</p>
<blockquote>
@ -212,48 +212,48 @@ writeln('MAX=', max:0:2);
</blockquote>
<p>В случае успешного прохождения тестового испытания в окно задачника не включается
раздел с примером верного решения, поскольку данные этого раздела совпадают
с результатами, полученными программой.
<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 можно вводить и выводить элементы данных несколькими способами, с использованием переменных
различных типов; например, исходную строку можно либо сразу прочесть в строковую переменную, либо вводить
посимвольно в цикле (в других группах заданий проводится более строгая проверка на соответствие типа переменной
типу элемента исходных или результирующих данных).
<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>Пример 2. Ввод и вывод массивов
</h2>
<hr>
<p>Рассмотрим еще одно задание группы ExamBegin, особенностью которого является вывод в качестве результата
элементов двумерного массива.
<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 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>При запуске программы-заготовки, созданной для этого задания, окно задачника примет следующий вид:
</p>
<blockquote>
@ -261,36 +261,36 @@ writeln('MAX=', max:0:2);
</blockquote>
<p>Анализируя исходные данные, можно заметить, что полученная матрица должна иметь 8 строк, тогда как
на экране отображаются только первые пять.
Это связано с тем, что по умолчанию используется режим &laquo;свернутого&raquo; отображения данных, при котором
на экране выводится только несколько начальных строк. Признаком того, что имеются данные,
не выведенные на экране, является кнопка, которая отображается в правом верхнем углу раздела исходных данных
(на этой кнопке изображается стилизованная стрелка, направленная вниз).
Для вывода всех данных достаточно нажать эту кнопку; можно также нажать клавишу <b>Ins</b> или выполнить
щелчок мышью в любом месте раздела с данными задания (кроме раздела, содержащего формулировку).
Если выполнить эти действия для нашего окна, то оно изменится следующим образом:</p>
<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>Повторный щелчок мышью, нажатие клавиши <b>Ins</b> или кнопки (на которой в данной ситуации будет отображаться
стрелка, направленная вверх &#151; см. рисунок) восстанавливает &laquo;сокращенное&raquo;
отображение данных. Заметим, что в режиме &laquo;сокращенного&raquo; отображения нумеруется только первая строка данных,
а в режиме полного отображения нумерацией снабжаются все строки.</p>
<p>
<a href="#scroll">Дополнительные возможности</a>, связанные с просмотром
данных большого размера, будут описаны далее, в пункте, посвященном задачам повышенной сложности.
<a href="#scroll">Дополнительные возможности</a>, связанные с просмотром
данных большого размера, будут описаны далее, в пункте, посвященном задачам повышенной сложности.
</p>
<p>Если закрыть окно задачника, находясь в режиме отображения всех данных,
то при последующих запусках программы окно будет сразу отображаться в этом режиме.
<p>Если закрыть окно задачника, находясь в режиме отображения всех данных,
то при последующих запусках программы окно будет сразу отображаться в этом режиме.
</p>
<p>Приведем вариант правильного решения данной задачи (в этом варианте учитывается, что результирующий
двумерный массив имеет не более 10 строк и столбцов; соответствующее условие приведено в
преамбуле к описанию
группы ExamBegin):
<p>Приведем вариант правильного решения данной задачи (в этом варианте учитывается, что результирующий
двумерный массив имеет не более 10 строк и столбцов; соответствующее условие приведено в
преамбуле к описанию
группы ExamBegin):
</p>
<blockquote><code><pre><b>uses</b> PT4Exam;
@ -315,67 +315,67 @@ writeln('MAX=', max:0:2);
<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>В приведенном решении следует обратить особое внимание на организацию ввода-вывода.
Укажем две особенности, связанные с вводом. Во-первых, несмотря
на то что по условию число <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>При выводе полученного двумерного массива необходимо обеспечить его правильное <i>форматирование</i>:
каждый элемент должен выводиться на семи экранных позициях с двумя дробными знаками и, кроме того,
каждая строка массива должна выводиться на новой экранной строке. Это достигается за счет использования
соответствующих атрибутов форматирования и явного перехода на новую строку с помощью процедуры
<code>writeln</code> без параметров.
</p>
<p>
<b>Примечание.</b>
Заметим, что в заданиях группы Matrix,
также посвященной обработке двумерных массивов, специальные действия по форматированию полученных массивов
выполнять не требуется, так как задачник автоматически форматирует все полученные результаты.
Таким образом, задания группы ExamBegin &laquo;более приближены&raquo; к реальной экзаменационной ситуации,
в которой программа учащегося должна не только обрабатывать исходные данные, но и обеспечивать наглядное
отображение результатов.
<b>Примечание.</b>
Заметим, что в заданиях группы Matrix,
также посвященной обработке двумерных массивов, специальные действия по форматированию полученных массивов
выполнять не требуется, так как задачник автоматически форматирует все полученные результаты.
Таким образом, задания группы ExamBegin &laquo;более приближены&raquo; к реальной экзаменационной ситуации,
в которой программа учащегося должна не только обрабатывать исходные данные, но и обеспечивать наглядное
отображение результатов.
</p>
<hr>
<a name="taskc"></a>
<h2>Пример 3. Обработка сложных наборов данных
<h2>Пример 3. Обработка сложных наборов данных
</h2>
<hr>
<p>Группа ExamTaskC содержит 100 типовых заданий, аналогичных заданиям,
которые предлагаются на ЕГЭ по информатике
в качестве задач повышенной сложности (задача C4). Основную часть данной группы составляют
задания на обработку сложных наборов данных (записей) с элементами-полями различных типов.
В подобных заданиях требуется правильно выбрать способ хранения данных и организовать их эффективную обработку;
при этом обычно требуется применить <i>несколько</i> базовых алгоритмов, например, алгоритм суммирования
или нахождения минимума/максимума и алгоритм поиска нужного элемента или сортировки набора данных по требуемому ключу.
В группу ExamTaskC включены также задания повышенной сложности на обработку текстовых данных
(подобные задания содержатся в завершающем разделе данной группы).
<p>Группа ExamTaskC содержит 100 типовых заданий, аналогичных заданиям,
которые предлагаются на ЕГЭ по информатике
в качестве задач повышенной сложности (задача C4). Основную часть данной группы составляют
задания на обработку сложных наборов данных (записей) с элементами-полями различных типов.
В подобных заданиях требуется правильно выбрать способ хранения данных и организовать их эффективную обработку;
при этом обычно требуется применить <i>несколько</i> базовых алгоритмов, например, алгоритм суммирования
или нахождения минимума/максимума и алгоритм поиска нужного элемента или сортировки набора данных по требуемому ключу.
В группу ExamTaskC включены также задания повышенной сложности на обработку текстовых данных
(подобные задания содержатся в завершающем разделе данной группы).
</p>
<p>Следует заметить, что возможность автоматической генерации
больших наборов исходных данных, предоставляемая задачником Programming Taskbook, позволяет существенно ускорить
тестирование учебных программ и сделать его более надежным, что, в свою очередь, повышает эффективность изучения
типовых приемов решения задач группы C.
<p>Следует заметить, что возможность автоматической генерации
больших наборов исходных данных, предоставляемая задачником Programming Taskbook, позволяет существенно ускорить
тестирование учебных программ и сделать его более надежным, что, в свою очередь, повышает эффективность изучения
типовых приемов решения задач группы C.
</p>
<p>В заданиях группы ExamTaskC ввод и вывод имеет те же особенности,
что и в заданиях группы ExamBegin.
<p>В заданиях группы ExamTaskC ввод и вывод имеет те же особенности,
что и в заданиях группы ExamBegin.
</p>
<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 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>Программа-заготовка, созданная для этого задания, подобно заготовкам для заданий группы ExamBegin,
будет использовать специальный модуль <code>PT4Exam</code>:
</p>
<blockquote><code><pre><b>uses</b> PT4Exam;
@ -386,49 +386,49 @@ writeln('MAX=', max:0:2);
<b>end</b>.
</pre></code></blockquote>
<p>При запуске этой программы на экране появится окно задачника, содержащее следующие данные:
<p>При запуске этой программы на экране появится окно задачника, содержащее следующие данные:
</p>
<blockquote>
<img border="0" src="gif/ExamTaskC25-1.png">
</blockquote>
<p>Окно будет иметь такой вид, если при его предшествующем закрытии оно находилось в режиме
отображения всех данных.
Для отображения всех данных на экране может потребоваться увеличить высоту окна; для этого достаточно
зацепить мышью заголовок окна и переместить его вверх (для перемещения заголовка окна задачника вверх и вниз
можно также воспользоваться клавиатурными комбинациями <b>Ctrl+Up</b> и <b>Ctrl+Down</b>).
<p>Окно будет иметь такой вид, если при его предшествующем закрытии оно находилось в режиме
отображения всех данных.
Для отображения всех данных на экране может потребоваться увеличить высоту окна; для этого достаточно
зацепить мышью заголовок окна и переместить его вверх (для перемещения заголовка окна задачника вверх и вниз
можно также воспользоваться клавиатурными комбинациями <b>Ctrl+Up</b> и <b>Ctrl+Down</b>).
</p>
<p>При первом тестовом испытании программы ей будет предложен для обработки
набор данных не слишком большого размера (порядка 10&#150;20 элементов).
<p>При первом тестовом испытании программы ей будет предложен для обработки
набор данных не слишком большого размера (порядка 10&#150;20 элементов).
</p>
<p>Вначале следует определиться со структурами данных, которые будут использоваться в программе. Поскольку
требуется найти одну характеристику для каждого года, а число лет невелико, можно использовать
числовой массив <code>year</code>, каждый элемент которого соответствует определенному году. Так как в языке Pascal можно
использовать произвольные границы индексов, удобно в качестве диапазона индексов указать диапазон лет,
который требуется проанализировать: <code>1990..2010</code>. В начале программы выполним инициализацию элементов массива,
положив их значения равными <code>0</code>
(заметим, что если после обработки исходных данных некоторые элементы массива <code>year</code>
останутся нулевыми, то это будет означать, что соответствующие годы не были представлены в наборе исходных данных,
и выводить информацию о них не следует).
<p>Вначале следует определиться со структурами данных, которые будут использоваться в программе. Поскольку
требуется найти одну характеристику для каждого года, а число лет невелико, можно использовать
числовой массив <code>year</code>, каждый элемент которого соответствует определенному году. Так как в языке Pascal можно
использовать произвольные границы индексов, удобно в качестве диапазона индексов указать диапазон лет,
который требуется проанализировать: <code>1990..2010</code>. В начале программы выполним инициализацию элементов массива,
положив их значения равными <code>0</code>
(заметим, что если после обработки исходных данных некоторые элементы массива <code>year</code>
останутся нулевыми, то это будет означать, что соответствующие годы не были представлены в наборе исходных данных,
и выводить информацию о них не следует).
</p>
<p>После инициализации массива следует прочесть информацию о количестве абитуриентов и организовать цикл,
в котором будут обрабатываться данные о каждом абитуриенте и соответствующим образом корректироваться
элементы массива <code>year</code>. В дальнейшем сведения об уже обработанном абитуриенте нам не будут нужны, поэтому сохранять
их в специальном наборе данных (например, массиве) не требуется. Заметим также, что фамилия абитуриента
для решения задачи не требуется, поэтому после чтения двух числовых данных можно сразу переходить к новой строке,
пропуская строковый элемент данных (фамилию). В задаче не нужно использовать
и номера школ, однако их придется считывать, так как только после номера школы указывается интересующий
нас год поступления абитуриента.
<p>После инициализации массива следует прочесть информацию о количестве абитуриентов и организовать цикл,
в котором будут обрабатываться данные о каждом абитуриенте и соответствующим образом корректироваться
элементы массива <code>year</code>. В дальнейшем сведения об уже обработанном абитуриенте нам не будут нужны, поэтому сохранять
их в специальном наборе данных (например, массиве) не требуется. Заметим также, что фамилия абитуриента
для решения задачи не требуется, поэтому после чтения двух числовых данных можно сразу переходить к новой строке,
пропуская строковый элемент данных (фамилию). В задаче не нужно использовать
и номера школ, однако их придется считывать, так как только после номера школы указывается интересующий
нас год поступления абитуриента.
</p>
<p>Когда данные обо всех абитуриентах будут обработаны,
в массиве <code>year</code> будет содержаться вся необходимая информация, которую останется
вывести в формате, указанном в условии задачи.
<p>Когда данные обо всех абитуриентах будут обработаны,
в массиве <code>year</code> будет содержаться вся необходимая информация, которую останется
вывести в формате, указанном в условии задачи.
</p>
<p>Приведем первый вариант решения (этот вариант содержит одну ошибку):
<p>Приведем первый вариант решения (этот вариант содержит одну ошибку):
</p>
<blockquote><code><pre><b>uses</b> PT4Exam;
@ -442,7 +442,7 @@ writeln('MAX=', max:0:2);
readln(n);
<b>for</b> i := 1 <b>to</b> n <b>do</b>
<b>begin</b>
readln(k, m); <i>{ k - номер школы, m - год поступления }</i>
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>
@ -450,17 +450,17 @@ writeln('MAX=', max:0:2);
<b>end</b>.
</pre></code></blockquote>
<p>Ошибка связана с тем, что на экран выводится информация о годах, отсутствующих в наборе исходных данных.
Поэтому она сразу будет выявлена при обработке наборов данных небольшого размера,
предлагаемых программе при первом тестовом запуске
(для большей наглядности приведем окно задачника в режиме сокращенного отображения данных, при котором
выводятся только пять первых элементов из каждого набора данных):
<p>Ошибка связана с тем, что на экран выводится информация о годах, отсутствующих в наборе исходных данных.
Поэтому она сразу будет выявлена при обработке наборов данных небольшого размера,
предлагаемых программе при первом тестовом запуске
(для большей наглядности приведем окно задачника в режиме сокращенного отображения данных, при котором
выводятся только пять первых элементов из каждого набора данных):
</p>
<blockquote>
<img border="0" src="gif/ExamTaskC25-2.png">
</blockquote>
<p>Для исправления ошибки достаточно добавить в последний цикл условный оператор:
<p>Для исправления ошибки достаточно добавить в последний цикл условный оператор:
</p>
<blockquote><code><pre><b>for</b> i := 1990 <b>to</b> 2010 <b>do</b>
@ -469,129 +469,129 @@ writeln('MAX=', max:0:2);
</pre></code></blockquote>
<p>Теперь все 9 тестовых испытаний программы, требуемых для того, чтобы решение было зачтено как выполненное,
будут пройдены успешно.
<p>Теперь все 9 тестовых испытаний программы, требуемых для того, чтобы решение было зачтено как выполненное,
будут пройдены успешно.
</p>
<a name="scroll"></a><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>Начиная со второго испытания,
программе может быть предложен для обработки набор исходных данных большего размера (порядка 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>Помимо стандартных действий по прокрутке данных, в окне задачника предусмотрены возможности
&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>
<p>Кроме трех кнопок, связанных с &laquo;интеллектуальной&raquo; прокруткой,
в приведенном на рисунке окне отображаются еще две дополнительные кнопки.
Первая из них располагается в правом верхнем углу раздела с формулировкой
и позволяет временно скрыть (а в дальнейшем опять отобразить)
раздел с формулировкой (эти же действия можно выполнить с помощью клавиши <b>Del</b> или щелчка мышью
на разделе с формулировкой).
Вторая дополнительная кнопка расположена в правом верхнем углу раздела с исходными данными.
Как уже отмечалось ранее, эта кнопка позволяет переключаться между полным
и сокращенным отображением наборов данных. Напомним, что
изображение на этой кнопке показывает текущий режим отображения данных. Например, если на кнопке изображена
стилизованная стрелка, направленная вверх (как на приведенном выше рисунке),
значит, в данный момент в окне отображаются все данные, а нажатие на эту кнопку переведет окно
в режим отображения нескольких начальных (как правило, пяти) элементов каждого набора данных.
<p>Кроме трех кнопок, связанных с &laquo;интеллектуальной&raquo; прокруткой,
в приведенном на рисунке окне отображаются еще две дополнительные кнопки.
Первая из них располагается в правом верхнем углу раздела с формулировкой
и позволяет временно скрыть (а в дальнейшем опять отобразить)
раздел с формулировкой (эти же действия можно выполнить с помощью клавиши <b>Del</b> или щелчка мышью
на разделе с формулировкой).
Вторая дополнительная кнопка расположена в правом верхнем углу раздела с исходными данными.
Как уже отмечалось ранее, эта кнопка позволяет переключаться между полным
и сокращенным отображением наборов данных. Напомним, что
изображение на этой кнопке показывает текущий режим отображения данных. Например, если на кнопке изображена
стилизованная стрелка, направленная вверх (как на приведенном выше рисунке),
значит, в данный момент в окне отображаются все данные, а нажатие на эту кнопку переведет окно
в режим отображения нескольких начальных (как правило, пяти) элементов каждого набора данных.
</p>
<p>Дополнительная информация о возможностях
режима окна с динамической компоновкой приведена в <a href="../PT4/window.html#dynmode">соответствующем разделе</a>
страницы, посвященной описанию окна задачника.
<p>Дополнительная информация о возможностях
режима окна с динамической компоновкой приведена в <a href="../PT4/window.html#dynmode">соответствующем разделе</a>
страницы, посвященной описанию окна задачника.
</p>
<hr>
<h2>Пример 4. Более сложное задание на обработку наборов данных
<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 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>Приведем окно задачника, которое появится на экране при запуске программы-заготовки для данного задания
(в данном окне скрыт раздел с формулировкой; в результате оказались скрытыми и кнопки,
отвечающие за &laquo;интеллектуальную&raquo; прокрутку, поскольку в окне полностью отображается
содержимое оставшихся разделов):
</p>
<blockquote>
<img border="0" src="gif/ExamTaskC53-1.png">
</blockquote>
<p>Выясним, какая структура является наиболее подходящей для хранения информации, необходимой для решения задачи.
Нам требуется информация, связанная с различными улицами, которых по условию не более 30, причем для каждой улицы
надо хранить сведения двух видов: ее название и максимальную цену бензина марки <i>M</i>. Поэтому мы можем либо завести
массив из 30 элементов-записей с двумя полями, либо два массива: один содержащий названия улиц, а другой &#151;
максимальные цены. Учитывая, что в конце программы нам потребуется выполнять сортировку полученных данных,
целесообразнее использовать массив записей, поскольку это позволит записать алгоритм сортировки
в более компактной форме.
<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>Определим запись <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>При обработке каждой строки с исходными данными нам будут нужны прежде всего сведения о марке бензина.
Если марка бензина не равна <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>Если улица с названием <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>Для ввода названий улиц и компаний в нашем случае удобно организовать <i>посимвольное</i> чтение строковых данных;
признаком завершения такого чтения будет обнаружение пробельного символа.
</p>
<p>После обработки набора исходных данных необходимо проверить, найдена ли хотя бы одна улица с АЗС,
предлагающей марку бензина <code>M</code> (для этого достаточно сравнить значение <code>ns</code> с нулем). Если ни одна улица
не найдена, то надо вывести строку &laquo;Нет&raquo;; в противном случае требуется выполнить сортировку
массива <code>s</code> по указанному набору ключей и вывести полученные данные в требуемом порядке. Поскольку размер
массива невелик, для его сортировки вполне допустимо использовать один из простых алгоритмов,
например, алгоритм <i>пузырьковой сортировки</i>.
<p>После обработки набора исходных данных необходимо проверить, найдена ли хотя бы одна улица с АЗС,
предлагающей марку бензина <code>M</code> (для этого достаточно сравнить значение <code>ns</code> с нулем). Если ни одна улица
не найдена, то надо вывести строку &laquo;Нет&raquo;; в противном случае требуется выполнить сортировку
массива <code>s</code> по указанному набору ключей и вывести полученные данные в требуемом порядке. Поскольку размер
массива невелик, для его сортировки вполне допустимо использовать один из простых алгоритмов,
например, алгоритм <i>пузырьковой сортировки</i>.
</p>
<p>Приведем один из вариантов правильного решения задачи:
<p>Приведем один из вариантов правильного решения задачи:
</p>
<blockquote><code><pre><b>uses</b> PT4Exam;
@ -608,39 +608,39 @@ writeln('MAX=', max:0:2);
c: char;
<b>begin</b>
Task('ExamTaskC53');
readln(m); <i>{ m - марка бензина }</i>
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>
readln <i>{ пропускаем оставшуюся часть строки }</i>
<b>else</b>
<b>begin</b>
s0 := '';
read(c); <i>{ пропускаем пробел после первого числа }</i>
read(c); <i>{ читаем первый символ названия улицы }</i>
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>
read(c); <i>{ читаем первый символ названия компании }</i>
<b>while</b> c &lt;&gt; ' ' <b>do</b>
read(c); <i>{ название компании не сохраняем }</i>
readln(p); <i>{ читаем цену бензина и переходим на новую строку }</i>
<i>{ Обработка прочитанной информации }</i>
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>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>if</b> k = 0 <b>then</b> <i>{ улица еще не содержится в массиве s }</i>
<b>begin</b>
Inc(ns);
s[ns].name := s0;
@ -648,12 +648,12 @@ writeln('MAX=', max:0:2);
<b>end</b>;
<b>end</b>;
<b>end</b>;
<b>if</b> ns = 0 <b>then</b> <i>{ ни одной улицы не найдено }</i>
writeln('Нет')
<b>if</b> ns = 0 <b>then</b> <i>{ ни одной улицы не найдено }</i>
writeln('Нет')
<b>else</b>
<b>begin</b>
<i>{ Сортировка по возрастанию максимальной цены,</i>
<i> а для одинаковых цен - по названиям улиц }</i>
<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>
@ -664,7 +664,7 @@ writeln('MAX=', max:0:2);
s[i] := s[i + 1];
s[i + 1] := x;
<b>end</b>;
<i>{ Вывод результатов в требуемом порядке }</i>
<i>{ Вывод результатов в требуемом порядке }</i>
<b>for</b> i := 1 <b>to</b> ns <b>do</b>
writeln(s[i].max,' ',s[i].name);
<b>end</b>;

View file

@ -7,17 +7,17 @@
</head>
<body>
<H1>Задание на обработку файлов</H1>
<H1>Задание на обработку файлов</H1>
<hr>
<h3>Создание программы-заготовки и знакомство с заданием</h3>
<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>В качестве примера задания на обработку файлов рассмотрим задание File48.</p>
<p>Напомним, что программу-заготовку для решения этого задания можно создать с помощью
команды
меню &laquo;Модули | Создать шаблон программы&raquo;, кнопки
<img border="0" src="gif/Load.gif" width="16" height="17"> или клавиатурной
комбинации <b>Shift+Ctrl+L</b>. Эта заготовка будет иметь следующий вид:
</p>
<blockquote>
@ -30,36 +30,36 @@
<b>end</b>.</pre></code>
</blockquote>
<p>После запуска данной программы на экране появится <a href="../PT4/window.html">окно задачника</a>:</p>
<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>В первой строке раздела исходных данных указаны имена трех исходных файлов (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>
<h3>Ввод части исходных данных</h3>
<p>Добавим в программу фрагмент, позволяющий ввести имена исходных файлов и связать с этими файлами соответствующие
файловые переменные. Поскольку мы собираемся работать с четырьмя файлами одного типа, удобно предусмотреть <i>массив</i>
для хранения всех файловых переменных:</p>
<blockquote>
<code><pre>
@ -79,44 +79,44 @@
</blockquote>
<p>Мы намеренно ограничились <i>тремя</i> итерациями цикла, оставив непрочитанным имя результирующего файла.
Считывание имен файлов производится в одну и ту же переменную <code>s</code>, поскольку после связывания файла,
имеющего имя <code>s</code>,
с соответствующей файловой переменной (процедурой <code>Assign</code>) все остальные действия
с данным файлом в нашей программе
будут осуществляться с использованием файловой переменной, без обращения к имени файла.</p>
<p>Запуск нового варианта программы уже не будет считаться ознакомительным, поскольку в программе
выполняется ввод исходных данных. Так как имя результирующего файла осталось непрочитанным, этот вариант
решения будет признан неверным и приведет к сообщению &laquo;<i>Введены не все требуемые исходные данные</i>&raquo;:</p>
<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>При этом на экране появится раздел результатов (кроме комментария он пока ничего не содержит),
а также панель индикаторов. Первый из индикаторов
(индикатор ввода) показывает
количество введенных исходных данных. Обратите внимание на то, что второй индикатор
(индикатор вывода) является неактивным: он выделяется серым цветом более светлого
оттенка и не содержит текстового заголовка.
Это объясняется тем, что индикатор вывода показывает количество результирующих данных,
полученных задачником от программы, а в нашем случае программа
не должна передавать задачнику никакие данные; вместо этого ей необходимо создать файл и заполнить его
требуемыми значениями. Для заданий подобного типа (обычно это задания, связанные с обработкой файлов)
индикатор вывода не используется.
</p>
<hr>
<h3>Ввод всех исходных данных без создания требуемого файла</h3>
<p>Изменим программу, заменив в заголовке цикла число <code>3</code> на <code>4</code>, и вновь запустим программу. Теперь все данные,
необходимые для выполнения задания, введены в программу (это видно по индикатору ввода). Однако задание не выполнено, поскольку результирующий файл
не создан. Поэтому решение опять признано ошибочным с диагностикой &laquo;<i>Результирующий файл не найден</i>&raquo;:</p>
<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>
<h3>Пример программы, приводящей к ошибке времени выполнения</h3>
<p>Добавим в тело цикла после процедуры <code>Assign</code> вызов процедуры <code>Reset</code>, обеспечивающий открытие существующего файла:</p>
<blockquote>
<code><pre>
<b>uses</b> PT4;
@ -135,28 +135,28 @@
<b>end</b>. </pre></code>
</blockquote>
<p>Теперь запуск программы приведет к сообщению об ошибке &laquo;<i>Error System.IO.FileNotFoundException</i>&raquo;:</p>
<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>Сообщение, начинающееся со слова <i>Error</i>, означает, что при работе программы произошла <i>ошибка времени выполнения</i>
(Runtime Error). После слова <i>Error</i> указывается имя этой ошибки (в данном случае <i>System.IO.FileNotFoundException</i>,
то есть ошибка ввода-вывода, связанная с тем, что файл не найден)
и краткое ее описание на английском языке.</p>
<p>Сообщение об ошибке времени выполнения появится и в разделе &laquo;Список ошибок&raquo;
окна <b>PascalABC.NET</b>:</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>
<h3>Создание пустого результирующего файла</h3>
<p>Для того чтобы избежать ошибки времени выполнения, отсутствующий файл результатов следует открыть
не процедурой <code>Reset</code>, а процедурой <code>Rewrite</code>, которая
и обеспечит создание этого файла. Далее, после завершения работы с файлами, открытыми в программе,
их необходимо закрыть процедурой <code>Close</code>. Добавим в программу соответствующие операторы:</p>
<blockquote>
<code><pre>
<b>uses</b> PT4;
@ -179,28 +179,28 @@
<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>
<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>
<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>
@ -210,32 +210,32 @@
<b>end</b>;
</pre></code>
</blockquote>
<p>Данный фрагмент обеспечивает считывание <i>одного</i> элемента для каждого из трех исходных файлов
и запись этих элементов в результирующий файл (в требуемом порядке). Подчеркнем, что мы <i>неправильно</i> указали
типы файлов; тем не менее, компиляция программы пройдет успешно, а после ее запуска не произойдет
ошибок времени выполнения.</p>
<p>Результат работы программы будет неожиданным:</p>
<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>
<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>
<h3>Исправление ошибки, связанной с неверными типами файловых данных</h3>
<p>Заменим в нашей программе все описания <code>real</code> на <code>integer</code>:</p>
<blockquote>
<code><pre>
<b>uses</b> PT4;
@ -264,8 +264,8 @@
</blockquote>
<p>Мы получим все еще неверное, но вполне &laquo;понятное&raquo; решение: первые три элемента результирующего файла
совпадают с контрольными (то есть &laquo;правильными&raquo;), а прочие элементы отсутствуют:</p>
<p>Мы получим все еще неверное, но вполне &laquo;понятное&raquo; решение: первые три элемента результирующего файла
совпадают с контрольными (то есть &laquo;правильными&raquo;), а прочие элементы отсутствуют:</p>
<blockquote>
<img border="0" src="gif/file48-8.png">
@ -273,8 +273,8 @@
<hr>
<h3>Верное решение</h3>
<p>Приведем, наконец, верное решение задания
<h3>Верное решение</h3>
<p>Приведем, наконец, верное решение задания
<code>File48</code>:</p>
<blockquote>
<code><pre>
@ -303,11 +303,11 @@
<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>
<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">
@ -315,26 +315,26 @@
<hr>
<h3>Просмотр результатов выполнения задания</h3>
<p>Щелкнув мышью на метке &laquo;Результаты (F2)&raquo;, расположенной в правом верхнем
углу окна задачника, или нажав клавишу <b>F2</b>, мы можем вывести на экран <i>окно результатов</i>,
в котором будет перечислены все наши попытки решения задачи:</p>
<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: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 Задание выполнено!
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>Для закрытия окна результатов достаточно нажать клавишу <b>Esc</b>.
Окно результатов можно отобразить на экране и после закрытия окна задачника и возврата в среду PascalABC.NET.
Для этого надо использовать команду меню &laquo;Модули | Просмотреть результаты&raquo;, кнопку
<img border="0" src="gif/Results.gif" width="16" height="17"> или клавиатурную
комбинацию <b>Shift+Ctrl+R</b>.
</p>

View file

@ -7,19 +7,19 @@
</head>
<body>
<H1>Задания на указатели и динамические структуры данных</H1>
<H1>Задания на указатели и динамические структуры данных</H1>
<hr>
<H2>Пример 1. Анализ существующей динамической структуры</H2>
<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>
<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>
@ -32,16 +32,16 @@
<b>end</b>;
</pre></code>
</blockquote>
<p>На примере задания Dynamic2 рассмотрим особенности, связанные с
использованием этих новых типов данных.</p>
<p>На примере задания Dynamic2 рассмотрим особенности, связанные с
использованием этих новых типов данных.</p>
<hr>
<h3>Создание программы-заготовки и знакомство с заданием</h3>
<h3>Создание программы-заготовки и знакомство с заданием</h3>
<p>Программа-заготовка для задания Dynamic2, созданная с помощью команды
меню &laquo;Модули | Создать шаблон программы&raquo;, кнопки
<img border="0" src="gif/Load.gif" width="16" height="17"> или клавиатурной
комбинации <b>Shift+Ctrl+L</b>, имеет следующий вид:</p>
<p>Программа-заготовка для задания Dynamic2, созданная с помощью команды
меню &laquo;Модули | Создать шаблон программы&raquo;, кнопки
<img border="0" src="gif/Load.gif" width="16" height="17"> или клавиатурной
комбинации <b>Shift+Ctrl+L</b>, имеет следующий вид:</p>
<blockquote>
<code><pre>
@ -54,80 +54,80 @@
</pre></code>
</blockquote>
<p>После запуска данной программы на экране появится <a href="../PT4/window.html">окно задачника</a>:</p>
<p>После запуска данной программы на экране появится <a href="../PT4/window.html">окно задачника</a>:</p>
<blockquote>
<img border="0" src="gif/Dynamic2-1.png">
</blockquote>
<p>Это окно содержит в качестве исходных и результирующих данных новые элементы: динамические структуры и указатели.</p>
<p>Это окно содержит в качестве исходных и результирующих данных новые элементы: динамические структуры и указатели.</p>
<p>Начнем с описания того, как отображается на экране <i>динамическая структура</i>. Для ее вывода используются две
экранные строки; в первой строке отображаются имена указателей, связанных с данной структурой,
а во второй &#151; содержимое элементов этой структуры, то есть значения их полей <code>Data</code> и способ связи
между ними. Вся информация о динамической структуре отображается бирюзовым цветом (подобно информации об элементах файлов).</p>
<p>Начнем с описания того, как отображается на экране <i>динамическая структура</i>. Для ее вывода используются две
экранные строки; в первой строке отображаются имена указателей, связанных с данной структурой,
а во второй &#151; содержимое элементов этой структуры, то есть значения их полей <code>Data</code> и способ связи
между ними. Вся информация о динамической структуре отображается бирюзовым цветом (подобно информации об элементах файлов).</p>
<p>Рассмотрим в качестве примера динамическую структуру, указанную на рисунке:</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>
<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>
<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>
<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>
<h3>Приступаем к решению</h3>
<p>Вернемся к заданию
Dynamic2. В нем не требуется ни создавать, ни преобразовывать исходную структуру данных;
ее необходимо лишь проанализировать,
а именно, определить значения всех ее элементов, подсчитать количество элементов и, кроме того,
вывести указатель на последний элемент этой структуры.</p>
<p>Приведем вначале неполное решение задачи, выводящее все необходимые данные, кроме указателя на последний элемент:</p>
<p>Вернемся к заданию
Dynamic2. В нем не требуется ни создавать, ни преобразовывать исходную структуру данных;
ее необходимо лишь проанализировать,
а именно, определить значения всех ее элементов, подсчитать количество элементов и, кроме того,
вывести указатель на последний элемент этой структуры.</p>
<p>Приведем вначале неполное решение задачи, выводящее все необходимые данные, кроме указателя на последний элемент:</p>
<blockquote>
<code><pre>
<b>uses</b> PT4;
@ -148,36 +148,36 @@ Dynamic2.
<b>end</b>.
</pre></code>
</blockquote>
<p>После запуска программы можно убедиться, что все числовые результирующие данные найдены правильно,
однако из-за того, что не выведен указатель
на последний элемент, решение признано ошибочным с диагностикой &laquo;<i>Выведены не все результирующие данные</i>&raquo;:</p>
<p>После запуска программы можно убедиться, что все числовые результирующие данные найдены правильно,
однако из-за того, что не выведен указатель
на последний элемент, решение признано ошибочным с диагностикой &laquo;<i>Выведены не все результирующие данные</i>&raquo;:</p>
<blockquote>
<img border="0" src="gif/Dynamic2-3.png">
</blockquote>
<p>Добавим в конец программы оператор</p>
<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>
<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>
<h3>Правильное решение</h3>
<p>Для того чтобы получить правильное решение, опишем вспомогательную переменную <code>p2</code>,
в которой будем сохранять адрес элемента, <i>предшествующего</i> элементу с адресом <code>p1</code>.
После завершения цикла <code><b>while</b></code> в этой переменной будет храниться адрес последнего элемента
динамической структуры:</p>
<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>
@ -191,40 +191,40 @@ write(p1);
<b>begin</b>
write(p1^.Data);
n := n + 1;
p2 := p1; { сохраняем адрес текущего элемента }
p1 := p1^.Next; { и переходим к следующему элементу }
p2 := p1; { сохраняем адрес текущего элемента }
p1 := p1^.Next; { и переходим к следующему элементу }
<b>end</b>;
write(n, p2);
<b>end</b>.
</pre></code></blockquote>
<p>Запустив эту программу три раза, мы получим сообщение &laquo;<i>Задание выполнено!</i>&raquo;:</p>
<p>Запустив эту программу три раза, мы получим сообщение &laquo;<i>Задание выполнено!</i>&raquo;:</p>
<blockquote>
<img border="0" src="gif/Dynamic2-5.png">
</blockquote>
<hr>
<H2>Пример 2. Добавление элемента к динамической структуре</H2>
<H2>Пример 2. Добавление элемента к динамической структуре</H2>
<hr>
<h3>Знакомство с заданием</h3>
<h3>Знакомство с заданием</h3>
<p>Рассмотрим простейшее задание, связанное с добавлением элемента к динамической структуре-стеку:
<p>Рассмотрим простейшее задание, связанное с добавлением элемента к динамической структуре-стеку:
Dynamic3.</p>
<p>При ознакомительном запуске этого задания мы обнаружим новое обозначение в тексте, описывающем результирующий стек,
а именно, точки, обрамляющие первый элемент стека:</p>
<p>При ознакомительном запуске этого задания мы обнаружим новое обозначение в тексте, описывающем результирующий стек,
а именно, точки, обрамляющие первый элемент стека:</p>
<blockquote>
<img border="0" src="gif/Dynamic3-1.png">
</blockquote>
<p>Точки обозначают элементы динамической структуры, память для которых <i>должна быть выделена программой учащегося</i>
(в отличие от тех элементов, которые размещаются в памяти самим задачником).</p>
<p>Точки обозначают элементы динамической структуры, память для которых <i>должна быть выделена программой учащегося</i>
(в отличие от тех элементов, которые размещаются в памяти самим задачником).</p>
<hr>
<h3>Приступаем к решению</h3>
<h3>Приступаем к решению</h3>
<p>Что произойдет, если динамическая структура будет создана с ошибками? Для того чтобы это выяснить, вернем в программе, решающей задание
Dynamic3, указатель на прежнюю вершину стека, не добавляя к ней новый элемент:</p>
<p>Что произойдет, если динамическая структура будет создана с ошибками? Для того чтобы это выяснить, вернем в программе, решающей задание
Dynamic3, указатель на прежнюю вершину стека, не добавляя к ней новый элемент:</p>
<blockquote><code><pre>
<b>uses</b> PT4;
<b>var</b>
@ -236,22 +236,22 @@ Dynamic3,
write(p1);
<b>end</b>.
</pre></code></blockquote>
<p>После запуска данной программы окно задачника примет вид:</p>
<p>После запуска данной программы окно задачника примет вид:</p>
<blockquote>
<img border="0" src="gif/Dynamic3-2.png">
</blockquote>
<p>Скобки вокруг каждого элемента результирующего стека означают, что эти элементы созданы самим задачником, но <i>располагаются
не на тех позициях, на которых они должны находиться при правильном решении</i>. Действительно, тот элемент,
который в решении является первым, должен (после добавления нового элемента) оказаться вторым и т.&nbsp;д. Итак,
наличие скобок в тексте результирующей динамической структуры означает, что ее элементы располагаются не в том порядке,
который требуется.</p>
<p>Скобки вокруг каждого элемента результирующего стека означают, что эти элементы созданы самим задачником, но <i>располагаются
не на тех позициях, на которых они должны находиться при правильном решении</i>. Действительно, тот элемент,
который в решении является первым, должен (после добавления нового элемента) оказаться вторым и т.&nbsp;д. Итак,
наличие скобок в тексте результирующей динамической структуры означает, что ее элементы располагаются не в том порядке,
который требуется.</p>
<hr>
<h3>Правильное решение</h3>
<h3>Правильное решение</h3>
<p>Для получения правильного решения задания Dynamic3 необходимо явно выделить память для нового элемента,
используя процедуру <code>New</code>, и заполнить поля этого элемента, связав его с текущей вершиной стека
(в результате сам этот элемент станет новой вершиной, адрес которой и следует вывести):</p>
<p>Для получения правильного решения задания Dynamic3 необходимо явно выделить память для нового элемента,
используя процедуру <code>New</code>, и заполнить поля этого элемента, связав его с текущей вершиной стека
(в результате сам этот элемент станет новой вершиной, адрес которой и следует вывести):</p>
<blockquote><code><pre>
<b>uses</b> PT4;
<b>var</b>
@ -266,36 +266,36 @@ Dynamic3,
write(p2);
<b>end</b>.
</pre></code></blockquote>
<p>Приведем вид окна задачника при первом запуске этой программы:</p>
<p>Приведем вид окна задачника при первом запуске этой программы:</p>
<blockquote>
<img border="0" src="gif/Dynamic3-3.png">
</blockquote>
<hr>
<H2>Пример 3. Удаление элемента из динамической структуры</H2>
<H2>Пример 3. Удаление элемента из динамической структуры</H2>
<hr>
<h3>Знакомство с заданием</h3>
<h3>Знакомство с заданием</h3>
<p>Рассмотрим простейшее задание на удаление элемента из динамической структуры &#151;
<p>Рассмотрим простейшее задание на удаление элемента из динамической структуры &#151;
Dynamic5.
В нем требуется удалить из стека вершину и вернуть указатель на новую вершину, то есть на элемент,
расположенный непосредственно за удаленным.</p>
<p>Особенность заданий на удаление элементов из динамических структур заключается в том, что удаляемый элемент
необходимо не только &laquo;отсоединить&raquo;
от исходной динамической структуры, но и полностью &laquo;уничтожить&raquo;, то есть <i>освободить память, занимаемую этим элементом</i>.</p>
<p>Для того чтобы напомнить учащемуся о необходимости уничтожения некоторых элементов исходной динамической
структуры, эти элементы выделяются на экране синим цветом меньшей яркости, чем обычные элементы (на рисунке
таким способом выделен элемент 15):</p>
В нем требуется удалить из стека вершину и вернуть указатель на новую вершину, то есть на элемент,
расположенный непосредственно за удаленным.</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>
<h3>Приступаем к решению</h3>
<p>Вначале приведем неправильный вариант решения, в котором
не освобождается память, занимаемая удаленным из стека элементом:</p>
<p>Вначале приведем неправильный вариант решения, в котором
не освобождается память, занимаемая удаленным из стека элементом:</p>
<blockquote><code><pre>
<b>uses</b> PT4;
<b>var</b> p1: PNode;
@ -305,19 +305,19 @@ Dynamic5.
write(p1^.Data, p1^.Next);
<b>end</b>.
</pre></code></blockquote>
<p>Несмотря на то что все результирующие данные будут совпадать с контрольными
(то есть текст в разделах &laquo;Полученные результаты&raquo; и &laquo;Пример верного решения&raquo; будет одинаковым), на
информационной панели появится сообщение об ошибке &laquo;<i>Не освобождена динамическая память</i>&raquo;,
а в разделе исходных данных будет выделен красным цветом тот элемент, который требовалось удалить:</p>
<p>Несмотря на то что все результирующие данные будут совпадать с контрольными
(то есть текст в разделах &laquo;Полученные результаты&raquo; и &laquo;Пример верного решения&raquo; будет одинаковым), на
информационной панели появится сообщение об ошибке &laquo;<i>Не освобождена динамическая память</i>&raquo;,
а в разделе исходных данных будет выделен красным цветом тот элемент, который требовалось удалить:</p>
<blockquote>
<img border="0" src="gif/Dynamic5-2.png">
</blockquote>
<hr>
<h3>Правильное решение</h3>
<h3>Правильное решение</h3>
<p>Для получения правильного решения достаточно добавить в конец программы оператор вызова
процедуры <code>Dispose</code>, освобождающий память, на которую указывает указатель <code>p1</code>:</p>
<p>Для получения правильного решения достаточно добавить в конец программы оператор вызова
процедуры <code>Dispose</code>, освобождающий память, на которую указывает указатель <code>p1</code>:</p>
<blockquote><code><pre>
<b>uses</b> PT4;
<b>var</b> p1: PNode;
@ -328,41 +328,41 @@ Dynamic5.
Dispose(p1);
<b>end</b>.
</pre></code></blockquote>
<p>Приведем вид окна задачника при первом запуске этой программы:</p>
<p>Приведем вид окна задачника при первом запуске этой программы:</p>
<blockquote>
<img border="0" src="gif/Dynamic5-3.png">
</blockquote>
<hr>
<H2>Пример 4. Двусвязные динамические структуры</H2>
<H2>Пример 4. Двусвязные динамические структуры</H2>
<hr>
<h3>Знакомство с заданием</h3>
<p>Особенности работы с двусвязными динамическими структурами рассмотрим на примере задания
<h3>Знакомство с заданием</h3>
<p>Особенности работы с двусвязными динамическими структурами рассмотрим на примере задания
Dynamic30,
в котором требуется преобразовать исходную односвязную структуру в двусвязную. Запустив программу-заготовку,
созданную для этого задания, мы увидим в области исходных данных информацию об &laquo;обычной&raquo; односвязной структуре,
подобной рассмотренным в предыдущих примерах:</p>
в котором требуется преобразовать исходную односвязную структуру в двусвязную. Запустив программу-заготовку,
созданную для этого задания, мы увидим в области исходных данных информацию об &laquo;обычной&raquo; односвязной структуре,
подобной рассмотренным в предыдущих примерах:</p>
<blockquote>
<img border="0" src="gif/Dynamic30-1.png">
</blockquote>
<p>Динамическая структура, приведенная в разделе результатов, имеет две особенности:
во-первых, ее элементы связаны символом <code>=</code>, а во-вторых, перед первым элементом присутствует текст
<p>Динамическая структура, приведенная в разделе результатов, имеет две особенности:
во-первых, ее элементы связаны символом <code>=</code>, а во-вторых, перед первым элементом присутствует текст
<code>nil&lt;</code>.</p>
<p>Это означает, что результирующая структура является <i>двусвязной</i>, то есть каждый ее элемент связан не
только с последующим элементом (с помощью поля <code>Next</code>, как в односвязной структуре), но и с
предыдущим элементом (с помощью нового поля <code>Prev</code>), а поле <code>Prev</code> первого элемента имеет
значение <code>nil</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>
<h3>Приступаем к решению</h3>
<p>Для преобразования исходной односвязной структуры в двусвязную необходимо задать правильные значения для
полей <code>Prev</code> всех элементов структуры, перебирая в цикле пары соседних элементов:</p>
<p>Для преобразования исходной односвязной структуры в двусвязную необходимо задать правильные значения для
полей <code>Prev</code> всех элементов структуры, перебирая в цикле пары соседних элементов:</p>
<blockquote><code><pre>
<b>uses</b> PT4;
<b>var</b>
@ -377,40 +377,40 @@ Dynamic30,
p1 := p1^.Next;
p := p^.Next;
<b>end</b>;
write(p1); <i>{ вывод указателя на последний элемент }</i>
write(p1); <i>{ вывод указателя на последний элемент }</i>
<b>end</b>.
</pre></code></blockquote>
<p>В этой программе мы определили поля <code>Prev</code> для всех элементов, кроме первого. Поэтому решение будет считаться ошибочным
(обратите внимание на то, что перед первым элементом полученного списка отсутствует текст <code>nil&lt;</code>):</p>
<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>
<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>
<p>Это означает, что между вторым и третьим элементом структуры имеется не двойная, а <i>одинарная</i> связь
(поле <code>Next</code> второго элемента содержит адрес третьего элемента, а поле <code>Prev</code> третьего элемента
<i>не содержит</i> адрес второго).</p>
<hr>
<h3>Правильное решение</h3>
<p>Для получения правильного решения достаточно добавить в программу перед циклом <code>while</code>
следующий оператор:</p>
<h3>Правильное решение</h3>
<p>Для получения правильного решения достаточно добавить в программу перед циклом <code>while</code>
следующий оператор:</p>
<blockquote><code><pre>
p1^.Prev := nil;
</pre></code></blockquote>
<p>Приведем вид окна задачника при первом запуске исправленной программы:</p>
<p>Приведем вид окна задачника при первом запуске исправленной программы:</p>
<blockquote>
<img border="0" src="gif/Dynamic30-4.png">
</blockquote>
<p><b>Замечание.</b> Для задания Dynamic30 возможен более короткий вариант решения,
в котором не требуется особо обрабатывать первый элемент списка:
<p><b>Замечание.</b> Для задания Dynamic30 возможен более короткий вариант решения,
в котором не требуется особо обрабатывать первый элемент списка:
</p>
<blockquote><code><pre>
@ -434,36 +434,36 @@ nil&lt; 33 = 64 - 78 = 12 = 51 >nil
<hr>
<H2>Пример 5. Циклические динамические структуры</H2>
<H2>Пример 5. Циклические динамические структуры</H2>
<hr>
<h3>Знакомство с заданием</h3>
<p>Динамическая структура называется <i>циклической</i>, если она замкнута в &laquo;кольцо&raquo;, то есть ее последний элемент
связан полем <code>Next</code> с первым (в случае двусвязной структуры требуется также, чтобы ее первый элемент
был связан полем <code>Prev</code>
с последним элементом). Простейшим заданием на циклические структуры является
Dynamic55, в котором требуется
преобразовать обычный двусвязный список
в циклический.</p>
<p>Запустив программу-заготовку для этого задания, мы увидим
на экране изображение двух динамических структур, причем исходная структура является &laquo;обычным&raquo; двусвязным списком,
а результирующая структура &#151; циклическим двусвязным списком:</p>
<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>
<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>
<h3>Приступаем к решению</h3>
<p>Для решения задания Dynamic55 достаточно найти последний элемент исходного списка и связать его с
первым элементом:</p>
<blockquote><code><pre>
<b>uses</b> PT4;
<b>var</b>
@ -478,21 +478,21 @@ Dynamic55,
write(p2);
<b>end</b>.
</pre></code></blockquote>
<p>В данном варианте решения мы &laquo;забыли&raquo; о том, что надо связать не только последний элемент с первым,
но и первый с последним (поскольку наш список &#151; двусвязный). Поэтому решение оказалось ошибочным
(обратите внимание на то, что после последнего элемента полученного списка изображена одинарная, а не двойная черта):</p>
<p>В данном варианте решения мы &laquo;забыли&raquo; о том, что надо связать не только последний элемент с первым,
но и первый с последним (поскольку наш список &#151; двусвязный). Поэтому решение оказалось ошибочным
(обратите внимание на то, что после последнего элемента полученного списка изображена одинарная, а не двойная черта):</p>
<blockquote>
<img border="0" src="gif/Dynamic55-3.png">
</blockquote>
<hr>
<h3>Правильное решение</h3>
<p>Для получения правильного решения достаточно добавить в программу перед процедурой вывода <code>write</code>
следующий оператор:</p>
<h3>Правильное решение</h3>
<p>Для получения правильного решения достаточно добавить в программу перед процедурой вывода <code>write</code>
следующий оператор:</p>
<blockquote><code><pre>
p1^.Prev := p2;
</pre></code></blockquote>
<p>Приведем вид окна задачника при первом запуске исправленной программы:</p>
<p>Приведем вид окна задачника при первом запуске исправленной программы:</p>
<blockquote>
<img border="0" src="gif/Dynamic55-4.png">
</blockquote>
@ -500,34 +500,34 @@ Dynamic55,
<hr>
<h3>Просмотр результатов выполнения заданий</h3>
<p>Щелкнув мышью на метке &laquo;Результаты (F2)&raquo;, расположенной в правом верхнем
углу окна задачника, или нажав клавишу <b>F2</b>, мы можем вывести на экран <i>окно результатов</i>,
в котором будет перечислены все наши попытки решения задачи:</p>
<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 Задание выполнено!
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>Для закрытия окна результатов достаточно нажать клавишу <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>

View file

@ -7,17 +7,17 @@
</head>
<body>
<H1>Задание на обработку строк</H1>
<H1>Задание на обработку строк</H1>
<hr>
<h3>Создание программы-заготовки и знакомство с заданием</h3>
<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>
<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;
@ -28,21 +28,21 @@
<b>end</b>.
</pre></code></blockquote>
<p>После запуска данной программы на экране появится <a href="../PT4/window.html">окно задачника</a>:</p>
<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>, находящиеся в начале или конце строк.
<p>Данные типа <code>char</code> и <code>string</code> в окне задачника заключаются в <i>апострофы</i>; это позволяет, в частности,
отличить числовые данные (например, <code>9</code>) от символьных и строковых данных, содержащих цифры
(например, <code>'9'</code>).
Кроме того, апострофы дают возможность увидеть <i>пробелы</i>, находящиеся в начале или конце строк.
<hr>
<h3>Ввод исходных данных</h3>
<p>Добавим в программу фрагмент, обеспечивающий ввод исходных данных
(мы намеренно ввели данные не в том порядке, в котором они указаны в окне задачника):
<h3>Ввод исходных данных</h3>
<p>Добавим в программу фрагмент, обеспечивающий ввод исходных данных
(мы намеренно ввели данные не в том порядке, в котором они указаны в окне задачника):
</p>
<blockquote>
<code><pre>
@ -57,47 +57,47 @@
</pre></code></blockquote>
<p>Запуск нового варианта программы уже не будет считаться ознакомительным, поскольку в программе
выполняется ввод исходных данных. Так как порядок ввода исходных данных является ошибочным,
этот вариант решения будет признан неверным и приведет к сообщению
&laquo;<i>Неверно указан тип при вводе исходных данных</i>&raquo;:</p>
<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>Общее правило, определяющее порядок ввода и вывода данных для задачника <b>Programming Taskbook</b>
гласит:
<i>ввод и вывод данных производится по строкам (слева направо), а строки просматриваются сверху вниз</i>.
Иными словами,
данные, отображаемые в окне задачника, вводятся и выводятся в том порядке, в котором читается обычный
текст.</p>
<p>На панели индикаторов, расположенной под информационной панелью,
отмечено, что введен всего один элемент исходных данных (из трех), хотя в процедуре <code>read</code> нашей программы
были
указаны три переменные. Это объясняется тем, что при вводе первой из этих переменных (<code>с1</code>)
была обнаружена ошибка несоответствия типа, поэтому задачник не стал анализировать остальные данные,
которые программа пыталась ввести. Здесь проявляется еще одно правило задачника
<b>Programming Taskbook</b>: <i>при обнаружении первой ошибки ввода-вывода
анализ оставшихся исходных данных и результатов не проводится</i>.
</p>
<p>Исправим нашу программу, изменив порядкок параметров в процедуре ввода:</p>
<p>Исправим нашу программу, изменив порядкок параметров в процедуре ввода:</p>
<blockquote>
<code><pre>
read(n, c1, c2);
</pre></code></blockquote>
<p>Теперь с вводом данных проблем не возникает, однако из-за того что в программе отсутствует вывод результирующих
данных, решение по-прежнему считается ошибочным:</p>
<p>Теперь с вводом данных проблем не возникает, однако из-за того что в программе отсутствует вывод результирующих
данных, решение по-прежнему считается ошибочным:</p>
<blockquote>
<img border="0" src="gif/string9-3.png">
</blockquote>
<p>Данная ошибка, в отличие от предыдущей, связана не с вводом исходных данных, а с выводом результатов.
Это отмечается в окне задачника двумя способами: цветной маркер ошибки располагается рядом с индикатором вывода,
и этим же цветом выделяется заголовок раздела результатов (который в данном случае не содержит никаких данных).
<p>Данная ошибка, в отличие от предыдущей, связана не с вводом исходных данных, а с выводом результатов.
Это отмечается в окне задачника двумя способами: цветной маркер ошибки располагается рядом с индикатором вывода,
и этим же цветом выделяется заголовок раздела результатов (который в данном случае не содержит никаких данных).
</p>
<hr>
<h3>Формирование и вывод требуемой строки</h3>
<p>Для формирования нужной строки воспользуемся операцией <code>+</code> (<i>сцепления</i> строк):</p>
<h3>Формирование и вывод требуемой строки</h3>
<p>Для формирования нужной строки воспользуемся операцией <code>+</code> (<i>сцепления</i> строк):</p>
<blockquote>
<code><pre>
<b>uses</b> PT4;
@ -114,30 +114,30 @@
write(s);
<b>end</b>.
</pre></code></blockquote>
<p>Заметим, что в операторе <code>s := ''</code> нет необходимости, так как все глобальные переменные в Паскале автоматически
инициализируются &laquo;нулевыми&raquo; значениями (для числовых данных это обычные нули, для символов &#151; это
символ <code>#0</code>, для
строк &#151; пустая строка <code>''</code>).</p>
<p>Результат выполнения этой программы будет следующим:</p>
<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>
<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>
<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>
<h3>Верное решение</h3>
<p>Ошибка в предыдущей программе возникла из-за неверного указания количества итераций цикла. Действительно,
на каждой итерации к строке добавляется по <i>два</i> символа, поэтому после <code>n</code> итераций
строка будет содержать <code>2*n</code> символов (а не <code>n</code>, как требуется в задании).
<p>Для исправления ошибки достаточно вдвое
уменьшить число итераций:</p>
<blockquote>
<code><pre>
<b>uses</b> PT4;
@ -154,13 +154,13 @@
write(s);
<b>end</b>.
</pre></code></blockquote>
<p>После запуска этого варианта мы получим сообщение &laquo;<i>Верное решение. Тест номер 1 (из 5)</i>&raquo;,
а после пяти подобных запусков &#151; сообщение &laquo;<i>Задание выполнено!</i>&raquo;:</p>
<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>
<p><b>Замечание.</b> Приведем другой, более быстрый, способ решения задания String9,
в котором результирующая строка заполняется <i>посимвольно</i>, как обычный массив:</p>
<blockquote>
<code><pre>
<b>uses</b> PT4;
@ -180,34 +180,34 @@
write(s);
<b>end</b>.
</pre></code></blockquote>
<p>Обратите внимание на процедуру <code>SetLength(s, n)</code>, которая обеспечивает правильную настройку <i>длины</i> результирующей
строки <code>s</code>. Без вызова этой процедуры программа работала бы неверно, так как любая
глобальная строковая переменная инициализируется пустой строкой, а при работе с отдельными символами строки
корректировка ее длины не производится.</p>
<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>
<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 Задание выполнено!
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>Для закрытия окна результатов достаточно нажать клавишу <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>

View file

@ -10,35 +10,35 @@
<a name="main"></a>
<h1>Задания на обработку деревьев
<h1>Задания на обработку деревьев
</h1>
<hr>
<h2>Пример 1. Анализ бинарного дерева
<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>В заданиях группы 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>Особенности, связанные с использованием новых типов данных, рассмотрим на
примере задания Tree2.
</p>
<p class="task">Tree2&#176;.
Дан адрес <i>P</i><sub>1</sub> записи типа TNode &#151; корня дерева.
Эта запись связана полями Left и Right с другими записями того же типа (дочерними вершинами),
они, в свою очередь, &#151; со своими дочерними вершинами, и так далее до записей,
поля Left и Right которых равны nil (у некоторых вершин может быть равно nil одно из полей Left или Right).
Вывести количество вершин дерева.
Дан адрес <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>. Приведем текст созданной заготовки:
<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>
@ -48,67 +48,67 @@
Task('Tree2');
<b>end</b>.
</pre></code></blockquote>
<p>После запуска программы на экране появится <a href="../PT4/window.html">окно задачника</a>:
<p>После запуска программы на экране появится <a href="../PT4/window.html">окно задачника</a>:
</p>
<blockquote>
<img border="0" src="gif/Tree2-1.png">
</blockquote>
<p>Это окно содержит в качестве исходных и результирующих данных новые
элементы: бинарные деревья и указатели.
<p>Это окно содержит в качестве исходных и результирующих данных новые
элементы: бинарные деревья и указатели.
</p>
<p>Начнем с описания того, как отображается на экране <i>дерево</i>. Для его вывода используется
несколько экранных строк. На каждой строке изображаются вершины дерева,
находящиеся на определенном уровне (номер уровня указывается слева от изображения дерева).
Для каждой вершины выводится ее значение, т.&nbsp;е. значение поля Data соответствующей записи типа TNode.
Любая вершина соединяется линиями со своими дочерними вершинами, расположенными на следующем уровне дерева;
левая дочерняя вершина изображается слева от родительской вершины, а правая &#151; справа.
Отсутствие у вершины одной или обеих дочерних вершин означает, что ее поля <code>Left</code> и/или <code>Right</code> равны <code>nil</code>.
<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).
Рассмотрим в качестве примера дерево, приведенное на рисунке.
Корень этого дерева имеет значение 15, левая дочерняя вершина корня равна 58,
правая дочерняя вершина равна 42, глубина дерева равна 4. Все листья дерева находятся на уровнях
3 и 4; листья на уровне 3 имеют значения 15 и 11, листья на уровне 4 &#151; значения 38 и 84.
Некоторые из внутренних вершин дерева имеют по две
дочерние вершины (это корень и вершины со значениями 55 и 20), некоторые по одной:
левой (вершины 42, 87 и 60) или правой (вершина 58).
</p>
<p>Поскольку это дерево указано в разделе исходных данных, следовательно, после инициализации
задания оно уже существует и размещается в некоторой области динамической памяти.
Для доступа к данным, размещенным в динамической памяти,
необходимо знать их адрес, поэтому в любом задании на обработку деревьев в набор исходных данных входят
<i>указатели</i>, содержащие адреса каких-либо вершин этих деревьев (как правило, указывается адрес корня дерева).
<p>Поскольку это дерево указано в разделе исходных данных, следовательно, после инициализации
задания оно уже существует и размещается в некоторой области динамической памяти.
Для доступа к данным, размещенным в динамической памяти,
необходимо знать их адрес, поэтому в любом задании на обработку деревьев в набор исходных данных входят
<i>указатели</i>, содержащие адреса каких-либо вершин этих деревьев (как правило, указывается адрес корня дерева).
</p>
<p>Работа с исходными и результирующими
данными типа указателя подробно обсуждается в разделе, посвященном
<a href="ctpointer.html">линейным динамическим структурам</a>.
<p>Работа с исходными и результирующими
данными типа указателя подробно обсуждается в разделе, посвященном
<a href="ctpointer.html">линейным динамическим структурам</a>.
</p>
</p>
<hr>
<h3>Решение задачи</h3>
<h3>Решение задачи</h3>
<p>В задании Tree2 не требуется ни создавать, ни
преобразовывать исходное дерево;
его необходимо лишь проанализировать, а именно определить количество его вершин.
<p>В задании Tree2 не требуется ни создавать, ни
преобразовывать исходное дерево;
его необходимо лишь проанализировать, а именно определить количество его вершин.
</p>
<p>Для выполнения этого задания, как и для подавляющего большинства других заданий на обработку деревьев,
следует воспользоваться вспомогательной <i>рекурсивной</i> подпрограммой (функцией или процедурой).
Рекурсивная природа алгоритмов,
связанных с обработкой деревьев (в частности, бинарных деревьев), объясняется тем, что сами
определения деревьев общего вида и бинарных деревьев являются рекурсивными.
Так, дать словесное описание функции <code>NodeCount(P)</code>, подсчитывающей число вершин дерева с корнем,
с которым связан указатель <code>P</code>, можно следующим образом: если указатель <code>P</code> равен <code>nil</code>,
то следует вернуть значение <code>0</code>; в противном случае следует вернуть значение
<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; его правому поддереву; при этом не требуется проверять,
что указанные поддеревья существуют, так как при их отсутствии соответствующее слагаемое просто будет равно нулю).
(в этом выражении первое слагаемое соответствует корню дерева, второе &#151;
его левому поддереву, а третье &#151; его правому поддереву; при этом не требуется проверять,
что указанные поддеревья существуют, так как при их отсутствии соответствующее слагаемое просто будет равно нулю).
</p>
<p>Таким образом, решение задачи будет иметь следующий вид:
<p>Таким образом, решение задачи будет иметь следующий вид:
</p>
<blockquote><code><pre>
<b>uses</b> PT4;
@ -126,57 +126,57 @@ begin
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>Цепочка рекурсивных вызовов функции <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>Запустив эту программу пять раз, мы получим сообщение &laquo;<i>Задание
выполнено!</i>&raquo;.
</p>
<hr>
<a name="parent"></a>
<h2>Пример 2. Бинарные деревья с обратной связью
<h2>Пример 2. Бинарные деревья с обратной связью
</h2>
<hr>
<p>Рассмотренная выше реализация бинарных деревьев позволяет легко переходить от родительских вершин
к их дочерним вершинам, но не допускает обратного перехода. В то же время, для некоторых задач,
связанных с обработкой деревьев, возможность обратного перехода от потомков к их предку позволяет
получить более простое решение. Ясно, что для обеспечения возможности обратного перехода
каждую вершину дерева надо снабдить еще одним полем связи, в котором должна храниться ссылка на
ее родительскую вершину. Это поле связи естественно назвать <code>Parent</code>. Поскольку корень дерева
предка не имеет, его поле <code>Parent</code> должно быть равно <code>nil</code>.
<p>Рассмотренная выше реализация бинарных деревьев позволяет легко переходить от родительских вершин
к их дочерним вершинам, но не допускает обратного перехода. В то же время, для некоторых задач,
связанных с обработкой деревьев, возможность обратного перехода от потомков к их предку позволяет
получить более простое решение. Ясно, что для обеспечения возможности обратного перехода
каждую вершину дерева надо снабдить еще одним полем связи, в котором должна храниться ссылка на
ее родительскую вершину. Это поле связи естественно назвать <code>Parent</code>. Поскольку корень дерева
предка не имеет, его поле <code>Parent</code> должно быть равно <code>nil</code>.
</p>
<p>Деревья, вершины которых содержат информацию о своих родителях, будем называть <i>деревьями с обратной связью</i>.
Особенности работы с подобными деревьями рассмотрим на примере задания Tree49.
<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.
Дан указатель <i>P</i><sub>1</sub> на корень дерева, вершинами которого являются записи типа TNode,
связанные между собой с помощью полей Left и Right. Используя поле Parent записи TNode,
преобразовать исходное дерево в <i>дерево с обратной связью</i>, в котором каждая вершина
связана не только со своими дочерними вершинами (полями Left и Right), но и с родительской
вершиной (полем Parent). Поле Parent корня дерева положить равным nil.
</p>
<p>Запустив программу-заготовку, созданную для задания Tree49,
мы увидим в области исходных данных изображение &laquo;обычного&raquo; бинарного дерева,
в то время как в области результатов будет изображено дерево с обратной связью,
вершины которого связаны не одинарными, а двойными линиями.
<p>Запустив программу-заготовку, созданную для задания Tree49,
мы увидим в области исходных данных изображение &laquo;обычного&raquo; бинарного дерева,
в то время как в области результатов будет изображено дерево с обратной связью,
вершины которого связаны не одинарными, а двойными линиями.
</p>
<blockquote>
<img border="0" src="gif/Tree49-1.png">
</blockquote>
<p>Обратите также внимание на то, что в области результатов отсутствуют какие-либо данные, кроме
измененного дерева. Это означает, что в программе, решающей задачу, не требуется использовать
процедуры вывода; достаточно лишь преобразовать исходное дерево требуемым образом.
Поскольку при таком преобразовании адрес корня дерева <i>P</i><sub>1</sub>
не изменится, задачник сможеть получить доступ к
этому дереву и проверить его правильность.
<p>Обратите также внимание на то, что в области результатов отсутствуют какие-либо данные, кроме
измененного дерева. Это означает, что в программе, решающей задачу, не требуется использовать
процедуры вывода; достаточно лишь преобразовать исходное дерево требуемым образом.
Поскольку при таком преобразовании адрес корня дерева <i>P</i><sub>1</sub>
не изменится, задачник сможеть получить доступ к
этому дереву и проверить его правильность.
</p>
<p>Для преобразования исходного дерева в дерево с обратной связью необходимо задать правильные значения
для полей <code>Parent</code> всех вершин дерева, перебирая эти вершины с помощью подходящей рекурсивной процедуры.
В эту процедуру удобно передавать в качестве параметров не только указатель <code>P</code> на текущую вершину,
но и указатель <code>Par</code> на предка этой вершины:
<p>Для преобразования исходного дерева в дерево с обратной связью необходимо задать правильные значения
для полей <code>Parent</code> всех вершин дерева, перебирая эти вершины с помощью подходящей рекурсивной процедуры.
В эту процедуру удобно передавать в качестве параметров не только указатель <code>P</code> на текущую вершину,
но и указатель <code>Par</code> на предка этой вершины:
</p>
<blockquote><code><pre>
<b>uses</b> PT4;
@ -195,77 +195,77 @@ begin
SetParent(P1, nil);
<b>end</b>.
</pre></code></blockquote>
<p>При стартовом запуске рекурсивной процедуры <code>SetParent</code> в качестве
второго параметра указывается <code>nil</code>.
<p>При стартовом запуске рекурсивной процедуры <code>SetParent</code> в качестве
второго параметра указывается <code>nil</code>.
</p>
<p>
<b>Примечание.</b> Обозначение для двойной связи может оказаться полезным при анализе ошибочного решения.
Так, если в изображении дерева с обратной связью имеется вершина, соединенная со своей родительским
вершиной не двойной, а одинарной линией, значит, у этой вершины поле <code>Parent</code> содержит ошибочное значение
(например, равно <code>nil</code>).
<b>Примечание.</b> Обозначение для двойной связи может оказаться полезным при анализе ошибочного решения.
Так, если в изображении дерева с обратной связью имеется вершина, соединенная со своей родительским
вершиной не двойной, а одинарной линией, значит, у этой вершины поле <code>Parent</code> содержит ошибочное значение
(например, равно <code>nil</code>).
</p>
<hr>
<a name="general"></a>
<h2>Пример 3. Деревья общего вида
<h2>Пример 3. Деревья общего вида
</h2>
<hr>
<p>С помощью связанных записей типа <code>TNode</code> можно моделировать не только бинарные деревья,
но и произвольные упорядоченные деревья, вершины которых имеют любое число непосредственных потомков
(будем называть такие деревья <i>деревьями общего вида</i>; для них также используется название
&laquo;деревья с множественным ветвлением&raquo;).
Рассмотрим задание Tree86 &#151; первое из заданий, связанных с деревьями общего вида, в котором
описываются особенности подобных деревьев.
<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> на его корень.
<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>Приведем пример дерева общего вида, которое реализовано с помощью связанных
записей типа <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>Корень этого дерева (со значением 13) имеет три дочерние вершины (71, 73 и 29),
причем вершина 71 не имеет потомков, вершина 73 имеет три непосредственных потомка (18, 93 и 92),
а вершина 29 &#151; два (24 и 84). На последнем уровне располагается вершина 46, являющаяся
единственной дочерней вершиной вершины 93.
</p>
<p>При ознакомительном запуске задания Tree86 на экране появится окно, подобное следующему.
<p>При ознакомительном запуске задания Tree86 на экране появится окно, подобное следующему.
</p>
<blockquote>
<img border="0" src="gif/Tree86-2.png">
</blockquote>
<p>Обратите внимание на то, как выглядит одно и то же дерево в двух различных представлениях:
вариант, соответствующий обычному бинарному дереву, приводится в разделе исходных данных,
а вариант, соответствующий дереву общего вида, &#151; в разделе результатов.
При переходе от бинарного дерева к дереву общего вида часть информации о структуре бинарного дерева
теряется, поскольку в случае, если некоторая вершина дерева общего вида имеет только одного
непосредственного потомка, нельзя определить, каким был этот потомок в исходном бинарном дереве &#151; левым или правым.
<p>Обратите внимание на то, как выглядит одно и то же дерево в двух различных представлениях:
вариант, соответствующий обычному бинарному дереву, приводится в разделе исходных данных,
а вариант, соответствующий дереву общего вида, &#151; в разделе результатов.
При переходе от бинарного дерева к дереву общего вида часть информации о структуре бинарного дерева
теряется, поскольку в случае, если некоторая вершина дерева общего вида имеет только одного
непосредственного потомка, нельзя определить, каким был этот потомок в исходном бинарном дереве &#151; левым или правым.
</p>
<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>При формировании нового дерева будем использовать рекурсивную функцию <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;
@ -287,7 +287,7 @@ begin
P1 := P2;
P2 := nil;
<b>end</b>;
<i>{ формирование списка дочерних вершин }</i>
<i>{ формирование списка дочерних вершин }</i>
result^.Left := CreateNode(P1);
<b>if</b> P1 &lt;&gt; nil <b>then</b>
result^.Left^.Right := CreateNode(P2);
@ -300,15 +300,15 @@ begin
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>.
<b>Примечание.</b> Фрагмент дерева общего вида, содержащий все дочерние вершины некоторой вершины,
можно рассматривать как <i>односвязный список</i>, элементы которого связаны между собой
с помощью поля <code>Right</code> (у последнего элемента списка поле <code>Right</code> равно <code>nil</code>).
Каждый элемент подобного списка может содержать &laquo;подсписок&raquo; своих дочерних элементов;
адрес начала этого подсписка хранится в поле <code>Left</code> данного элемента.
Поэтому в алгоритмах, связанных с обработкой вершин деревьев общего вида,
для перебора непосредственных потомков некоторой вершины удобно использовать <i>цикл</i>
(как при переборе элементов списка), в то время как для обработки каждой дочерней вершины следует,
как обычно, использовать <i>рекурсию</i>.
</p>

View file

@ -6,93 +6,93 @@
</head>
<link rel="StyleSheet" href="../../default.css">
<body>
<H1>Что такое проверяемые задания</H1>
<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>
<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><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><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><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>Все примеры, связанные с электронным задачником <b>Programming Taskbook</b>, иллюстрируются
изображениями окна задачника
в <a href="..\PT4\window.html#dynmode">режиме с динамической компоновкой</a>, появившемся в версии 4.11.
</p>
</body>

View file

@ -2,7 +2,7 @@
<head>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="Keyword" value="Чертежник">
<param name="Keyword" value="Чертежник">
<param name="Keyword" value="Drawman">
<param name="Keyword" value="ToPoint">
<param name="Keyword" value="OnVector">
@ -18,54 +18,54 @@
</head>
<body>
<H1>Исполнитель Чертежник</H1>
Исполнитель Чертежник
предназначен для построения рисунков и чертежей на плоскости с координатами.
Чертежник имеет перо, которое он может поднимать, опускать и перемещать.
При перемещении опущенного пера за ним остается след.
<p>Исполнитель Чертежник и поле, на котором он работает, отображаются на экране следующим
образом:</p>
<H1>Исполнитель Чертежник</H1>
Исполнитель Чертежник
предназначен для построения рисунков и чертежей на плоскости с координатами.
Чертежник имеет перо, которое он может поднимать, опускать и перемещать.
При перемещении опущенного пера за ним остается след.
<p>Исполнитель Чертежник и поле, на котором он работает, отображаются на экране следующим
образом:</p>
<p><img border="0" src="DMa1.png" width="381" height="213"></p>
<p>Здесь маленький квадрат изображает Чертежника, красным цветом изображены
отрезки, которые надо нарисовать, а синим &#151; уже нарисованные Чертежником
отрезки. Когда перо Чертежника опущено, он изображается квадратом меньшего
размера.</p>
<p>Команды исполнителя Чертежник
содержатся в модуле <code>Drawman</code>:
<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>
<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>
<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>
<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> процедуры с параметрами.
<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>
<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

@ -7,27 +7,27 @@
</head>
<body>
<H1>Что такое исполнители</H1>
<p><b>Исполнителем</b> будем называть устройство, способное выполнять
определенный набор команд. Обычно с исполнителем связана некоторая среда, в
которой он работает.
<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>
<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>

View file

@ -2,7 +2,7 @@
<head>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="Keyword" value="Робот">
<param name="Keyword" value="Робот">
<param name="Keyword" value="Robot">
<param name="Keyword" value="Left">
<param name="Keyword" value="Right">
@ -29,60 +29,60 @@
</head>
<body>
<H1>Исполнитель Робот</H1>
<p >Исполнитель Робот
действует на прямоугольном клеточном поле. Между некоторыми клетками, а
также по периметру поля находятся <i>стены</i>. Основная цель Робота ¦&#151; закрасить
указанные клетки и переместиться в конечную клетку.</p>
<p>Исполнитель Робот и поле, на котором он работает, отображаются следующим
образом:</p>
<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>Здесь большой желтый квадрат изображает Робота, маленький
желтый квадрат в левом верхнем углу клетки &#151; конечное положение Робота, черными точками помечены клетки, которые надо закрасить.</p>
<p>Команды исполнителя Робот содержатся в
модуле <code>Robot</code>:
</p>
<blockquote>
<code>Right</code>
перемещает Робота вправо;<code><br>
Left</code> перемещает Робота влево;<code><br>
Up</code> перемещает Робота вверх;
<code>Right</code>
перемещает Робота вправо;<code><br>
Left</code> перемещает Робота влево;<code><br>
Up</code> перемещает Робота вверх;
<code><br>
Down</code> перемещает Робота вниз;
Down</code> перемещает Робота вниз;
<code><br>
Paint</code> закрашивает текущую ячейку;<code><br>
WallFromLeft</code> возвращает <code>True</code>
если слева от Робота стена;
Paint</code> закрашивает текущую ячейку;<code><br>
WallFromLeft</code> возвращает <code>True</code>
если слева от Робота стена;
<code><br>
WallFromRight</code> возвращает <code>True</code>
если справа от Робота стена;
WallFromRight</code> возвращает <code>True</code>
если справа от Робота стена;
<code><br>
WallFromUp</code> возвращает <code>True</code>
если сверху от Робота стена;
WallFromUp</code> возвращает <code>True</code>
если сверху от Робота стена;
<code><br>
WallFromDown</code> возвращает <code>True</code>
если снизу от Робота стена;
WallFromDown</code> возвращает <code>True</code>
если снизу от Робота стена;
<code><br>
FreeFromLeft</code> возвращает <code>True</code>
если слева от Робота свободно;
FreeFromLeft</code> возвращает <code>True</code>
если слева от Робота свободно;
<code><br>
FreeFromRight</code> возвращает <code>True</code>
если справа от Робота свободно;
FreeFromRight</code> возвращает <code>True</code>
если справа от Робота свободно;
<code><br>
FreeFromUp</code> возвращает <code>True</code>
если сверху от Робота свободно;
FreeFromUp</code> возвращает <code>True</code>
если сверху от Робота свободно;
<code><br>
FreeFromDown</code> возвращает <code>True</code>
если снизу от Робота свободно;
FreeFromDown</code> возвращает <code>True</code>
если снизу от Робота свободно;
<code><br>
CellIsPainted</code> возвращает <code>True</code>
если ячейка, в которой находится Робот, закрашена;
CellIsPainted</code> возвращает <code>True</code>
если ячейка, в которой находится Робот, закрашена;
<code><br>
CellIsFree</code> возвращает <code>True</code>
если ячейка, в которой находится Робот, не закрашена.
CellIsFree</code> возвращает <code>True</code>
если ячейка, в которой находится Робот, не закрашена.
</blockquote>
<p>Для вызова задания для исполнителя Робот используется
следующий шаблон программы:</p>
<p>Для вызова задания для исполнителя Робот используется
следующий шаблон программы:</p>
<blockquote>
<code><b>uses</b> Robot;<br>
<b>begin</b> <br>
@ -90,26 +90,26 @@
Task('c1'); <br>
<b>end</b>. </code>
</blockquote>
<p>Здесь <code>Task</code> &#151; процедура,
содержащаяся в модуле <code>Robot</code> и вызывающая
задание с указанным именем.</p>
<p>Имеются следующие группы заданий для исполнителя Робот:</p>
<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> переменные-счетчики;<br>
<code>mix</code> смешанные задачи;<br>
cc</code> вложенные циклы;<code><br>
p</code> процедуры без параметров;<code><br>
pp</code> процедуры с параметрами.
<code>a</code> вводные задания;<code><br>
c</code> цикл с параметром;<code><br>
if</code> логические выражения;<code><br>
w</code> циклы с условием;<code><br>
сif</code> циклы + логические выражения;<code><br>
count</code> переменные-счетчики;<br>
<code>mix</code> смешанные задачи;<br>
cc</code> вложенные циклы;<code><br>
p</code> процедуры без параметров;<code><br>
pp</code> процедуры с параметрами.
</blockquote>
<p>Для создания стандартного поля размера 7 x 9
используется процедура <code><a name="StandardField">StandardField</a></code> без параметров, а для создания
поля размера N x M &#151; процедура <code><a name="Field">Field</a>(N,M)</code>.
Робот при этом помещается в центр поля.</p>
<p>Для создания стандартного поля размера 7 x 9
используется процедура <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

@ -18,12 +18,12 @@
</head>
<body>
<H1>Модуль </span>DMTaskMaker</H1>
<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>
<b><font size="2" color="#800080"><span lang="ru">Типы</span> модуля </font></b>
<font size="2" color="#800080"><b>DMTaskMaker</b></font></td>
</tr>
</table>
@ -32,14 +32,14 @@
<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>Тип процедуры, генерирующей конкретное задание.
Каждое задание реализуется в виде отдельной процедуры; для связывания этой процедуры
с именем задания необходимо использовать процедуру <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>
<b><font size="2" color="#800080">Процедуры модуля </font></b>
<font size="2" color="#800080"><b>DMTaskMaker</b></font></td>
</tr>
</table>
@ -47,59 +47,59 @@
<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>
<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>
<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>
<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>
<p><span lang="ru">Поднимает перо Чертежника-постановщика заданий.</span></p>
<blockquote>
<p><code><b>procedure</b> DoPenDown; </code></p>
</blockquote>
<p><span lang="ru">Опускает перо Чертежника-постановщика заданий.</span></p>
<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">.
<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>Обеспечивает автоматическую регистрацию новой группы заданий в программном модуле <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>Связывает имя задания <code>name</code> с процедурой <code>p</code>, в которой реализовано данное задание.
Данную процедуру следует вызывать для <i>каждого</i> задания.
Подобно описанной выше процедуре <code>RegisterGroup</code>, процедура <code>RegisterTask</code> должна вызываться в секции инициализации
модуля, содержащего реализацию новой группы заданий для Чертежника. Порядок вызова этих процедур может быть произвольным.
</p>

View file

@ -10,11 +10,11 @@
</head>
<body>
<H1>Создание заданий для исполнителя <span lang="ru">Чертежник</span></H1>
<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>
<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>
@ -23,7 +23,7 @@
<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; TaskText('Задание mydm1. Начертите, используя цикл');<br>
&nbsp; Field(14,8);<br>
&nbsp; DoToPoint(7,7);<br>
&nbsp; a:=6;<br>
@ -40,11 +40,11 @@
&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>RegisterGroup('mydm','Мои задания для Чертежника','DMTasks',2);<br>
&nbsp; </span>RegisterTask('mydm1',FirstDM);<br>
<b>end</b>.</code></p>
</blockquote>
<p><span lang="ru">Наберем и запустим основную программу (сохранять ее в каком-либо файле не требуется):</span></p>
<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>
@ -52,9 +52,9 @@
&nbsp; Task('my<span lang="en-us">dm</span>1');<br>
<b>end</b>.</code></p>
</blockquote>
<p>Будет выведено следующее задание для <span lang="ru">Чертежника</span>:</p>
<p>Будет выведено следующее задание для <span lang="ru">Чертежника</span>:</p>
<p><img border="0" src="images/dmmake1.PNG"></p>
<p>Добавим задание на разработку процедуры:</p>
<p>Добавим задание на разработку процедуры:</p>
<blockquote>
<p><code><b>procedure</b> DoCross;<br>
<b>begin</b><br>
@ -69,7 +69,7 @@
<b>end</b>;</code></p>
<p><code><b>procedure</b> SecondDM;<br>
<b>begin</b><br>
&nbsp; TaskText('Задание mydm2. Начертите, используя процедуру Cross');<br>
&nbsp; TaskText('Задание mydm2. Начертите, используя процедуру Cross');<br>
&nbsp; Field(18,12);<br>
&nbsp; DoToPoint(3,8);<br>
&nbsp; DoCross;<br>
@ -81,15 +81,15 @@
&nbsp; DoCross;<br>
<b>end</b>;</code></p>
</blockquote>
<p>Добавим вызов процедуры регистрации для данного задания; в результате секция инициализации примет следующий вид:</p>
<p>Добавим вызов процедуры регистрации для данного задания; в результате секция инициализации примет следующий вид:</p>
<blockquote>
<p><code><b>begin</b><br>
&nbsp; RegisterGroup('mydm','Мои задания для Чертежника','DMTasks',2);<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>
<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>
@ -97,24 +97,24 @@
&nbsp; Task('my<span lang="en-us">dm2</span>');<br>
<b>end</b>.</code></p>
</blockquote>
<p>При запуске этой программы в окне исполнителя Чертежник будет выведено новое задание:</p>
<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;, то окно примет следующий вид:
При первом запуске программы с подключенным модулем <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 появилась в списке доступных групп для исполнителя Чертежник. Наберем имя задания
<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>
<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>
@ -124,7 +124,7 @@
<br>
<b>end</b>.</code></p>
</blockquote>
<p>Можно попытаться решить :)</p>
<p>Можно попытаться решить :)</p>
</body>
</html>

View file

@ -22,12 +22,12 @@
</head>
<body>
<H1>Модул<span lang="ru">ь </span>RobotTaskMaker</H1>
<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>
<b><font size="2" color="#800080"><span lang="ru">Типы</span> модуля </font></b>
<font size="2" color="#800080"><b>RobotTaskMaker</b></font></td>
</tr>
</table>
@ -36,14 +36,14 @@
<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>Тип процедуры, генерирующей конкретное задание.
Каждое задание реализуется в виде отдельной процедуры; для связывания этой процедуры
с именем задания необходимо использовать процедуру <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>
<b><font size="2" color="#800080">Процедуры модуля </font></b>
<font size="2" color="#800080"><b>RobotTaskMaker</b></font></td>
</tr>
</table>
@ -51,80 +51,80 @@
<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>
<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">
<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">
<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">
<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">
<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">
<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>
<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>
<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>
<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>
<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>Обеспечивает автоматическую регистрацию новой группы заданий в программном модуле <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>Связывает имя задания <code>name</code> с процедурой <code>p</code>, в которой реализовано данное задание.
Данную процедуру следует вызывать для <i>каждого</i> задания.
Подобно описанной выше процедуре <code>RegisterGroup</code>, процедура <code>RegisterTask</code> должна вызываться в секции инициализации
модуля, содержащего реализацию новой группы заданий для Робота. Порядок вызова этих процедур может быть произвольным.
</p>
</body>

View file

@ -10,11 +10,11 @@
</head>
<body>
<H1>Создание заданий для исполнителя Робот</H1>
<H1>Создание заданий для исполнителя Робот</H1>
<hr>
<p><span lang="ru">Опишем последовательность создания группы заданий для
исполнителя Робот. Создадим модуль </span>RobTasks.pas со следующи<span lang="ru">м
текстом:</span></p>
<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>
@ -22,7 +22,7 @@
<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>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>
@ -33,27 +33,27 @@
<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; RegisterGroup('myrob','Мои задания для Робота','RobTasks',2);<br>
&nbsp; RegisterTask('myrob1',FirstRob);<br>
<b>end</b>.</code></p>
</blockquote>
<p><span lang="ru">Наберем и запустим основную программу (сохранять ее в каком-либо файле не требуется):</span></p>
<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>
<p><img border="0" src="images/rbmake1.PNG"></p>
<p><span lang="ru">
Добавим задание, в котором конфигурация поля случайна:</span></p>
Добавим задание, в котором конфигурация поля случайна:</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>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>
@ -67,39 +67,39 @@
<span lang="ru">&nbsp;&nbsp;&nbsp; </span><b>end</b>;<br>
<b>end</b>;</code></p>
</blockquote>
<p>Добавим вызов процедуры регистрации для данного задания; в результате секция инициализации примет следующий вид:</p>
<p>Добавим вызов процедуры регистрации для данного задания; в результате секция инициализации примет следующий вид:</p>
<blockquote>
<p><code><b>begin</b><br>
&nbsp; RegisterGroup('myrob','Мои задания для Робота','RobTasks',2);<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>
<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><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;, то окно примет следующий вид:
При первом запуске программы с подключенным модулем <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 появилась в списке доступных групп для исполнителя Робот. Наберем имя задания
<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>
<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>
@ -108,7 +108,7 @@
<br>
<b>end</b>.</code></p>
</blockquote>
<p>Можно приступать к решению собственноручно разработанной задачи :)</p>
<p>Можно приступать к решению собственноручно разработанной задачи :)</p>
</body>
</html>

View file

@ -10,26 +10,26 @@
</head>
<body>
<H1>Конструкторы проверяемых заданий: обзор</span></H1>
<H1>Конструкторы проверяемых заданий: обзор</span></H1>
<hr>
<p>В системе <b>PascalABC.NET</b> можно
создавать проверяемые задания для исполнителей Робот и Чертежник, а также
для электронного задачника <b>Programming Taskbook</b>.
Задания разрабатываются с помощью конструкторов <b>RobotTaskMaker</b>, <b>DMTaskMaker</b> и
<b>PT4TaskMaker</b>; конструкторы <b>RobotTaskMaker</b> и <b>DMTaskMaker</b>
реализованы в виде одноименных модулей, конструктор <b>PT4TaskMaker</b> реализован в виде
модуля PT4TaskMakerNET. В данном разделе приводятся
подробные описания каждого из конструкторов и примеры их использования для создания новых заданий:</p>
<ul><li><a href="RobotMake.html">Модуль RobotTaskMaker</a></p>
<li><a href="RobotMakeCreation.html">Создание заданий для исполнителя Робот</a></p>
<li><a href="DMMake.html">Модуль DMTaskMaker</a></p>
<li><a href="DMMakeCreation.html">Создание заданий для исполнителя Чертежник</a></p>
<li><a href="tmaker_main.html">Модуль PT4TaskMakerNET: общее описание</a></p>
<li><a href="tmaker_proc1.html">Модуль PT4TaskMakerNET: основные компоненты</a></p>
<li><a href="tmaker_proc2.html">Модуль PT4TaskMakerNET: дополнительные компоненты</a></p>
<li><a href="tmaker_format.html">Модуль PT4TaskMakerNET: форматирование текста заданий</a></p>
<li><a href="tmaker_samples.html">Модуль PT4TaskMakerNET: примеры разработки учебных заданий</a></p>
<li><a href="tmaker_exam.html">Модуль PT4TaskMakerNET: разработка заданий, связанных с&nbsp;ЕГЭ по&nbsp;информатике</a></p>
<p>В системе <b>PascalABC.NET</b> можно
создавать проверяемые задания для исполнителей Робот и Чертежник, а также
для электронного задачника <b>Programming Taskbook</b>.
Задания разрабатываются с помощью конструкторов <b>RobotTaskMaker</b>, <b>DMTaskMaker</b> и
<b>PT4TaskMaker</b>; конструкторы <b>RobotTaskMaker</b> и <b>DMTaskMaker</b>
реализованы в виде одноименных модулей, конструктор <b>PT4TaskMaker</b> реализован в виде
модуля PT4TaskMakerNET. В данном разделе приводятся
подробные описания каждого из конструкторов и примеры их использования для создания новых заданий:</p>
<ul><li><a href="RobotMake.html">Модуль RobotTaskMaker</a></p>
<li><a href="RobotMakeCreation.html">Создание заданий для исполнителя Робот</a></p>
<li><a href="DMMake.html">Модуль DMTaskMaker</a></p>
<li><a href="DMMakeCreation.html">Создание заданий для исполнителя Чертежник</a></p>
<li><a href="tmaker_main.html">Модуль PT4TaskMakerNET: общее описание</a></p>
<li><a href="tmaker_proc1.html">Модуль PT4TaskMakerNET: основные компоненты</a></p>
<li><a href="tmaker_proc2.html">Модуль PT4TaskMakerNET: дополнительные компоненты</a></p>
<li><a href="tmaker_format.html">Модуль PT4TaskMakerNET: форматирование текста заданий</a></p>
<li><a href="tmaker_samples.html">Модуль PT4TaskMakerNET: примеры разработки учебных заданий</a></p>
<li><a href="tmaker_exam.html">Модуль PT4TaskMakerNET: разработка заданий, связанных с&nbsp;ЕГЭ по&nbsp;информатике</a></p>
</ul>
</body>

View file

@ -10,73 +10,73 @@
</head>
<body>
<H1>Модуль PT4TaskMakerNET: разработка заданий, связанных с&nbsp;ЕГЭ по&nbsp;информатике</H1>
<H1>Модуль PT4TaskMakerNET: разработка заданий, связанных с&nbsp;ЕГЭ по&nbsp;информатике</H1>
<hr>
<h2>Группы заданий Exam и их особенности</h2>
<p>Начиная с версии 4.10, в базовый набор задачника Programming Taskbook
для языков Pascal и C++ входят
специальные группы заданий, связанные с ЕГЭ по информатике: ExamBegin и ExamTaskC.
Порядок выполнения заданий из этих групп имеет ряд особенностей, основной из которых
является отказ от применения специальных средств ввода-вывода, входящих в состав
задачника. В заданиях групп Exam для ввода-вывода надо применять стандартные средства
используемого языка программирования. Это позволяет максимально приблизить вид программы,
выполняющей задание, к виду, требуемому на экзамене, а также учесть при выполнении задания
его дополнительные особенности, связанные с организацией ввода исходных данных и форматированием
результатов.
<h2>Группы заданий Exam и их особенности</h2>
<p>Начиная с версии 4.10, в базовый набор задачника Programming Taskbook
для языков Pascal и C++ входят
специальные группы заданий, связанные с ЕГЭ по информатике: ExamBegin и ExamTaskC.
Порядок выполнения заданий из этих групп имеет ряд особенностей, основной из которых
является отказ от применения специальных средств ввода-вывода, входящих в состав
задачника. В заданиях групп Exam для ввода-вывода надо применять стандартные средства
используемого языка программирования. Это позволяет максимально приблизить вид программы,
выполняющей задание, к виду, требуемому на экзамене, а также учесть при выполнении задания
его дополнительные особенности, связанные с организацией ввода исходных данных и форматированием
результатов.
</p>
<p>С использованием конструктора учебных заданий PT4TaskMaker преподаватель может разрабатывать
новые группы заданий, связанные с ЕГЭ по информатике. При этом необходимо следовать
дополнительным правилам, основные из которых приводятся ниже.
<p>С использованием конструктора учебных заданий PT4TaskMaker преподаватель может разрабатывать
новые группы заданий, связанные с ЕГЭ по информатике. При этом необходимо следовать
дополнительным правилам, основные из которых приводятся ниже.
</p>
<a name="list"></a>
<ol><li>Любые группы заданий, связанные с ЕГЭ по информатике, должны иметь имена, начинающиеся
с префикса Exam (для групп с этим префиксом задачник генерирует специальные программы-заготовки,
позволяющие использовать при выполнении задания стандартные средства ввода-вывода).
<li>Необходимо проверять номер текущей версии задачника и текущий язык программирования, создавая
новую группу тольков случае, если версия имеет номер не ниже 4.10, а языком программирования является
Pascal или C++.
<li>В преамбуле к группе заданий желательно отметить тот факт, что для ввода-вывода необходимо
использовать стандартные средства языка.
<li>В новые группы Exam следует импортировать только те задания, которые также относятся к группам Exam.
<li>Набор исходных и контрольных данных надо сохранять в текстовых файлах, передавая задачнику
информацию об именах этих файлов (процедурами DataS) и связывая содержимое этих файлов
с разделами исходных и результирующих данных (процедурами DataFileT и ResultFileT соответственно).
<li>При любых вариантах наборов исходных данных соответствующие контрольные файлы не должны быть пустыми
(при наличии пустого файла результатов задачник считает запуск программы ознакомительным).
<ol><li>Любые группы заданий, связанные с ЕГЭ по информатике, должны иметь имена, начинающиеся
с префикса Exam (для групп с этим префиксом задачник генерирует специальные программы-заготовки,
позволяющие использовать при выполнении задания стандартные средства ввода-вывода).
<li>Необходимо проверять номер текущей версии задачника и текущий язык программирования, создавая
новую группу тольков случае, если версия имеет номер не ниже 4.10, а языком программирования является
Pascal или C++.
<li>В преамбуле к группе заданий желательно отметить тот факт, что для ввода-вывода необходимо
использовать стандартные средства языка.
<li>В новые группы Exam следует импортировать только те задания, которые также относятся к группам Exam.
<li>Набор исходных и контрольных данных надо сохранять в текстовых файлах, передавая задачнику
информацию об именах этих файлов (процедурами DataS) и связывая содержимое этих файлов
с разделами исходных и результирующих данных (процедурами DataFileT и ResultFileT соответственно).
<li>При любых вариантах наборов исходных данных соответствующие контрольные файлы не должны быть пустыми
(при наличии пустого файла результатов задачник считает запуск программы ознакомительным).
</ol>
<p>Проиллюстрируем эти правила, разработав в среде PascalABC.NET демонстрационную группу заданий ExamDemo.
Задания, связанные с ЕГЭ, вполне допустимо разрабатывать и на других языках, поддерживаемых
конструктором учебных заданий, в частности, на языке C++ или на языке Pascal в средах Delphi или Lazarus,
причем полученные реализации не будут иметь никаких существенных отличий от реализации, приведенной ниже.
Задания можно разрабатывать даже на языке C#, несмотря на то что <i>выполнять</i> их на этом языке будет нельзя.
<p>Проиллюстрируем эти правила, разработав в среде PascalABC.NET демонстрационную группу заданий ExamDemo.
Задания, связанные с ЕГЭ, вполне допустимо разрабатывать и на других языках, поддерживаемых
конструктором учебных заданий, в частности, на языке C++ или на языке Pascal в средах Delphi или Lazarus,
причем полученные реализации не будут иметь никаких существенных отличий от реализации, приведенной ниже.
Задания можно разрабатывать даже на языке C#, несмотря на то что <i>выполнять</i> их на этом языке будет нельзя.
</p>
<h2>Реализация сводной группы заданий</h2>
<p>Напомним, что <i>сводной группой</i> называется группа, все задания которой импортированы из уже имеющихся групп.
Сводные группы оказываются очень полезными при составлении вариантов проверочных работ, поскольку
позволяют дать заданиям новые имена и тем самым затрудняют применение разного рода шпаргалок.
<h2>Реализация сводной группы заданий</h2>
<p>Напомним, что <i>сводной группой</i> называется группа, все задания которой импортированы из уже имеющихся групп.
Сводные группы оказываются очень полезными при составлении вариантов проверочных работ, поскольку
позволяют дать заданиям новые имена и тем самым затрудняют применение разного рода шпаргалок.
</p>
<p>Так как в сводных группах отсутствуют новые задания, при разработке сводных групп для заданий, связанных
с ЕГЭ по информатике, достаточно учесть правила 1&#150;4, приведенные в предыдущем пункте.
<p>Так как в сводных группах отсутствуют новые задания, при разработке сводных групп для заданий, связанных
с ЕГЭ по информатике, достаточно учесть правила 1&#150;4, приведенные в предыдущем пункте.
</p>
<p>Будем предполагать, что общие правила разработки новых
групп заданий в среде PascalABC.NET читателю известны (см. раздел &laquo;<a href="tmaker_samples.html">Примеры</a>&raquo;).
<p>Будем предполагать, что общие правила разработки новых
групп заданий в среде PascalABC.NET читателю известны (см. раздел &laquo;<a href="tmaker_samples.html">Примеры</a>&raquo;).
</p>
<p>Следуя правилам именования групп (имя должно состоять из латинских букв и цифр, иметь длину не более 9
символов и не оканчиваться цифрой), а также правилу 1 из предыдущего пункта
(наличие префикса Exam),
назовем нашу группу ExamDemo. Динамическая библиотека в этом случае должна иметь имя PT4ExamDemo.
<p>Следуя правилам именования групп (имя должно состоять из латинских букв и цифр, иметь длину не более 9
символов и не оканчиваться цифрой), а также правилу 1 из предыдущего пункта
(наличие префикса Exam),
назовем нашу группу ExamDemo. Динамическая библиотека в этом случае должна иметь имя PT4ExamDemo.
</p>
<p>Импортируем в группу ExamDemo несколько заданий из обеих групп Exam, входящих в базовый набор.
Из группы ExamBegin возьмем задания ExamBegin71 и ExamBegin72,
входящие в подгруппу &laquo;Преобразование массивов&raquo;
и связанные перестановкой элементов массива.
Из группы ExamTaskC возьмем серию из 12 заданий ExamTaskC25&#150;ExamTaskC36,
объединенных общей предметной областью: сведениями об абитуриентах из различных школ.
<p>Импортируем в группу ExamDemo несколько заданий из обеих групп Exam, входящих в базовый набор.
Из группы ExamBegin возьмем задания ExamBegin71 и ExamBegin72,
входящие в подгруппу &laquo;Преобразование массивов&raquo;
и связанные перестановкой элементов массива.
Из группы ExamTaskC возьмем серию из 12 заданий ExamTaskC25&#150;ExamTaskC36,
объединенных общей предметной областью: сведениями об абитуриентах из различных школ.
</p>
<p>Учитывая правила подготовки динамических библиотек с группами учебных заданий,
а также правила 2 и 3 из предыдущего пункта, получим следующий вариант нашей библиотеки (файл PT4ExamDemo.pas):
<p>Учитывая правила подготовки динамических библиотек с группами учебных заданий,
а также правила 2 и 3 из предыдущего пункта, получим следующий вариант нашей библиотеки (файл PT4ExamDemo.pas):
</p>
<pre>library PT4ExamDemo;
@ -95,14 +95,14 @@ begin
if (CurrentVersion &lt; '4.10') or
(CurrentLanguage and (lgPascal or lgCPP) = 0) then
exit;
CreateGroup('ExamDemo', '^ЕГЭ по информатике: примеры различных задач',
'М. Э. Абрамян, 2013', 'qdfedsag33gbg45j', 14, InitTask);
CommentText('\PПри выполнении заданий данной группы вместо');
CommentText('специальных операций ввода-вывода, предоставляемых');
CommentText('задачником, необходимо применять стандартные операции');
CommentText('используемого языка программирования: процедуры');
CommentText('\MRead\m/\MReadln\m\:\MWrite\m/\MWriteln\m для языка');
CommentText('Pascal, потоки \Mcin\m\:\Mcout\m для языка C++.');
CreateGroup('ExamDemo', '^ЕГЭ по информатике: примеры различных задач',
'М. Э. Абрамян, 2013', 'qdfedsag33gbg45j', 14, InitTask);
CommentText('\PПри выполнении заданий данной группы вместо');
CommentText('специальных операций ввода-вывода, предоставляемых');
CommentText('задачником, необходимо применять стандартные операции');
CommentText('используемого языка программирования: процедуры');
CommentText('\MRead\m/\MReadln\m\:\MWrite\m/\MWriteln\m для языка');
CommentText('Pascal, потоки \Mcin\m\:\Mcout\m для языка C++.');
end;
procedure activate(S: string);
@ -113,55 +113,55 @@ end;
begin
end.
</pre>
<p>Кратко опишем полученную программу. Вначале к ней подключается модуль PT4TaskMakerNET, в котором
реализован конструктор учебных заданий для среды PascalABC.NET.
Затем следует описание основной процедуры группы заданий
<a href="tmaker_proc1.html#TInitTaskProc">InitTask</a>, определяющей задание по его номеру.
Поскольку мы не создавали своих заданий, в данной процедуре
используется только стандартная процедура <a href="tmaker_proc1.html#UseTask">UseTask</a>, позволяющая
импортировать задания из имеющихся групп.
В нашем случае импортируются задания с номерами 71 и 72 из группы ExamBegin и задания с номерами 25&#150;36
из группы ExamTaskC (всего 14 заданий).
<p>Кратко опишем полученную программу. Вначале к ней подключается модуль PT4TaskMakerNET, в котором
реализован конструктор учебных заданий для среды PascalABC.NET.
Затем следует описание основной процедуры группы заданий
<a href="tmaker_proc1.html#TInitTaskProc">InitTask</a>, определяющей задание по его номеру.
Поскольку мы не создавали своих заданий, в данной процедуре
используется только стандартная процедура <a href="tmaker_proc1.html#UseTask">UseTask</a>, позволяющая
импортировать задания из имеющихся групп.
В нашем случае импортируются задания с номерами 71 и 72 из группы ExamBegin и задания с номерами 25&#150;36
из группы ExamTaskC (всего 14 заданий).
</p>
<p>Затем описывается процедура инициализации данной группы заданий. Она имеет стандартное имя inittaskgroup
(набранное строчными, т.&nbsp;е. маленькими буквами). В этой процедуре
вызывается процедура <a href="tmaker_proc1.html#CreateGroup">CreateGroup</a>, в которой задаются
характеристики создаваемой группы:
имя (<code>'ExamDemo'</code>), описание (<code>'^ЕГЭ по информатике: примеры различных задач'</code>), сведения об авторе,
строковый ключ, число заданий (<code>14</code>) и основная процедура группы (<code>InitTask</code>).
<p>Затем описывается процедура инициализации данной группы заданий. Она имеет стандартное имя inittaskgroup
(набранное строчными, т.&nbsp;е. маленькими буквами). В этой процедуре
вызывается процедура <a href="tmaker_proc1.html#CreateGroup">CreateGroup</a>, в которой задаются
характеристики создаваемой группы:
имя (<code>'ExamDemo'</code>), описание (<code>'^ЕГЭ по информатике: примеры различных задач'</code>), сведения об авторе,
строковый ключ, число заданий (<code>14</code>) и основная процедура группы (<code>InitTask</code>).
</p>
<p>Поскольку надо гарантировать, что группа будет создана только в случае использования задачника версии не ниже 4.10
и только для языков Pascal и С++, перед вызовом процедуры инициализации группы CreateGroup выполняется проверка
перечисленных выше условий. Если хотя бы одно из условий нарушено, то выполняется немедленный выход из
процедуры inittaskgroup, и группа ExamDemo не создается.
<p>Поскольку надо гарантировать, что группа будет создана только в случае использования задачника версии не ниже 4.10
и только для языков Pascal и С++, перед вызовом процедуры инициализации группы CreateGroup выполняется проверка
перечисленных выше условий. Если хотя бы одно из условий нарушено, то выполняется немедленный выход из
процедуры inittaskgroup, и группа ExamDemo не создается.
</p>
<p>Следует обратить внимание на наличие символа-метки &laquo;^&raquo; в начале строки-описания группы.
Этот символ отменяет автоматическое преобразование к нижнему регистру
первой буквы описания при его выводе в программных модулях PT4Demo и PT4Load (если бы символ &laquo;^&raquo;
отсутствовал, то строка с описанием данной группы имела бы вид &laquo;Тема: еГЭ по информатике:
примеры различных задач&raquo;).
<p>Следует обратить внимание на наличие символа-метки &laquo;^&raquo; в начале строки-описания группы.
Этот символ отменяет автоматическое преобразование к нижнему регистру
первой буквы описания при его выводе в программных модулях PT4Demo и PT4Load (если бы символ &laquo;^&raquo;
отсутствовал, то строка с описанием данной группы имела бы вид &laquo;Тема: еГЭ по информатике:
примеры различных задач&raquo;).
</p>
<p>Наконец, в соответствии с правилом 3, мы включили в создаваемую группу <i>преамбулу</i>,
в которой отмечается основная особенность данной группы: необходимость использования
стандартных средств ввода-вывода (для определения текста преамбулы вызываются
процедуры <a href="tmaker_proc1.html#CommentText">CommentText</a>). Обратите внимание на управляющие
последовательности <code>\M</code>&#150;<code>\m</code>, позволяющие отобразить фрагмент текста <code>моноширинным шрифтом</code>.
<p>Наконец, в соответствии с правилом 3, мы включили в создаваемую группу <i>преамбулу</i>,
в которой отмечается основная особенность данной группы: необходимость использования
стандартных средств ввода-вывода (для определения текста преамбулы вызываются
процедуры <a href="tmaker_proc1.html#CommentText">CommentText</a>). Обратите внимание на управляющие
последовательности <code>\M</code>&#150;<code>\m</code>, позволяющие отобразить фрагмент текста <code>моноширинным шрифтом</code>.
</p>
<p>После процедуры inittaskgroup описывается вспомогательная процедура activate
(ее имя также должно быть набрано строчными буквами), в которой необходимо вызвать
процедуру ActivateNET, описанную в модуле PT4TaskMakerNET.
<p>После процедуры inittaskgroup описывается вспомогательная процедура activate
(ее имя также должно быть набрано строчными буквами), в которой необходимо вызвать
процедуру ActivateNET, описанную в модуле PT4TaskMakerNET.
</p>
<p>Для успешной компиляции программы с созданной группой необходимо, чтобы ей был доступен
модуль PT4TaskMakerNET. Этот модуль входит в число стандартных модулей библиотеки системы PascalABC.NET
и размещается в подкаталоге LIB системного каталога PascalABC.NET, поэтому копировать его в рабочий каталог
не требуется.
<p>Для успешной компиляции программы с созданной группой необходимо, чтобы ей был доступен
модуль PT4TaskMakerNET. Этот модуль входит в число стандартных модулей библиотеки системы PascalABC.NET
и размещается в подкаталоге LIB системного каталога PascalABC.NET, поэтому копировать его в рабочий каталог
не требуется.
</p>
<p>Для того чтобы при успешной компиляции можно было сразу просмотреть содержимое созданной группы,
достаточно использовать вспомогательную тестирующую программу, являющуюся заготовкой для выполнения
заданий из созданной группы.
Эту программу проще всего создать с помощью программного модуля PT4Load,
нажав комбинацию клавиш [Shift]+[Ctrl]+[L] и введя в поле &laquo;Задание&raquo;; имя первого задания
группы: ExamDemo1. В результате будет создан файл с именем ExamDemo1.pas со следующим содержимым:
<p>Для того чтобы при успешной компиляции можно было сразу просмотреть содержимое созданной группы,
достаточно использовать вспомогательную тестирующую программу, являющуюся заготовкой для выполнения
заданий из созданной группы.
Эту программу проще всего создать с помощью программного модуля PT4Load,
нажав комбинацию клавиш [Shift]+[Ctrl]+[L] и введя в поле &laquo;Задание&raquo;; имя первого задания
группы: ExamDemo1. В результате будет создан файл с именем ExamDemo1.pas со следующим содержимым:
</p>
<pre>uses PT4Exam;
@ -170,82 +170,82 @@ begin
end.
</pre>
<p>Следует обратить внимание на то, что к созданной программе подключается не традиционный модуль
задачника PT4, а специальный его вариант PT4Exam, используемый для заданий, связанных с ЕГЭ.
<p>Следует обратить внимание на то, что к созданной программе подключается не традиционный модуль
задачника PT4, а специальный его вариант PT4Exam, используемый для заданий, связанных с ЕГЭ.
</p>
<p>Для того чтобы тестирующая программа отображала задания в демонстрационном режиме, причем
при ее запуске на экране отображалось последнее из заданий, включенных в группу, достаточно заменить
в процедуре Task номер задания на символ &laquo;?&raquo;: <code>Task('ExamDemo?')</code>.
<p>Для того чтобы тестирующая программа отображала задания в демонстрационном режиме, причем
при ее запуске на экране отображалось последнее из заданий, включенных в группу, достаточно заменить
в процедуре Task номер задания на символ &laquo;?&raquo;: <code>Task('ExamDemo?')</code>.
</p>
<p>Теперь при запуске тестирующей программы на экране отобразится окно задачника с заданием ExamDemo14:
<p>Теперь при запуске тестирующей программы на экране отобразится окно задачника с заданием ExamDemo14:
</p>
<p class="ris"><img border="0" src="images\pt4exam1a.png">
</p>
<p>По умолчанию окно задачника отображается в режиме с динамической компоновкой, который появился
в версии 4.11 и является более наглядным, чем режим с фиксированной компоновкой. Однако
при разработке заданий желательно применять режим с фиксированной компоновкой, поскольку
он позволит выявить недостатки форматирования (в частности, вертикального выравнивания данных),
присущие только этому режиму. Для переключения между режимами отображения данных достаточно нажать клавишу
[F4]. После выполнения этого действия окно задачника изменится следующим образом:
<p>По умолчанию окно задачника отображается в режиме с динамической компоновкой, который появился
в версии 4.11 и является более наглядным, чем режим с фиксированной компоновкой. Однако
при разработке заданий желательно применять режим с фиксированной компоновкой, поскольку
он позволит выявить недостатки форматирования (в частности, вертикального выравнивания данных),
присущие только этому режиму. Для переключения между режимами отображения данных достаточно нажать клавишу
[F4]. После выполнения этого действия окно задачника изменится следующим образом:
</p>
<p class="ris"><img border="0" src="images\pt4exam1.png">
</p>
<p>В окне задачника можно просматривать все имеющиеся задания данной группы
(нажимая клавиши [Enter] и [Backspace], а также генерировать различные варианты исходных данных
и связанных с ними контрольных (т.&nbsp;е. &laquo;правильных&raquo;) результатов. При закрытии окна
программа немедленно завершит работу, и мы вернемся в редактор среды PascalABC.NET.
Заметим, что при последующих запусках программы будет автоматически выбираться тот режим окна
задачника, в котором оно находилось в момент его предшествующего закрытия.
<p>В окне задачника можно просматривать все имеющиеся задания данной группы
(нажимая клавиши [Enter] и [Backspace], а также генерировать различные варианты исходных данных
и связанных с ними контрольных (т.&nbsp;е. &laquo;правильных&raquo;) результатов. При закрытии окна
программа немедленно завершит работу, и мы вернемся в редактор среды PascalABC.NET.
Заметим, что при последующих запусках программы будет автоматически выбираться тот режим окна
задачника, в котором оно находилось в момент его предшествующего закрытия.
</p>
<p>Для того чтобы cгенерировать html-страницу с описанием созданной группы (это позволяет, в частности,
увидеть текст преамбулы группы), достаточно в процедуре Task тестирующей программы заменить символ &laquo;?&raquo;
на символ &laquo;#&raquo;: <code>Task('ExamDemo#')</code>.
Теперь при запуске этой программы на экране вместо окна задачника с заданием ExamDemo14
появится html-браузер с описанием созданной группы:
<p>Для того чтобы cгенерировать html-страницу с описанием созданной группы (это позволяет, в частности,
увидеть текст преамбулы группы), достаточно в процедуре Task тестирующей программы заменить символ &laquo;?&raquo;
на символ &laquo;#&raquo;: <code>Task('ExamDemo#')</code>.
Теперь при запуске этой программы на экране вместо окна задачника с заданием ExamDemo14
появится html-браузер с описанием созданной группы:
</p>
<p class="ris"><img border="1" src="images\pt4exam2.png">
</p>
<h2>Добавление новых заданий</h2>
<p>Добавим к нашей группе новые задания. Подобно заданиям, импортированным
из группы ExamBegin, они будут посвящены преобразованию массивов путем перестановки их элементов.
Если импортированные задания были посвящены инвертированию массива (или его части), то в новых
заданиях надо будет выполнить перестановку всех пар элементов или перестановку первой и второй
половины массива. Чтобы не уточнять действия в случае массивов нечетного размера,
добавим в задание условие о том, что исходный массив всегда имеет четный размер.
Тип элементов массива для подобных заданий является несущественным, поэтому будем обрабатывать
массивы вещественных чисел. Таким образом, набор исходных данных будет иметь вид, подобный
набору из задания ExamDemo2 (см. формулировку этого задания, приведенную на предыдущем рисунке).
Оформление вывода результатов также не будет отличаться от
оформления, требуемого в задании ExamDemo2.
<h2>Добавление новых заданий</h2>
<p>Добавим к нашей группе новые задания. Подобно заданиям, импортированным
из группы ExamBegin, они будут посвящены преобразованию массивов путем перестановки их элементов.
Если импортированные задания были посвящены инвертированию массива (или его части), то в новых
заданиях надо будет выполнить перестановку всех пар элементов или перестановку первой и второй
половины массива. Чтобы не уточнять действия в случае массивов нечетного размера,
добавим в задание условие о том, что исходный массив всегда имеет четный размер.
Тип элементов массива для подобных заданий является несущественным, поэтому будем обрабатывать
массивы вещественных чисел. Таким образом, набор исходных данных будет иметь вид, подобный
набору из задания ExamDemo2 (см. формулировку этого задания, приведенную на предыдущем рисунке).
Оформление вывода результатов также не будет отличаться от
оформления, требуемого в задании ExamDemo2.
</p>
<p>Прежде чем приступать к реализации заданий, добавим в начало нашей библиотеки
описание ряда вспомогательных переменных, процедур и функций.
<p>Прежде чем приступать к реализации заданий, добавим в начало нашей библиотеки
описание ряда вспомогательных переменных, процедур и функций.
</p>
<p>Первая функция упрощает генерацию случайных исходных данных вещественного типа
с не более чем двумя дробными знаками:
<p>Первая функция упрощает генерацию случайных исходных данных вещественного типа
с не более чем двумя дробными знаками:
</p>
<pre>function RandR(a, b: integer): real;
begin
result := RandomN(a*100, b*100)/100;
end;
</pre>
<p>При реализации функции RandR мы использовали функцию <a href="tmaker_proc1.html#Random">RandomN</a>, входящую в состав
конструктора учебных заданий, начиная с версии 4.11 (функция RandomN(M, N) возвращает
случайное целое число, лежащее в диапазоне M..N, включая границы диапазона). Функция
RandR(a, b) (a и b &#151; целые) возвращает вещественное число, лежащее в диапазоне a..b
и <i>имеющее не более двух дробных знаков</i>. Такие числа можно без потери точности
записывать в текстовый файл в формате с двумя дробными
знаками; таким образом, программа учащегося прочтет из файла именно то число,
которое было сгенерировано при инициализации задания. Напомним, что в версии 4.11 конструктора
имеется функция RandomR, также предназначенная для генерации случайных вещественных чисел, однако она
не позволяет фиксировать число дробных знаков, и поэтому менее пригодна для генерации
данных, предназначенных для записи в текстовые файлы.
<p>При реализации функции RandR мы использовали функцию <a href="tmaker_proc1.html#Random">RandomN</a>, входящую в состав
конструктора учебных заданий, начиная с версии 4.11 (функция RandomN(M, N) возвращает
случайное целое число, лежащее в диапазоне M..N, включая границы диапазона). Функция
RandR(a, b) (a и b &#151; целые) возвращает вещественное число, лежащее в диапазоне a..b
и <i>имеющее не более двух дробных знаков</i>. Такие числа можно без потери точности
записывать в текстовый файл в формате с двумя дробными
знаками; таким образом, программа учащегося прочтет из файла именно то число,
которое было сгенерировано при инициализации задания. Напомним, что в версии 4.11 конструктора
имеется функция RandomR, также предназначенная для генерации случайных вещественных чисел, однако она
не позволяет фиксировать число дробных знаков, и поэтому менее пригодна для генерации
данных, предназначенных для записи в текстовые файлы.
</p>
<p>Поскольку в обоих заданиях нам потребуется выполнять обмен значений, содержащихся в вещественных переменных,
опишем процедуру, которая выполняет подобный обмен:
<p>Поскольку в обоих заданиях нам потребуется выполнять обмен значений, содержащихся в вещественных переменных,
опишем процедуру, которая выполняет подобный обмен:
</p>
<pre>procedure SwapR(var a, b: real);
var
@ -256,34 +256,34 @@ begin
b := c;
end;
</pre>
<p>Следующая группа вспомогательных переменных и процедур связана с особенностью заданий типа Exam, описанной
в правиле 5 (см. первый пункт данного раздела). Ввиду важности этого правила приведем его еще раз:
<p>Следующая группа вспомогательных переменных и процедур связана с особенностью заданий типа Exam, описанной
в правиле 5 (см. первый пункт данного раздела). Ввиду важности этого правила приведем его еще раз:
</p>
<ul><li>Набор исходных и контрольных данных надо сохранять в текстовых файлах, передавая задачнику
информацию об именах этих файлов (процедурами DataS) и связывая содержимое этих файлов
с разделами исходных и результирующих данных (процедурами DataFileT и ResultFileT соответственно).
<ul><li>Набор исходных и контрольных данных надо сохранять в текстовых файлах, передавая задачнику
информацию об именах этих файлов (процедурами DataS) и связывая содержимое этих файлов
с разделами исходных и результирующих данных (процедурами DataFileT и ResultFileT соответственно).
</ul>
<p>Таким образом, при инициализации каждого задания группы Exam надо выполнить следующие действия:
<p>Таким образом, при инициализации каждого задания группы Exam надо выполнить следующие действия:
</p>
<ol><li>Сгенерировать имена файлов, содержащих исходные и контрольные данные (эти имена должны быть различными
и меняться при каждом тестовом испытании программы; кроме того, подобно всем файлам, используемым в заданиях,
они должны иметь расширение .tst).
<li>Связать созданные имена с файловыми переменными и открыть эти файлы на запись.
<li>Заполнить файлы необходимыми данными.
<li>Закрыть файлы с исходными и контрольными данными.
<li>Передать задачнику информацию об именах созданных файлов, чтобы при выполнении задания эта
информация была использована при связывании файлов со стандартными потоками ввода-вывода.
<li>Передать задачнику информацию о том, что первый из созданных файлов должен
быть включен в раздел исходных данных, а второй &#151; в раздел результатов; это, во-первых, позволит
отобразить содержимое файлов в окне задачника и, во-вторых, обеспечит проверку правильности
результирующего файла, созданного программой учащегося (путем его сравнения с данными контрольного файла).
<ol><li>Сгенерировать имена файлов, содержащих исходные и контрольные данные (эти имена должны быть различными
и меняться при каждом тестовом испытании программы; кроме того, подобно всем файлам, используемым в заданиях,
они должны иметь расширение .tst).
<li>Связать созданные имена с файловыми переменными и открыть эти файлы на запись.
<li>Заполнить файлы необходимыми данными.
<li>Закрыть файлы с исходными и контрольными данными.
<li>Передать задачнику информацию об именах созданных файлов, чтобы при выполнении задания эта
информация была использована при связывании файлов со стандартными потоками ввода-вывода.
<li>Передать задачнику информацию о том, что первый из созданных файлов должен
быть включен в раздел исходных данных, а второй &#151; в раздел результатов; это, во-первых, позволит
отобразить содержимое файлов в окне задачника и, во-вторых, обеспечит проверку правильности
результирующего файла, созданного программой учащегося (путем его сравнения с данными контрольного файла).
</ol>
<p>От условий конкретного задания будет зависеть только действие 3, связанное с заполнением файлов нужными данными.
Все остальные действия являются стандартными и должны выполняться при инициализации любого задания групп Exam.
Поэтому удобно оформить эти действия в виде двух вспомогательных процедур, одна из которых (StartExam) выполняет
начальные действия 1&#150;2, а другая (EndExam) &#151; завершающие действия 4&#150;6. Поскольку в каждой из этих
процедур необходимо использовать имена созданных файлов и связанные с ними файловые переменные, эти переменные
удобно описать как глобальные:
<p>От условий конкретного задания будет зависеть только действие 3, связанное с заполнением файлов нужными данными.
Все остальные действия являются стандартными и должны выполняться при инициализации любого задания групп Exam.
Поэтому удобно оформить эти действия в виде двух вспомогательных процедур, одна из которых (StartExam) выполняет
начальные действия 1&#150;2, а другая (EndExam) &#151; завершающие действия 4&#150;6. Поскольку в каждой из этих
процедур необходимо использовать имена созданных файлов и связанные с ними файловые переменные, эти переменные
удобно описать как глобальные:
</p>
<pre>var
f1,f2: text;
@ -312,57 +312,57 @@ begin
ResultFileT(f2name, 1, 5);
end;
</pre>
<p>Обсудим особенности этих процедур. Имена файлов, создаваемых в процедуре StartExam,
имеют вид pt1#####.tst (для файла с исходными
данными) и pt2#####.tst (для файла с контрольными данными), причем в позициях, помеченных символом &laquo;#&raquo;,
располагаются цифры, выбираемые случайным образом. Тем самым обеспечиваются все требования к именам файлов:
они генерируются случайным образом, имеют расширение .tst, и имя файла с исходными данными всегда отличается
от имени контрольного файла. Напомним, что все файлы с расширением .tst автоматически удаляются из рабочего каталога
после проверки учебного задания.
<p>Обсудим особенности этих процедур. Имена файлов, создаваемых в процедуре StartExam,
имеют вид pt1#####.tst (для файла с исходными
данными) и pt2#####.tst (для файла с контрольными данными), причем в позициях, помеченных символом &laquo;#&raquo;,
располагаются цифры, выбираемые случайным образом. Тем самым обеспечиваются все требования к именам файлов:
они генерируются случайным образом, имеют расширение .tst, и имя файла с исходными данными всегда отличается
от имени контрольного файла. Напомним, что все файлы с расширением .tst автоматически удаляются из рабочего каталога
после проверки учебного задания.
</p>
<p>При анализе процедуры EndExam следует обратить внимание на то, что информация о содержимом исходного файла
занимает всю область исходных данных (строки с первой по пятую &#151; см. вызов процедуры
<p>При анализе процедуры EndExam следует обратить внимание на то, что информация о содержимом исходного файла
занимает всю область исходных данных (строки с первой по пятую &#151; см. вызов процедуры
<a href="tmaker_proc2.html#DataFile">DataFileT</a>)
и, таким образом, она <i>скрывает</i>
информацию об именах файлов, ранее выведенную в первой строке области исходных данных (см. вызовы процедур
и, таким образом, она <i>скрывает</i>
информацию об именах файлов, ранее выведенную в первой строке области исходных данных (см. вызовы процедур
<a href="tmaker_proc1.html#DataN">DataS</a>).
В обычном задании такая реализация была бы ошибочной, поскольку учащийся не увидел бы
на экране имена файлов и не понял бы, что эти имена необходимо ввести и обработать в его программе.
Однако в задании групп Exam именно такая реализация является правильной, поскольку
ввод имен файлов и связывание этих файлов со стандартными потоками ввода-вывода выполняется
автоматически (&laquo;незаметно&raquo; для программы учащегося), и поэтому информацию
об именах файлов на экране отображать не следует.
В обычном задании такая реализация была бы ошибочной, поскольку учащийся не увидел бы
на экране имена файлов и не понял бы, что эти имена необходимо ввести и обработать в его программе.
Однако в задании групп Exam именно такая реализация является правильной, поскольку
ввод имен файлов и связывание этих файлов со стандартными потоками ввода-вывода выполняется
автоматически (&laquo;незаметно&raquo; для программы учащегося), и поэтому информацию
об именах файлов на экране отображать не следует.
</p>
<p>Итак, наличие процедур StartExam и EndExam позволяет нам упростить
реализацию заданий: после определения формулировки любого задания нам достаточно
вызвать процедуру StartExam, заполнить файлы f1 и f2 исходными и, соответственно,
контрольными данными и вызвать процедуру EndExam.
<p>Итак, наличие процедур StartExam и EndExam позволяет нам упростить
реализацию заданий: после определения формулировки любого задания нам достаточно
вызвать процедуру StartExam, заполнить файлы f1 и f2 исходными и, соответственно,
контрольными данными и вызвать процедуру EndExam.
</p>
<p>Приступим к непосредственной реализации заданий. Поскольку эти задания являются однотипными,
реализуем их в одной процедуре Exam1, снабдив ее параметром m: при m&nbsp;=&nbsp;1 будет инициализироваться
первое задание, а при m&nbsp;=&nbsp;2 &#151; второе:
<p>Приступим к непосредственной реализации заданий. Поскольку эти задания являются однотипными,
реализуем их в одной процедуре Exam1, снабдив ее параметром m: при m&nbsp;=&nbsp;1 будет инициализироваться
первое задание, а при m&nbsp;=&nbsp;2 &#151; второе:
</p>
<pre>procedure Exam1(m: integer);
var
n, i: integer;
a: array[1..10] of real;
begin
CreateTask('Преобразование массивов');
CreateTask('Преобразование массивов');
case m of
1:
begin
TaskText('На вход в первой строке подается целое положительное четное число {N},', 0, 1);
TaskText('а во второй строке \= массив из {N} вещественных чисел. Поменять местами', 0, 2);
TaskText('его первый элемент со вторым, третий с четвертым, и т.\,д. Вывести', 0, 3);
TaskText('преобразованный массив в одной строке, для каждого элемента', 0, 4);
TaskText('отводить 7 экранных позиций.', 0, 5);
TaskText('На вход в первой строке подается целое положительное четное число {N},', 0, 1);
TaskText('а во второй строке \= массив из {N} вещественных чисел. Поменять местами', 0, 2);
TaskText('его первый элемент со вторым, третий с четвертым, и т.\,д. Вывести', 0, 3);
TaskText('преобразованный массив в одной строке, для каждого элемента', 0, 4);
TaskText('отводить 7 экранных позиций.', 0, 5);
end;
2:
begin
TaskText('На вход в первой строке подается целое положительное четное число {N},', 0, 2);
TaskText('а во второй строке \= массив из {N} вещественных чисел. Поменять местами', 0, 3);
TaskText('первую и вторую половину элементов массива. Вывести преобразованный массив', 0, 4);
TaskText('в одной строке, для каждого элемента отводить 7 экранных позиций.', 0, 5);
TaskText('На вход в первой строке подается целое положительное четное число {N},', 0, 2);
TaskText('а во второй строке \= массив из {N} вещественных чисел. Поменять местами', 0, 3);
TaskText('первую и вторую половину элементов массива. Вывести преобразованный массив', 0, 4);
TaskText('в одной строке, для каждого элемента отводить 7 экранных позиций.', 0, 5);
end;
end;
StartExam;
@ -385,34 +385,34 @@ begin
SetTestCount(3);
end;
</pre>
<p>Обратите внимание на то, что при вызове процедуры CreateTask ей передается строковый параметр, содержащий
имя подгруппы &laquo;Преобразование массивов&raquo;. Это обеспечивает включение новых заданий
в подгруппу, с которой связаны ранее импортированные в нашу группу задания ExamBegin71 и ExamBegin72.
<p>Обратите внимание на то, что при вызове процедуры CreateTask ей передается строковый параметр, содержащий
имя подгруппы &laquo;Преобразование массивов&raquo;. Это обеспечивает включение новых заданий
в подгруппу, с которой связаны ранее импортированные в нашу группу задания ExamBegin71 и ExamBegin72.
</p>
<p>Размер исходного массива всегда будет четным и не превосходящим 10; последнее условие необходимо для
того, чтобы все исходные данные можно было разместить на одной экранной строке.
<p>Размер исходного массива всегда будет четным и не превосходящим 10; последнее условие необходимо для
того, чтобы все исходные данные можно было разместить на одной экранной строке.
</p>
<p>В обоих заданиях значения элементов исходного массива можно выбирать произвольным образом из некоторого диапазона.
Мы выбрали диапазон от -99 до 99, поскольку в этом случае при отображении чисел с двумя дробными знаками
они будут занимать не более 6 экранных позиций.
<p>В обоих заданиях значения элементов исходного массива можно выбирать произвольным образом из некоторого диапазона.
Мы выбрали диапазон от -99 до 99, поскольку в этом случае при отображении чисел с двумя дробными знаками
они будут занимать не более 6 экранных позиций.
</p>
<p>При записи в файл элементов исходного массива между ними всегда располагается по одному пробелу, поскольку
такой порядок организации исходных данных принят во всех заданиях групп ExamBegin и ExamTaskC. Чтобы обеспечить
при этом отображение вещественных чисел с двумя дробными знаками, используется специальный набор форматирующих
атрибутов: &laquo;<code>:0:2</code>&raquo;. При выводе результатов, согласно формулировке задания,
необходимо отводить для каждого элемента массива по 7 экранных позиций и выводить его с двумя дробными знаками
(последнее условие принято по умолчанию во всех заданиях групп ExamBegin и ExamTaskC, использующих
вещественные данные). Поэтому при выводе применяются другие форматирующие атрибуты: &laquo;<code>:7:2</code>&raquo;.
<p>При записи в файл элементов исходного массива между ними всегда располагается по одному пробелу, поскольку
такой порядок организации исходных данных принят во всех заданиях групп ExamBegin и ExamTaskC. Чтобы обеспечить
при этом отображение вещественных чисел с двумя дробными знаками, используется специальный набор форматирующих
атрибутов: &laquo;<code>:0:2</code>&raquo;. При выводе результатов, согласно формулировке задания,
необходимо отводить для каждого элемента массива по 7 экранных позиций и выводить его с двумя дробными знаками
(последнее условие принято по умолчанию во всех заданиях групп ExamBegin и ExamTaskC, использующих
вещественные данные). Поэтому при выводе применяются другие форматирующие атрибуты: &laquo;<code>:7:2</code>&raquo;.
</p>
<p>Так как алгоритм решения обеих задач не содержит ветвлений, для проверки его правильности
достаточно небольшого числа тестовых запусков. Мы установили это число равным трем, указав его
в качестве параметра процедуры <a href="tmaker_proc1.html#SetTestCount">SetTestCount</a>.
<p>Так как алгоритм решения обеих задач не содержит ветвлений, для проверки его правильности
достаточно небольшого числа тестовых запусков. Мы установили это число равным трем, указав его
в качестве параметра процедуры <a href="tmaker_proc1.html#SetTestCount">SetTestCount</a>.
</p>
<p>Нам осталось включить вызовы процедуры Exam1 (с параметрами, равными 1 и 2)
в основную процедуру группы InitTask, связав эти вызовы с номерами заданий. Следует разместить новые
задания сразу после импортированных заданий ExamBegin71 и ExamBegin72, так как все эти задания
относятся к одной и той же подгруппе &laquo;Преобразование массивов&raquo;. При этом номера
последних 12 заданий увеличатся на 2:
<p>Нам осталось включить вызовы процедуры Exam1 (с параметрами, равными 1 и 2)
в основную процедуру группы InitTask, связав эти вызовы с номерами заданий. Следует разместить новые
задания сразу после импортированных заданий ExamBegin71 и ExamBegin72, так как все эти задания
относятся к одной и той же подгруппе &laquo;Преобразование массивов&raquo;. При этом номера
последних 12 заданий увеличатся на 2:
</p>
<pre>procedure InitTask(num: integer);
begin
@ -423,63 +423,63 @@ begin
end;
end;
</pre>
<p>Необходимо также увеличить на 2 пятый параметр процедуры CreateGroup, определяющий общее количество
заданий в группе (теперь это количество должно быть равно 16).
<p>Необходимо также увеличить на 2 пятый параметр процедуры CreateGroup, определяющий общее количество
заданий в группе (теперь это количество должно быть равно 16).
</p>
<p>
Для просмотра новых заданий в окне задачника надо заменить в параметре процедуры Task
тестирующей программы символ &laquo;#&raquo; на &laquo;?&raquo;: <code>Task('ExamDemo?')</code>.
Для просмотра новых заданий в окне задачника надо заменить в параметре процедуры Task
тестирующей программы символ &laquo;#&raquo; на &laquo;?&raquo;: <code>Task('ExamDemo?')</code>.
</p>
<p>При нажатии клавиши [F9] мы увидим на экране окно задачника в демо-режиме, в котором можно выбрать
и просмотреть все задания, включенные к настоящему моменту в нашу группу. Приведем вид окна для задания ExamDemo4
(напомним, что это задание инициализируется посредством вызова процедуры Exam1 с параметром, равным 2):
<p>При нажатии клавиши [F9] мы увидим на экране окно задачника в демо-режиме, в котором можно выбрать
и просмотреть все задания, включенные к настоящему моменту в нашу группу. Приведем вид окна для задания ExamDemo4
(напомним, что это задание инициализируется посредством вызова процедуры Exam1 с параметром, равным 2):
</p>
<p class="ris"><img border="0" src="images\pt4exam3.png">
</p>
<h2>Добавление заданий повышенной сложности</h2>
<p>Наша группа ExamDemo к настоящему моменту содержит 12 заданий повышенной сложности, импортированных
из группы ExamTaskC. Все эти задания связаны с общей предметной областью; они содержат сведения об
абитуриентах и включают их фамилии, номера школ и годы поступления в вузы. Для того чтобы проиллюстрировать
некоторые особенности, связанные с разработкой подобных заданий, дополним набор уже имеющихся заданий двумя
новыми заданиями из той же предметной области.
<h2>Добавление заданий повышенной сложности</h2>
<p>Наша группа ExamDemo к настоящему моменту содержит 12 заданий повышенной сложности, импортированных
из группы ExamTaskC. Все эти задания связаны с общей предметной областью; они содержат сведения об
абитуриентах и включают их фамилии, номера школ и годы поступления в вузы. Для того чтобы проиллюстрировать
некоторые особенности, связанные с разработкой подобных заданий, дополним набор уже имеющихся заданий двумя
новыми заданиями из той же предметной области.
</p>
<p>Новые задания будут связаны с группировкой абитуриентов по школам:
для каждой школы надо найти связанный с ней минимальный (или максимальный) год
поступления абитуриента. Второе из двух заданий мы усложним, дополнительно потребовав, чтобы
полученные результаты были отсортированы по убыванию максимального года (а для одинаковых годов &#151;
по возрастанию номера школы). Первое задание сделаем более простым: в нем результирующие данные
надо располагать по возрастанию номеров школ.
<p>Новые задания будут связаны с группировкой абитуриентов по школам:
для каждой школы надо найти связанный с ней минимальный (или максимальный) год
поступления абитуриента. Второе из двух заданий мы усложним, дополнительно потребовав, чтобы
полученные результаты были отсортированы по убыванию максимального года (а для одинаковых годов &#151;
по возрастанию номера школы). Первое задание сделаем более простым: в нем результирующие данные
надо располагать по возрастанию номеров школ.
</p>
<p>При генерации наборов исходных данных нам потребуются не только числа (номера школ и годы поступления),
но и строковые данные &#151; фамилии абитуриентов (хотя для выполнения этих заданий они не требуются).
Проще всего определить массив возможных фамилий достаточно большого размера, из которого выбирать
элементы случайным образом. Заметим, что в условии заданий не говорится о том, что все фамилии
в исходном наборе должны быть различными, поэтому совпадения фамилий вполне допустимы (если
в некоторой группе заданий все фамилии должны быть уникальными, то целесообразно дополнять их <i>инициалами</i>,
чтобы обеспечить большее разнообразие; кроме того, для таких заданий
при добавлении к набору исходных данных новой фамилии необходимо проверять,
что среди уже имеющихся элементов набора отсутствует данная фамилия с теми же инициалами).
<p>При генерации наборов исходных данных нам потребуются не только числа (номера школ и годы поступления),
но и строковые данные &#151; фамилии абитуриентов (хотя для выполнения этих заданий они не требуются).
Проще всего определить массив возможных фамилий достаточно большого размера, из которого выбирать
элементы случайным образом. Заметим, что в условии заданий не говорится о том, что все фамилии
в исходном наборе должны быть различными, поэтому совпадения фамилий вполне допустимы (если
в некоторой группе заданий все фамилии должны быть уникальными, то целесообразно дополнять их <i>инициалами</i>,
чтобы обеспечить большее разнообразие; кроме того, для таких заданий
при добавлении к набору исходных данных новой фамилии необходимо проверять,
что среди уже имеющихся элементов набора отсутствует данная фамилия с теми же инициалами).
</p>
<p>Добавим к нашей библиотеке вспомогательный массив фамилий из 40 элементов
(обратите внимание на то, что по правилам языка PascalABC.NET между описанием массива
и списком инициализирующих значений указывается знак присваивания):
<p>Добавим к нашей библиотеке вспомогательный массив фамилий из 40 элементов
(обратите внимание на то, что по правилам языка PascalABC.NET между описанием массива
и списком инициализирующих значений указывается знак присваивания):
</p>
<pre>const
famcount = 40;
var
fam: array[1..famcount] of string :=
('Иванов', 'Петров', 'Сидоров', 'Кузнецов', 'Филиппов',
'Сергеев', 'Александров', 'Петухов', 'Пономарев', 'Яшин',
'Греков', 'Иванова', 'Кузнецова', 'Алексеева', 'Зайцев',
'Волкова', 'Фролов', 'Юрьев', 'Бондарев', 'Семенов',
'Семенова', 'Федченко', 'Марченко', 'Борисова', 'Петровский',
'Беляева', 'Белкин', 'Лысенко', 'Сорокина', 'Пастухов',
'Юрьева', 'Кондратьев', 'Тимофеев', 'Степанова', 'Якимов',
'Юсов', 'Степанов', 'Руденко', 'Демидов', 'Леонидов');
('Иванов', 'Петров', 'Сидоров', 'Кузнецов', 'Филиппов',
'Сергеев', 'Александров', 'Петухов', 'Пономарев', 'Яшин',
'Греков', 'Иванова', 'Кузнецова', 'Алексеева', 'Зайцев',
'Волкова', 'Фролов', 'Юрьев', 'Бондарев', 'Семенов',
'Семенова', 'Федченко', 'Марченко', 'Борисова', 'Петровский',
'Беляева', 'Белкин', 'Лысенко', 'Сорокина', 'Пастухов',
'Юрьева', 'Кондратьев', 'Тимофеев', 'Степанова', 'Якимов',
'Юсов', 'Степанов', 'Руденко', 'Демидов', 'Леонидов');
</pre>
<p>Оба новых задания, как и два предыдущих,
мы реализуем в виде одной процедуры с параметром m, принимающим значения 1 или 2:
<p>Оба новых задания, как и два предыдущих,
мы реализуем в виде одной процедуры с параметром m, принимающим значения 1 или 2:
</p>
<pre>procedure Exam2(m: integer);
var
@ -487,33 +487,33 @@ var
a: array[1..100] of integer;
nums: array[1..10] of integer;
begin
CreateTask('Обработка сложных наборов данных');
CreateTask('Обработка сложных наборов данных');
case m of
1:
begin
TaskText('На вход подаются сведения об абитуриентах. В первой строке указывается',0,1);
TaskText('количество абитуриентов {N}, каждая из последующих {N} строк имеет формат',0,2);
TaskText('\(\M&lt;Год поступления&gt; &lt;Фамилия&gt; &lt;Номер школы&gt;\m\)',0,3);
TaskText('Номер школы содержит не более двух цифр, годы лежат в диапазоне от 1990',0,4);
TaskText('до 2010. Для каждого номера школы, присутствующего в исходных данных,',0,5);
TaskText('определить связанный с ним минимальный год поступления (вначале указывать',0,0);
TaskText('номер школы, затем минимальный год). Сведения о каждой школе выводить',0,0);
TaskText('на новой строке и упорядочивать по возрастанию номера школы.',0,0);
TaskText('На вход подаются сведения об абитуриентах. В первой строке указывается',0,1);
TaskText('количество абитуриентов {N}, каждая из последующих {N} строк имеет формат',0,2);
TaskText('\(\M&lt;Год поступления&gt; &lt;Фамилия&gt; &lt;Номер школы&gt;\m\)',0,3);
TaskText('Номер школы содержит не более двух цифр, годы лежат в диапазоне от 1990',0,4);
TaskText('до 2010. Для каждого номера школы, присутствующего в исходных данных,',0,5);
TaskText('определить связанный с ним минимальный год поступления (вначале указывать',0,0);
TaskText('номер школы, затем минимальный год). Сведения о каждой школе выводить',0,0);
TaskText('на новой строке и упорядочивать по возрастанию номера школы.',0,0);
k := 1;
for i := 1 to 100 do
a[i] := 2100;
end;
2:
begin
TaskText('На вход подаются сведения об абитуриентах. В первой строке указывается',0,1);
TaskText('количество абитуриентов {N}, каждая из последующих {N} строк имеет формат',0,2);
TaskText('\(\M&lt;Номер школы&gt; &lt;Фамилия&gt; &lt;Год поступления&gt;\m\)',0,3);
TaskText('Номер школы содержит не более двух цифр, годы лежат в диапазоне от 1990',0,4);
TaskText('до 2010. Для каждого номера школы, присутствующего в исходных данных,',0,5);
TaskText('определить связанный с ним максимальный год поступления (вначале указывать',0,0);
TaskText('максимальный год, затем номер школы). Сведения о каждой школе выводить',0,0);
TaskText('на новой строке и упорядочивать по убыванию максимального года,',0,0);
TaskText('а для совпадающих годов \= по возрастанию номера школы.',0,0);
TaskText('На вход подаются сведения об абитуриентах. В первой строке указывается',0,1);
TaskText('количество абитуриентов {N}, каждая из последующих {N} строк имеет формат',0,2);
TaskText('\(\M&lt;Номер школы&gt; &lt;Фамилия&gt; &lt;Год поступления&gt;\m\)',0,3);
TaskText('Номер школы содержит не более двух цифр, годы лежат в диапазоне от 1990',0,4);
TaskText('до 2010. Для каждого номера школы, присутствующего в исходных данных,',0,5);
TaskText('определить связанный с ним максимальный год поступления (вначале указывать',0,0);
TaskText('максимальный год, затем номер школы). Сведения о каждой школе выводить',0,0);
TaskText('на новой строке и упорядочивать по убыванию максимального года,',0,0);
TaskText('а для совпадающих годов \= по возрастанию номера школы.',0,0);
k := -1;
for i := 1 to 100 do
a[i] := 0;
@ -572,75 +572,75 @@ begin
SetTestCount(5);
end;
</pre>
<p>Обсудим детали реализации этих заданий. Начальная часть их формулировки
посвящена описанию предметной области и является стандартной для данной серии заданий. Обратите внимание на то, что
поля исходных записей в заданиях указываются в различном порядке.
Этот прием используется во всех сериях группы ExamTaskC, чтобы обеспечить большее разнообразие входящих в них задач.
<p>Обсудим детали реализации этих заданий. Начальная часть их формулировки
посвящена описанию предметной области и является стандартной для данной серии заданий. Обратите внимание на то, что
поля исходных записей в заданиях указываются в различном порядке.
Этот прием используется во всех сериях группы ExamTaskC, чтобы обеспечить большее разнообразие входящих в них задач.
</p>
<p>При определении завершающей части формулировки заданий последний параметр процедур TaskText полагается равным 0.
Это означает, что в режиме окна с фиксированной компоновкой данные строки
при первоначальном отображении задания не видны на экране, однако их можно просмотреть, используя
<i>прокрутку</i> раздела с формулировкой задания. В режиме с динамической компоновкой полный текст формулировки задания
сразу отображается на экране.
<p>При определении завершающей части формулировки заданий последний параметр процедур TaskText полагается равным 0.
Это означает, что в режиме окна с фиксированной компоновкой данные строки
при первоначальном отображении задания не видны на экране, однако их можно просмотреть, используя
<i>прокрутку</i> раздела с формулировкой задания. В режиме с динамической компоновкой полный текст формулировки задания
сразу отображается на экране.
</p>
<p>В процедуре используются два массива: массив a предназначен для хранения контрольных (правильных) результатов,
а массив nums является вспомогательным (его назначение описывается далее).
Для хранения исходных данных массив не предусматривается, поскольку
после генерации полей очередной записи они будут немедленно записываться
в исходный файл и обрабатываться.
<p>В процедуре используются два массива: массив a предназначен для хранения контрольных (правильных) результатов,
а массив nums является вспомогательным (его назначение описывается далее).
Для хранения исходных данных массив не предусматривается, поскольку
после генерации полей очередной записи они будут немедленно записываться
в исходный файл и обрабатываться.
</p>
<p>Количество записей в исходном наборе данных записывается в переменную n.
Наборы, содержащие небольшое число записей, удобны при отладке программы (благодаря своей &laquo;обозримости&raquo;),
в то время как большие наборы позволяют проверить программу в &laquo;реальной&raquo; ситуации и тем самым
окончательно убедиться в правильности алгоритма.
Используя функцию <a href="tmaker_proc1.html#CurrentTest">CurrentTest</a>, добавленную в версию 4.11 конструктора
PT4TaskMaker, мы обеспечили дополнительную &laquo;настройку&raquo; процесса генерации исходных данных:
при первом тестовом запуске
программы с решением задачи ей всегда предлагается набор из небольшого количества записей (что упрощает поиск
и исправление ошибок), а при втором тестовом запуске &#151; большой набор записей (что позволяет проверить предложенный
алгоритм &laquo;на прочность&raquo;). При последующих тестовых запусках (а также при демонстрационном
и ознакомительном запуске программы) значение n с равной вероятностью
выбирается либо из диапазона 10..20, либо из диапазона 50..100.
<p>Количество записей в исходном наборе данных записывается в переменную n.
Наборы, содержащие небольшое число записей, удобны при отладке программы (благодаря своей &laquo;обозримости&raquo;),
в то время как большие наборы позволяют проверить программу в &laquo;реальной&raquo; ситуации и тем самым
окончательно убедиться в правильности алгоритма.
Используя функцию <a href="tmaker_proc1.html#CurrentTest">CurrentTest</a>, добавленную в версию 4.11 конструктора
PT4TaskMaker, мы обеспечили дополнительную &laquo;настройку&raquo; процесса генерации исходных данных:
при первом тестовом запуске
программы с решением задачи ей всегда предлагается набор из небольшого количества записей (что упрощает поиск
и исправление ошибок), а при втором тестовом запуске &#151; большой набор записей (что позволяет проверить предложенный
алгоритм &laquo;на прочность&raquo;). При последующих тестовых запусках (а также при демонстрационном
и ознакомительном запуске программы) значение n с равной вероятностью
выбирается либо из диапазона 10..20, либо из диапазона 50..100.
</p>
<p>В случае генерации исходных данных для указанных заданий при небольших значениях n (10&#150;20)
возникает дополнительная проблема:
если выбирать случайным образом номера школ из всего допустимого диапазона 1&#150;100,
то с большой вероятностью каждый номер школы появится в наборе исходных данных
всего по одному разу, что не позволит проверить правильность реализованного в программе алгоритма нахождения
минимального/максимального значения. Чтобы решить эту проблему, используется вспомогательный массив nums из 10
элементов, в который заносятся 10 случайно выбранных номеров школ,
после чего номера школ для исходного набора записей выбираются уже из этого набора номеров.
<p>В случае генерации исходных данных для указанных заданий при небольших значениях n (10&#150;20)
возникает дополнительная проблема:
если выбирать случайным образом номера школ из всего допустимого диапазона 1&#150;100,
то с большой вероятностью каждый номер школы появится в наборе исходных данных
всего по одному разу, что не позволит проверить правильность реализованного в программе алгоритма нахождения
минимального/максимального значения. Чтобы решить эту проблему, используется вспомогательный массив nums из 10
элементов, в который заносятся 10 случайно выбранных номеров школ,
после чего номера школ для исходного набора записей выбираются уже из этого набора номеров.
</p>
<p>В любом задании, связанном с нахождением набора записей, обычно требуется <i>отсортировать</i> полученный набор.
Задание должно быть сформулировано таким образом, чтобы обеспечить
<i>однозначный</i> порядок вывода полученных данных. В частности, если поле, по которому выполняется сортировка
(<i>главный ключ сортировки</i>),
может содержать одинаковые значения, то обязательно следует указать дополнительное поле
(<i>подчиненный ключ сортировки</i>),
по которому надо сортировать записи с одинаковым главным ключом.
При выводе отсортированных данных вначале надо располагать главный ключ,
после него &#151; подчиненные ключи (если они имеются), затем &#151; остальные поля
(такой порядок вывода принят во всех заданиях группы ExamTaskC).
<p>В любом задании, связанном с нахождением набора записей, обычно требуется <i>отсортировать</i> полученный набор.
Задание должно быть сформулировано таким образом, чтобы обеспечить
<i>однозначный</i> порядок вывода полученных данных. В частности, если поле, по которому выполняется сортировка
(<i>главный ключ сортировки</i>),
может содержать одинаковые значения, то обязательно следует указать дополнительное поле
(<i>подчиненный ключ сортировки</i>),
по которому надо сортировать записи с одинаковым главным ключом.
При выводе отсортированных данных вначале надо располагать главный ключ,
после него &#151; подчиненные ключи (если они имеются), затем &#151; остальные поля
(такой порядок вывода принят во всех заданиях группы ExamTaskC).
</p>
<p>Для упорядочивания результатов во втором задании вместо сортировки массива a по убыванию
используется другой алгоритм, связанный с последовательным нахождением максимального элемента, выводом
этого элемента и его &laquo;порчей&raquo; (заменой его значения на 0). Обычная сортировка массива
в данном случае не позволит получить требуемый набор данных, так как при перемене местами значений
элементов в массиве a будет потеряна связь с номером школы (который определяется по индексу элемента).
Заметим, что возможен и вариант получения упорядоченного набора данных с помощью сортировки,
однако для этого надо использовать массив <i>записей</i>, полями которых являются максимальный год и номер школы.
<p>Для упорядочивания результатов во втором задании вместо сортировки массива a по убыванию
используется другой алгоритм, связанный с последовательным нахождением максимального элемента, выводом
этого элемента и его &laquo;порчей&raquo; (заменой его значения на 0). Обычная сортировка массива
в данном случае не позволит получить требуемый набор данных, так как при перемене местами значений
элементов в массиве a будет потеряна связь с номером школы (который определяется по индексу элемента).
Заметим, что возможен и вариант получения упорядоченного набора данных с помощью сортировки,
однако для этого надо использовать массив <i>записей</i>, полями которых являются максимальный год и номер школы.
</p>
<p>Во втором задании результаты должны упорядочиваться по <i>набору ключей</i>: первый
(главный) ключ &#151; максимальный год (сортируется по убыванию), второй (подчиненный) ключ &#151; номер школы
(сортируется по возрастанию).
Использованный нами способ упорядочивания обеспечивает <i>автоматическую</i> сортировку
по подчиненному ключу, так как при поиске очередного максимума массив a перебирается
по <i>возрастанию</i> индексов, и поэтому в результате находится номер <i>первого</i> максимального элемента.
<p>Во втором задании результаты должны упорядочиваться по <i>набору ключей</i>: первый
(главный) ключ &#151; максимальный год (сортируется по убыванию), второй (подчиненный) ключ &#151; номер школы
(сортируется по возрастанию).
Использованный нами способ упорядочивания обеспечивает <i>автоматическую</i> сортировку
по подчиненному ключу, так как при поиске очередного максимума массив a перебирается
по <i>возрастанию</i> индексов, и поэтому в результате находится номер <i>первого</i> максимального элемента.
</p>
<p>Прочие фрагменты процедуры Exam2 дополнительных комментариев не требуют.
<p>Прочие фрагменты процедуры Exam2 дополнительных комментариев не требуют.
</p>
<p>Вызов процедуры Exam2 надо добавить в конец оператора case процедуры InitTask, связав его
с номерами 17 и 18:
<p>Вызов процедуры Exam2 надо добавить в конец оператора case процедуры InitTask, связав его
с номерами 17 и 18:
</p>
<pre>procedure InitTask(num: integer);
@ -653,29 +653,29 @@ begin
end;
end;
</pre>
<p>Кроме того, необходимо опять откорректировать параметр процедуры CreateGroup, определяющий количество
заданий, положив его равным 18.
<p>Кроме того, необходимо опять откорректировать параметр процедуры CreateGroup, определяющий количество
заданий, положив его равным 18.
</p>
<p>При нажатии клавиши [F9] на экране появится окно задачника с последним заданием данной группы
(на рисунке приведен вид окна после прокрутки раздела с формулировкой задания):
<p>При нажатии клавиши [F9] на экране появится окно задачника с последним заданием данной группы
(на рисунке приведен вид окна после прокрутки раздела с формулировкой задания):
</p>
<p class="ris"><img border="0" src="images\pt4exam4.png">
</p>
<p>Если теперь опять заменить символ &laquo;?&raquo; на символ &laquo;# &raquo;
в параметре процедуры Task тестирующей программы,
то при нажатии [F9] мы увидим html-страницу с описанием группы, которое теперь содержит
не только импортированные, но и реализованные нами задания:
<p>Если теперь опять заменить символ &laquo;?&raquo; на символ &laquo;# &raquo;
в параметре процедуры Task тестирующей программы,
то при нажатии [F9] мы увидим html-страницу с описанием группы, которое теперь содержит
не только импортированные, но и реализованные нами задания:
</p>
<p class="ris"><img border="1" src="images\pt4exam5.png">
</p>
<p>Поскольку при создании новых заданий мы указали в качестве параметра процедур CreateTask
названия подгрупп (и разместили новые задания после заданий из данных подгрупп),
новые задания отображаются в составе этих подгрупп: ExamDemo3 и ExamDemo4 &#151; в подгруппе
&laquo;Преобразование массивов&raquo;, а ExamDemo17 и ExamDemo18 &#151; в подгруппе
&laquo;Обработка сложных наборов данных&raquo;.
<p>Поскольку при создании новых заданий мы указали в качестве параметра процедур CreateTask
названия подгрупп (и разместили новые задания после заданий из данных подгрупп),
новые задания отображаются в составе этих подгрупп: ExamDemo3 и ExamDemo4 &#151; в подгруппе
&laquo;Преобразование массивов&raquo;, а ExamDemo17 и ExamDemo18 &#151; в подгруппе
&laquo;Обработка сложных наборов данных&raquo;.
</p>

File diff suppressed because it is too large Load diff

View file

@ -10,155 +10,155 @@
</head>
<body>
<H1>Модуль PT4TaskMakerNET: общее описание</H1>
<H1>Модуль PT4TaskMakerNET: общее описание</H1>
<hr>
<H2>Назначение и состав конструктора учебных заданий</H2>
<H2>Назначение и состав конструктора учебных заданий</H2>
<p><i>Конструктор учебных заданий PT4TaskMaker</i> позволяет разрабатывать
новые группы заданий для электронного задачника Programming Taskbook.
<p><i>Конструктор учебных заданий PT4TaskMaker</i> позволяет разрабатывать
новые группы заданий для электронного задачника Programming Taskbook.
</p>
<p>
Начиная с версии 4.11, новые группы заданий, доступные
для всех поддерживаемых задачником сред, можно
разрабатывать не только на языке Pascal, но и на языках C++ и C#, причем
конструктор для языка Pascal можно использовать и в среде PascalABC.NET.
Конструктор для среды PascalABC.NET реализован в виде модуля PT4TaskMakerNET.
Начиная с версии 4.11, новые группы заданий, доступные
для всех поддерживаемых задачником сред, можно
разрабатывать не только на языке Pascal, но и на языках C++ и C#, причем
конструктор для языка Pascal можно использовать и в среде PascalABC.NET.
Конструктор для среды PascalABC.NET реализован в виде модуля PT4TaskMakerNET.
</p>
<p>
Каждая группа учебных заданий оформляется в виде отдельной динамической библиотеки
(dll-файла). Dll-файлы с новыми группами могут находиться либо
в рабочем каталоге учащегося, либо в подкаталоге Lib системного каталога
задачника. Подключение новых групп происходит автоматически при инициализации
задания, поэтому вид проекта-заготовки при работе с новыми группами
не отличается от стандартного вида проекта, ориентированного на
базовые группы заданий. Кроме того, новые группы автоматически
добавляются в список доступных групп в программных модулях PT4Demo и PT4Load.
Созданные в виде dll-файлов новые группы заданий могут использоваться
не только в любых средах программирования, поддерживаемых универсальным вариантом задачника,
но и в среде PascalABC.NET; для этого достаточно разместить dll-файл в
подкаталоге PT4\Lib системного каталога PascalABC.NET или в рабочем каталоге учащегося.
Каждая группа учебных заданий оформляется в виде отдельной динамической библиотеки
(dll-файла). Dll-файлы с новыми группами могут находиться либо
в рабочем каталоге учащегося, либо в подкаталоге Lib системного каталога
задачника. Подключение новых групп происходит автоматически при инициализации
задания, поэтому вид проекта-заготовки при работе с новыми группами
не отличается от стандартного вида проекта, ориентированного на
базовые группы заданий. Кроме того, новые группы автоматически
добавляются в список доступных групп в программных модулях PT4Demo и PT4Load.
Созданные в виде dll-файлов новые группы заданий могут использоваться
не только в любых средах программирования, поддерживаемых универсальным вариантом задачника,
но и в среде PascalABC.NET; для этого достаточно разместить dll-файл в
подкаталоге PT4\Lib системного каталога PascalABC.NET или в рабочем каталоге учащегося.
</p>
<h2>Обзор элементов конструктора учебных заданий</h2>
<p>Конструктор учебных заданий представляет собой набор констант, функций и процедур,
предназначенных для определения каждого из входящих в группу заданий, а также для настройки свойств группы в целом.
<h2>Обзор элементов конструктора учебных заданий</h2>
<p>Конструктор учебных заданий представляет собой набор констант, функций и процедур,
предназначенных для определения каждого из входящих в группу заданий, а также для настройки свойств группы в целом.
</p>
<p>Ниже перечислены элементы, входящие в конструктор PT4TaskMaker:
<p>Ниже перечислены элементы, входящие в конструктор PT4TaskMaker:
</p>
<ul>
<li>процедурный тип <a href="tmaker_proc1.html#TInitTaskProc">TInitTaskProc</a>;
в библиотеке с группой заданий должна быть определена <i>основная процедура группы</i> типа TInitTaskProc,
позволяющая генерировать задание с требуемым номером;
<li>процедура CreateGroup, определяющая <a href="tmaker_proc1.html#CreateGroup">общие характеристики</a> группы заданий;
<li>процедуры и константы, используемые для <a href="tmaker_proc1.html#CreateTask">создания нового задания</a> и добавления в него
формулировки, а также исходных и контрольных данных базовых типов (логического, целочисленного,
вещественного, символьного строкового); обычно каждое задание оформляется в виде отдельной процедуры, которая вызывается
из основной процедуры группы;
<li>процедура <a href="tmaker_proc1.html#UseTask">UseTask</a>, позволяющая импортировать в создаваемую
группу задания из других групп; эта процедура обычно вызывается в основной процедуре группы;
<li>процедуры, обеспечивающие <a href="tmaker_proc1.html#CommentText">добавление комментариев</a>, оформляемых в виде <i>преамбулы</i> к группе и ее подгруппам;
<li>функции и константы, позволяющие определить <a href="tmaker_proc1.html#PT4State">текущее состояние задачника</a>
(используемый язык программирования, текущую <i>локаль</i>
&#151; русскую или английскую &#151;, текущую версию задачника, а также номер текущего тестового испытания программы,
выполняющей задание);
<li>функции, предоставляющие разработчику заданий <a href="tmaker_proc1.html#Sample">образцы слов, предложений и многострочных текстов</a>;
<li>процедуры, позволяющие включать в задание <a href="tmaker_proc2.html#File">файловые данные</a>;
<li>процедуры, позволяющие включать в задание <a href="tmaker_proc2.html#Dynamic">указатели и динамические структуры данных</a>
&#151; линейные списки и деревья;
<li>процедуры для разработки заданий по <a href="tmaker_proc2.html#MPI">параллельному MPI-программированию</a>.
<li>процедурный тип <a href="tmaker_proc1.html#TInitTaskProc">TInitTaskProc</a>;
в библиотеке с группой заданий должна быть определена <i>основная процедура группы</i> типа TInitTaskProc,
позволяющая генерировать задание с требуемым номером;
<li>процедура CreateGroup, определяющая <a href="tmaker_proc1.html#CreateGroup">общие характеристики</a> группы заданий;
<li>процедуры и константы, используемые для <a href="tmaker_proc1.html#CreateTask">создания нового задания</a> и добавления в него
формулировки, а также исходных и контрольных данных базовых типов (логического, целочисленного,
вещественного, символьного строкового); обычно каждое задание оформляется в виде отдельной процедуры, которая вызывается
из основной процедуры группы;
<li>процедура <a href="tmaker_proc1.html#UseTask">UseTask</a>, позволяющая импортировать в создаваемую
группу задания из других групп; эта процедура обычно вызывается в основной процедуре группы;
<li>процедуры, обеспечивающие <a href="tmaker_proc1.html#CommentText">добавление комментариев</a>, оформляемых в виде <i>преамбулы</i> к группе и ее подгруппам;
<li>функции и константы, позволяющие определить <a href="tmaker_proc1.html#PT4State">текущее состояние задачника</a>
(используемый язык программирования, текущую <i>локаль</i>
&#151; русскую или английскую &#151;, текущую версию задачника, а также номер текущего тестового испытания программы,
выполняющей задание);
<li>функции, предоставляющие разработчику заданий <a href="tmaker_proc1.html#Sample">образцы слов, предложений и многострочных текстов</a>;
<li>процедуры, позволяющие включать в задание <a href="tmaker_proc2.html#File">файловые данные</a>;
<li>процедуры, позволяющие включать в задание <a href="tmaker_proc2.html#Dynamic">указатели и динамические структуры данных</a>
&#151; линейные списки и деревья;
<li>процедуры для разработки заданий по <a href="tmaker_proc2.html#MPI">параллельному MPI-программированию</a>.
</ul>
<h2><a name="libr"></a>Библиотечные и сводные группы</h2>
<h2><a name="libr"></a>Библиотечные и сводные группы</h2>
<p>При разработке новых заданий целесообразно объединять их в группы с именами, содержащими, кроме названия темы, дополнительные
сведения, например, версию созданной группы и данные об авторе. Однако допустимые имена групп могут содержать
не более 9 символов, что является недостаточным для указания дополнительных сведений.
С другой стороны, группы, содержащие только новые задания (<i>библиотечные группы</i>), вряд ли будут использоваться
непосредственно в учебном процессе; более целесообразной будет компоновка этих новых заданий с заданиями из соответствующей базовой группы
задачника (и, возможно, с заданиями из других библиотечных групп).</p>
<p>При разработке новых заданий целесообразно объединять их в группы с именами, содержащими, кроме названия темы, дополнительные
сведения, например, версию созданной группы и данные об авторе. Однако допустимые имена групп могут содержать
не более 9 символов, что является недостаточным для указания дополнительных сведений.
С другой стороны, группы, содержащие только новые задания (<i>библиотечные группы</i>), вряд ли будут использоваться
непосредственно в учебном процессе; более целесообразной будет компоновка этих новых заданий с заданиями из соответствующей базовой группы
задачника (и, возможно, с заданиями из других библиотечных групп).</p>
<p>Поэтому при разработке группы, содержащей исключительно новые задания (<i>библиотечной группы</i>, или <i>библиотеки заданий</i>)
разрешено указывать имя длины более 9 символов (но не более 25).
<p>Поэтому при разработке группы, содержащей исключительно новые задания (<i>библиотечной группы</i>, или <i>библиотеки заданий</i>)
разрешено указывать имя длины более 9 символов (но не более 25).
</p>
<p>Библиотечные группы не предназначены для непосредственного использования в учебном процессе. Задания из этих групп
можно запускать с помощью процедуры Task,
однако они будут отображаться только в <i>демонстрационном режиме</i> (точнее, в режиме &laquo;просмотра библиотеки заданий&raquo;,
о чем будет свидетельствовать соответствующий текст, указываемый в окне задачника вместо сведений об учащемся).
Библиотечные группы не включаются в список групп, отображаемый в модуле PT4Load, однако доступны
для просмотра с помощью модуля PT4Demo (в этом модуле библиотечные группы указываются в конце
списка групп).
<p>Библиотечные группы не предназначены для непосредственного использования в учебном процессе. Задания из этих групп
можно запускать с помощью процедуры Task,
однако они будут отображаться только в <i>демонстрационном режиме</i> (точнее, в режиме &laquo;просмотра библиотеки заданий&raquo;,
о чем будет свидетельствовать соответствующий текст, указываемый в окне задачника вместо сведений об учащемся).
Библиотечные группы не включаются в список групп, отображаемый в модуле PT4Load, однако доступны
для просмотра с помощью модуля PT4Demo (в этом модуле библиотечные группы указываются в конце
списка групп).
</p>
<p>Для применения на занятиях удобно использовать <i>сводные группы</i>, не содержащие реализации новых заданий,
а лишь импортирующие наборы заданий из базовых и дополнительных библиотечных групп и компонующие их в порядке, который требуется преподавателю.
При импортировании задания из другой группы у него изменяется название и ключ
(которые берутся из характеристик сводной группы), однако сохраняются такие характеристики импортируемой группы, как
<a href="tmaker_proc1.html#CommentText">заголовки подгрупп</a> и сведения об авторе.
Имена сводных групп должны содержать не более 9 символов.
<p>Для применения на занятиях удобно использовать <i>сводные группы</i>, не содержащие реализации новых заданий,
а лишь импортирующие наборы заданий из базовых и дополнительных библиотечных групп и компонующие их в порядке, который требуется преподавателю.
При импортировании задания из другой группы у него изменяется название и ключ
(которые берутся из характеристик сводной группы), однако сохраняются такие характеристики импортируемой группы, как
<a href="tmaker_proc1.html#CommentText">заголовки подгрупп</a> и сведения об авторе.
Имена сводных групп должны содержать не более 9 символов.
</p>
<h2><a name="structure"></a>Структура проекта с описанием группы заданий</h2>
<h2><a name="structure"></a>Структура проекта с описанием группы заданий</h2>
<p>В данном разделе описываются правила, которым должен удовлетворять проект (dll-библиотека),
содержащий описание новой группы заданий (см. также раздел &laquo;<a href="tmaker_samples.html">Примеры</a>&raquo;).
<p>В данном разделе описываются правила, которым должен удовлетворять проект (dll-библиотека),
содержащий описание новой группы заданий (см. также раздел &laquo;<a href="tmaker_samples.html">Примеры</a>&raquo;).
</p>
<p>Каждый проект, реализуемый в виде dll-библиотеки, должен содержать определение <i>единственной</i> группы заданий.
Имя библиотеки с группой заданий должно иметь вид <code>PT4</code>&lt;<i>имя группы</i>&gt;&lt;<i>маркер локали</i>&gt;,
где &lt;<i>маркер локали</i>&gt; является либо пустой строкой, либо имеет вид <code>_ru</code> или <code>_en</code>.
Например, группа TMDemoPas может быть реализована в виде библиотек PT4TMDemoPas.dll, PT4TMDemoPas_ru.dll
и PT4TMDemoPas_en.dll. Библиотеки с явно указанным маркером локали используются только в
варианте задачника, соответствующем данной локали (ru &#151; в русском варианте задачника,
en &#151; в английском). Библиотеки, в которых не указан маркер локали, используются в любом
варианте задачника (если они не перекрываются библиотекой с явно указанной локалью).
Порядок поиска библиотек для требуемой группы следующий: вначале просматривается <i>рабочий каталог учащегося</i>
и в нем ищется библиотека с данным именем и явно указанной локалью; если она не найдена,
то ищется библиотека с данным именем без маркера локали; если она не найдена, то
поиск библиотек (в этом же порядке) выполняется в <i>каталоге Lib системного каталога задачника</i>.
<p>Каждый проект, реализуемый в виде dll-библиотеки, должен содержать определение <i>единственной</i> группы заданий.
Имя библиотеки с группой заданий должно иметь вид <code>PT4</code>&lt;<i>имя группы</i>&gt;&lt;<i>маркер локали</i>&gt;,
где &lt;<i>маркер локали</i>&gt; является либо пустой строкой, либо имеет вид <code>_ru</code> или <code>_en</code>.
Например, группа TMDemoPas может быть реализована в виде библиотек PT4TMDemoPas.dll, PT4TMDemoPas_ru.dll
и PT4TMDemoPas_en.dll. Библиотеки с явно указанным маркером локали используются только в
варианте задачника, соответствующем данной локали (ru &#151; в русском варианте задачника,
en &#151; в английском). Библиотеки, в которых не указан маркер локали, используются в любом
варианте задачника (если они не перекрываются библиотекой с явно указанной локалью).
Порядок поиска библиотек для требуемой группы следующий: вначале просматривается <i>рабочий каталог учащегося</i>
и в нем ищется библиотека с данным именем и явно указанной локалью; если она не найдена,
то ищется библиотека с данным именем без маркера локали; если она не найдена, то
поиск библиотек (в этом же порядке) выполняется в <i>каталоге Lib системного каталога задачника</i>.
</p>
<p>Проект с описанием новой группы должен иметь определенную структуру.
Приведем описание структуры проекта, который реализуется
на языке Pascal в среде PascalABC.NET:
<p>Проект с описанием новой группы должен иметь определенную структуру.
Приведем описание структуры проекта, который реализуется
на языке Pascal в среде PascalABC.NET:
</p>
<pre>library PT4MakerDemo;
uses PT4TaskMakerNET;
// процедуры, реализующие конкретные задания
// процедуры, реализующие конкретные задания
...
procedure InitTask(num: integer);
begin
// в данной процедуре выполняются вызовы вспомогательных процедур,
// реализующих все задания группы; номер задания определяется
// параметром num; для определения процедуры, соответствующей
// требуемому номеру, обычно используется оператор case
// в данной процедуре выполняются вызовы вспомогательных процедур,
// реализующих все задания группы; номер задания определяется
// параметром num; для определения процедуры, соответствующей
// требуемому номеру, обычно используется оператор case
...
end;
procedure inittaskgroup;
begin
// вспомогательная процедура, в которой выполняется вызов стартовой
// процедуры CreateGroup и могут вызываться процедуры, связанные
// с добавлением комментариев (преамбул) для группы и ее подгрупп.
// Все буквы в ее имени должны быть строчными
// вспомогательная процедура, в которой выполняется вызов стартовой
// процедуры CreateGroup и могут вызываться процедуры, связанные
// с добавлением комментариев (преамбул) для группы и ее подгрупп.
// Все буквы в ее имени должны быть строчными
CreateGroup('TMDemoAbc', 'Примеры различных задач (конструктор для языка PascalABC.NET)',
'М. Э. Абрамян, 2013', 'qwqfsdf13dfttd', 8, InitTask);
CreateGroup('TMDemoAbc', 'Примеры различных задач (конструктор для языка PascalABC.NET)',
'М. Э. Абрамян, 2013', 'qwqfsdf13dfttd', 8, InitTask);
...
end;
procedure activate(S: string);
begin
// вспомогательная процедура, используемая при подключении библиотеки
// к задачнику. Все буквы в ее имени должны быть строчными
// вспомогательная процедура, используемая при подключении библиотеки
// к задачнику. Все буквы в ее имени должны быть строчными
ActivateNET(S);
end;
@ -167,63 +167,63 @@ begin
end.
</pre>
<p>При определении новой группы заданий можно учитывать <i>текущий язык программирования</i>,
установленный для задачника, и в зависимости от этого языка по-разному инициализировать
некоторые задания группы. Эта возможность является особенно полезной при реализации
заданий, связанных с обработкой динамических структур данных, поскольку в языках Visual Basic и 1C
подобные задания должны быть недоступны, а в языках Pascal и C++ они должны оформляться по-другому, нежели в
языках платформы .NET, Python и Java. См. также <a href="tmaker_samples.html#dynamic">пункт, посвященный динамическим структурам данных</a>, в разделе &laquo;Примеры&raquo;.
<p>При определении новой группы заданий можно учитывать <i>текущий язык программирования</i>,
установленный для задачника, и в зависимости от этого языка по-разному инициализировать
некоторые задания группы. Эта возможность является особенно полезной при реализации
заданий, связанных с обработкой динамических структур данных, поскольку в языках Visual Basic и 1C
подобные задания должны быть недоступны, а в языках Pascal и C++ они должны оформляться по-другому, нежели в
языках платформы .NET, Python и Java. См. также <a href="tmaker_samples.html#dynamic">пункт, посвященный динамическим структурам данных</a>, в разделе &laquo;Примеры&raquo;.
</p>
<p>Разрабатываемые группы заданий желательно снабжать <i>дополнительными комментариями</i>. Эти комментарии не отображаются
в окне задачника, однако включаются в html-описание группы в виде <i>преамбулы группы</i> (html-описание
группы можно создать, либо вызвав в программе
процедуру Task с параметром вида '&lt;<i>имя группы</i>&gt;#', например, <code>'TMDemoAbc#'</code>, либо воспользовавшись
кнопкой <img src="images\demo_3.png"> в окне среды PascalABC.NET.
Кроме того, большие группы заданий целесообразно разделять на
несколько подгрупп, в каждую из которых также можно добавлять комментарии (<i>преамбулы подгрупп</i>). В преамбулах, как
и в формулировках заданий, можно использовать специальные <a href="tmaker_format.html">управляющие последовательности</a>,
которые позволяют отформатировать текст требуемым образом
(в частности, обеспечивают выделение переменных, позволяют
использовать в тексте верхние и нижние индексы, специальные символы и т.&nbsp;д.). Форматирование
используется и при отображении формулировки задания в окне задачника, и при генерации
html-страницы с описанием группы заданий.
См. также <a href="tmaker_samples.html#comments">пункт,
посвященный добавлению комментариев</a>, в разделе &laquo;Примеры&raquo;.
<p>Разрабатываемые группы заданий желательно снабжать <i>дополнительными комментариями</i>. Эти комментарии не отображаются
в окне задачника, однако включаются в html-описание группы в виде <i>преамбулы группы</i> (html-описание
группы можно создать, либо вызвав в программе
процедуру Task с параметром вида '&lt;<i>имя группы</i>&gt;#', например, <code>'TMDemoAbc#'</code>, либо воспользовавшись
кнопкой <img src="images\demo_3.png"> в окне среды PascalABC.NET.
Кроме того, большие группы заданий целесообразно разделять на
несколько подгрупп, в каждую из которых также можно добавлять комментарии (<i>преамбулы подгрупп</i>). В преамбулах, как
и в формулировках заданий, можно использовать специальные <a href="tmaker_format.html">управляющие последовательности</a>,
которые позволяют отформатировать текст требуемым образом
(в частности, обеспечивают выделение переменных, позволяют
использовать в тексте верхние и нижние индексы, специальные символы и т.&nbsp;д.). Форматирование
используется и при отображении формулировки задания в окне задачника, и при генерации
html-страницы с описанием группы заданий.
См. также <a href="tmaker_samples.html#comments">пункт,
посвященный добавлению комментариев</a>, в разделе &laquo;Примеры&raquo;.
</p>
<h2><a name="debug"></a>Настройка проектов для языка PascalABC.NET и особенности их отладки</h2>
<p>Для разработки новой группы заданий в среде PascalABC.NET
достаточно подготовить pas-файл с именем, совпадающим с именем
создаваемой библиотеки, и структурой, описанной в
пункте <a href="#structure">&laquo;Структура проекта с описанием группы заданий&raquo;</a>.
Для данного файла должен быть доступен модуль PT4TaskMakerNET; он может размещаться
в этом же каталоге или в подкаталоге Lib системного каталога среды PascalABC.NET.
<h2><a name="debug"></a>Настройка проектов для языка PascalABC.NET и особенности их отладки</h2>
<p>Для разработки новой группы заданий в среде PascalABC.NET
достаточно подготовить pas-файл с именем, совпадающим с именем
создаваемой библиотеки, и структурой, описанной в
пункте <a href="#structure">&laquo;Структура проекта с описанием группы заданий&raquo;</a>.
Для данного файла должен быть доступен модуль PT4TaskMakerNET; он может размещаться
в этом же каталоге или в подкаталоге Lib системного каталога среды PascalABC.NET.
</p>
<p>При нажатии клавиши [F9] будет создана динамическая библиотека с новой группой заданий.
<p>При нажатии клавиши [F9] будет создана динамическая библиотека с новой группой заданий.
</p>
<p>Поскольку в среде PascalABC.NET
не предусмотрены средства для определения главного приложения при разработке библиотек,
для тестирования новой группы заданий необходимо использовать еще одно приложение, заготовку
для которого можно создать с помощью программного модуля PT4Load
уже после первой успешной компиляции динамической библиотеки. Впрочем, заготовка является
настолько простой, что ее можно создать и непосредственно. Например, для тестирования
группы с именем TMDemoAbc достаточно воспользоваться следующей программой:
<p>Поскольку в среде PascalABC.NET
не предусмотрены средства для определения главного приложения при разработке библиотек,
для тестирования новой группы заданий необходимо использовать еще одно приложение, заготовку
для которого можно создать с помощью программного модуля PT4Load
уже после первой успешной компиляции динамической библиотеки. Впрочем, заготовка является
настолько простой, что ее можно создать и непосредственно. Например, для тестирования
группы с именем TMDemoAbc достаточно воспользоваться следующей программой:
</p>
<pre>uses PT4;
begin
Task('TMDemoAbc1?');
end.
</pre>
<p>При запуске этой программы на экран будет выведено окно задачника для группы
TMDemoAbc в демонстрационном режиме, причем в качестве текущего будет выбрано
первое задание данной группы (демонстрационный режим устанавливается благодаря
символу &laquo;?&raquo;, указанному после имени задания). Для отображения в окне задачника
сразу после запуска программы другого существующего задания этой группы достаточно
указать его номер в параметре процедуры Task. Можно также удалить номер, указав
символ &laquo;?&raquo; сразу после имени группы заданий: <code>Task('TMDemoAbc?')</code>.
В этом случае при запуске программы будет отображаться <i>последнее</i> задание, входящее в группу.
<p>При запуске этой программы на экран будет выведено окно задачника для группы
TMDemoAbc в демонстрационном режиме, причем в качестве текущего будет выбрано
первое задание данной группы (демонстрационный режим устанавливается благодаря
символу &laquo;?&raquo;, указанному после имени задания). Для отображения в окне задачника
сразу после запуска программы другого существующего задания этой группы достаточно
указать его номер в параметре процедуры Task. Можно также удалить номер, указав
символ &laquo;?&raquo; сразу после имени группы заданий: <code>Task('TMDemoAbc?')</code>.
В этом случае при запуске программы будет отображаться <i>последнее</i> задание, входящее в группу.
</p>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -10,21 +10,21 @@
</head>
<body>
<H1>Модуль PT4TaskMakerNET: примеры разработки учебных заданий</H1>
<H1>Модуль PT4TaskMakerNET: примеры разработки учебных заданий</H1>
<hr>
<h2>Создание простейшей сводной группы</h2>
<p>Вначале опишем действия по созданию наиболее простого варианта группы заданий &#151; <a href="tmaker_main.html#Libr"><i>сводной группы</i></a>,
в которой не разрабатываются новые задания, а лишь производится перекомпоновка заданий из имеющихся групп.
<h2>Создание простейшей сводной группы</h2>
<p>Вначале опишем действия по созданию наиболее простого варианта группы заданий &#151; <a href="tmaker_main.html#Libr"><i>сводной группы</i></a>,
в которой не разрабатываются новые задания, а лишь производится перекомпоновка заданий из имеющихся групп.
</p>
<p>Создадим группу
заданий MakerDemo, в которую импортируем два первых задания из базовой группы Begin. Следуя правилам об именовании
dll-файлов с группами заданий, дадим нашей библиотеке имя PT4MakerDemo.
<p>Создадим группу
заданий MakerDemo, в которую импортируем два первых задания из базовой группы Begin. Следуя правилам об именовании
dll-файлов с группами заданий, дадим нашей библиотеке имя PT4MakerDemo.
</p>
<p>Файл PT4MakerDemo.pas, содержащий сводную группу заданий, является кратким и имеет стандартную структуру:
<p>Файл PT4MakerDemo.pas, содержащий сводную группу заданий, является кратким и имеет стандартную структуру:
</p>
<pre>library PT4MakerDemo;
@ -40,8 +40,8 @@ end;
procedure inittaskgroup;
begin
CreateGroup('MakerDemo', 'Примеры различных задач',
'М. Э. Абрамян, 2013', 'qwqfsdf13dfttd', 2, InitTask);
CreateGroup('MakerDemo', 'Примеры различных задач',
'М. Э. Абрамян, 2013', 'qwqfsdf13dfttd', 2, InitTask);
end;
procedure activate(S: string);
@ -53,49 +53,49 @@ begin
end.
</pre>
<p>К библиотеке подключается модуль PT4TaskMakerNET, после чего в ней описывается основная процедура группы заданий
<a href="tmaker_proc1.html#TInitTaskProc">InitTask</a>, определяющая задание по его номеру.
Поскольку мы не создавали своих заданий, в данной процедуре
используется только стандартная процедура <a href="tmaker_proc1.html#UseTask">UseTask</a>, позволяющая импортировать задания из имеющихся групп.
В нашем случае импортируются задания с номерами 1 и 2 из группы Begin.
<p>К библиотеке подключается модуль PT4TaskMakerNET, после чего в ней описывается основная процедура группы заданий
<a href="tmaker_proc1.html#TInitTaskProc">InitTask</a>, определяющая задание по его номеру.
Поскольку мы не создавали своих заданий, в данной процедуре
используется только стандартная процедура <a href="tmaker_proc1.html#UseTask">UseTask</a>, позволяющая импортировать задания из имеющихся групп.
В нашем случае импортируются задания с номерами 1 и 2 из группы Begin.
</p>
<p>Затем описывается процедура инициализации данной группы заданий. Она должна иметь стандартное имя inittaskgroup
(<i><b>набранное строчными, т.&nbsp;е. маленькими буквами</b></i>). В этой процедуре
вызывается процедура <a href="tmaker_proc1.html#CreateGroup">CreateGroup</a>, в которой задаются настройки создаваемой группы:
имя (<code>'MakerDemo'</code>), описание (<code>'Примеры различных задач'</code>), сведения об авторе,
строковый ключ, число заданий (<code>2</code>) и основная процедура группы (<code>InitTask</code>).
<p>Затем описывается процедура инициализации данной группы заданий. Она должна иметь стандартное имя inittaskgroup
(<i><b>набранное строчными, т.&nbsp;е. маленькими буквами</b></i>). В этой процедуре
вызывается процедура <a href="tmaker_proc1.html#CreateGroup">CreateGroup</a>, в которой задаются настройки создаваемой группы:
имя (<code>'MakerDemo'</code>), описание (<code>'Примеры различных задач'</code>), сведения об авторе,
строковый ключ, число заданий (<code>2</code>) и основная процедура группы (<code>InitTask</code>).
</p>
<p>После процедуры inittaskgroup описывается вспомогательная процедура activate
(ее имя также должно быть набрано строчными буквами), в которой необходимо вызвать
процедуру ActivateNET, описанную в модуле PT4TaskMakerNET.
<p>После процедуры inittaskgroup описывается вспомогательная процедура activate
(ее имя также должно быть набрано строчными буквами), в которой необходимо вызвать
процедуру ActivateNET, описанную в модуле PT4TaskMakerNET.
</p>
<a name="debug"></a>
<h2>Тестирование созданной группы</h2>
<h2>Тестирование созданной группы</h2>
<p>Для успешной компиляции программы с созданной группой необходимо, чтобы ей был доступен
модуль PT4TaskMakerNET. Этот модуль входит в число стандартных модулей библиотеки системы PascalABC.NET
и размещается в подкаталоге LIB системного каталога PascalABC.NET, поэтому копировать его в рабочий каталог
не требуется.
Однако даже при успешной компиляции программы просмотреть задания группы не удастся, так как
созданную библиотеку (dll-файл) нельзя запускать на выполнение (при успешной компиляции будет выведено
сообщение &laquo;Невозможно запустить динамическую библиотеку&raquo;.
<p>Для успешной компиляции программы с созданной группой необходимо, чтобы ей был доступен
модуль PT4TaskMakerNET. Этот модуль входит в число стандартных модулей библиотеки системы PascalABC.NET
и размещается в подкаталоге LIB системного каталога PascalABC.NET, поэтому копировать его в рабочий каталог
не требуется.
Однако даже при успешной компиляции программы просмотреть задания группы не удастся, так как
созданную библиотеку (dll-файл) нельзя запускать на выполнение (при успешной компиляции будет выведено
сообщение &laquo;Невозможно запустить динамическую библиотеку&raquo;.
</p>
<p>Для тестирования полученной библиотеки
необходимо создать вспомогательную программу, являющуюся заготовкой для выполнения заданий из созданной группы.
Так как после успешной компиляции библиотеки в рабочем каталоге уже содержится файл PT4MakerDemo.dll,
для создания программы-заготовки можно использовать программный модуль PT4Load.
Вызвав его окно на экран (для этого достаточно использовать клавиатурную комбинацию [Shift]+[Ctrl]+[L])
и удалив, при необходимости, имя ранее введенного задания,
мы должны увидеть в списке доступных групп заданий созданную нами группу MakerDemo.
Если имя группы MakerDemo не отображается, значит, задачник не смог успешно загрузить эту группу
из библиотеки PT4MakerDemo.dll. В этом случае необходимо проверить имя созданной библиотеки (в частности,
наличие в нем префикса PT4) и наличие в файле библиотеки процедур inittaskgroup и activate,
определенных по описанным выше правилам.
<p>Для тестирования полученной библиотеки
необходимо создать вспомогательную программу, являющуюся заготовкой для выполнения заданий из созданной группы.
Так как после успешной компиляции библиотеки в рабочем каталоге уже содержится файл PT4MakerDemo.dll,
для создания программы-заготовки можно использовать программный модуль PT4Load.
Вызвав его окно на экран (для этого достаточно использовать клавиатурную комбинацию [Shift]+[Ctrl]+[L])
и удалив, при необходимости, имя ранее введенного задания,
мы должны увидеть в списке доступных групп заданий созданную нами группу MakerDemo.
Если имя группы MakerDemo не отображается, значит, задачник не смог успешно загрузить эту группу
из библиотеки PT4MakerDemo.dll. В этом случае необходимо проверить имя созданной библиотеки (в частности,
наличие в нем префикса PT4) и наличие в файле библиотеки процедур inittaskgroup и activate,
определенных по описанным выше правилам.
</p>
<p>Если имя группы появилось в списке, то надо ввести в поле &laquo;Задание&raquo; имя &laquo;MakerDemo1&raquo;
и нажать клавишу [Enter] (или кнопку &laquo;Загрузка&raquo;); в результате будет создан файл MakerDemo1.pas,
который сразу загрузится в редактор среды PascalABC.NET. Приведем содержимое этого файла:
<p>Если имя группы появилось в списке, то надо ввести в поле &laquo;Задание&raquo; имя &laquo;MakerDemo1&raquo;
и нажать клавишу [Enter] (или кнопку &laquo;Загрузка&raquo;); в результате будет создан файл MakerDemo1.pas,
который сразу загрузится в редактор среды PascalABC.NET. Приведем содержимое этого файла:
</p>
<pre>
uses PT4;
@ -105,116 +105,116 @@ begin
end.
</pre>
<p>Поскольку мы собираемся просматривать задания группы в демо-режиме,
добавим в конец строки с именем
задания символ &laquo;?&raquo;:
<p>Поскольку мы собираемся просматривать задания группы в демо-режиме,
добавим в конец строки с именем
задания символ &laquo;?&raquo;:
</p>
<pre> Task('MakerDemo1?');
</pre>
<p>После компиляции и запуска полученной программы на экране отобразится окно задачника
с указанным заданием данной группы:
<p>После компиляции и запуска полученной программы на экране отобразится окно задачника
с указанным заданием данной группы:
</p>
<p class="ris"><img border="0" src="images\pt4make6.png">
</p>
<p>По умолчанию окно задачника отображается в режиме с динамической компоновкой, который появился
в версии 4.11 и является более наглядным, чем режим с фиксированной компоновкой. Однако
при разработке заданий желательно применять режим с фиксированной компоновкой, поскольку
он позволит выявить недостатки форматирования (в частности, вертикального выравнивания данных),
присущие только этому режиму. Для переключения между режимами отображения данных достаточно нажать клавишу
[F4]. После выполнения этого действия окно задачника изменится следующим образом:
<p>По умолчанию окно задачника отображается в режиме с динамической компоновкой, который появился
в версии 4.11 и является более наглядным, чем режим с фиксированной компоновкой. Однако
при разработке заданий желательно применять режим с фиксированной компоновкой, поскольку
он позволит выявить недостатки форматирования (в частности, вертикального выравнивания данных),
присущие только этому режиму. Для переключения между режимами отображения данных достаточно нажать клавишу
[F4]. После выполнения этого действия окно задачника изменится следующим образом:
</p>
<p class="ris"><img border="0" src="images\pt4make6a.png">
</p>
<p>В окне задачника можно просматривать все имеющиеся задания данной группы
(нажимая клавиши [Enter] и [Backspace], а также генерировать различные варианты исходных данных
и связанных с ними контрольных (т.&nbsp;е. &laquo;правильных&raquo;) результатов. При закрытии окна
программа немедленно завершит работу, и мы вернемся в редактор среды PascalABC.NET.
Заметим, что при последующих запусках программы будет автоматически выбираться тот режим окна
задачника, в котором оно находилось в момент его предшествующего закрытия.
<p>В окне задачника можно просматривать все имеющиеся задания данной группы
(нажимая клавиши [Enter] и [Backspace], а также генерировать различные варианты исходных данных
и связанных с ними контрольных (т.&nbsp;е. &laquo;правильных&raquo;) результатов. При закрытии окна
программа немедленно завершит работу, и мы вернемся в редактор среды PascalABC.NET.
Заметим, что при последующих запусках программы будет автоматически выбираться тот режим окна
задачника, в котором оно находилось в момент его предшествующего закрытия.
</p>
<p>
</p>
<p><b>Примечание</b>. После добавления в группу нового задания было бы желательно, чтобы
при звпуске тестирующей программы на экране сразу отображались данные, связанные с последним
добавленным заданием. Чтобы не приходилось каждый раз изменять номер задания в процедуре Task,
можно удалить этот номер, указав символ &laquo;?&raquo; сразу после имени группы:
<p><b>Примечание</b>. После добавления в группу нового задания было бы желательно, чтобы
при звпуске тестирующей программы на экране сразу отображались данные, связанные с последним
добавленным заданием. Чтобы не приходилось каждый раз изменять номер задания в процедуре Task,
можно удалить этот номер, указав символ &laquo;?&raquo; сразу после имени группы:
<code>Task('MakerDemo?')</code>.
В этом случае при запуске программы на экране будет отображаться
<i>последнее</i> задание данной группы.
В этом случае при запуске программы на экране будет отображаться
<i>последнее</i> задание данной группы.
</p>
<a name="comments"></a><h2>Добавление описания группы и ее подгрупп</h2>
<a name="comments"></a><h2>Добавление описания группы и ее подгрупп</h2>
<p>По тексту, расположенному выше названия задания MakerDemo1 (см. приведенные выше рисунки),
мы видим, что импортированные из группы Begin задания
входят в подгруппу с заголовком &laquo;Ввод и вывод данных, оператор присваивания&raquo;.
В сводной группе MakerDemo мы можем добавить комментарий (<i>преамбулу</i>) как к самой группе, так и к любой имеющейся в ней
подгруппе. Кроме того, мы можем <i>импортировать</i>
преамбулу любой имеющейся группы или подгруппы. Для иллюстрации этих возможностей добавим в процедуру inittaskgroup
новые операторы (их надо указать после вызова процедуры CreateGroup):
<p>По тексту, расположенному выше названия задания MakerDemo1 (см. приведенные выше рисунки),
мы видим, что импортированные из группы Begin задания
входят в подгруппу с заголовком &laquo;Ввод и вывод данных, оператор присваивания&raquo;.
В сводной группе MakerDemo мы можем добавить комментарий (<i>преамбулу</i>) как к самой группе, так и к любой имеющейся в ней
подгруппе. Кроме того, мы можем <i>импортировать</i>
преамбулу любой имеющейся группы или подгруппы. Для иллюстрации этих возможностей добавим в процедуру inittaskgroup
новые операторы (их надо указать после вызова процедуры CreateGroup):
</p>
<pre>CommentText('Данная группа демонстрирует различные возможности');
CommentText('\Iконструктора учебных заданий\i \MPT4TaskMaker\m.');
<pre>CommentText('Данная группа демонстрирует различные возможности');
CommentText('\Iконструктора учебных заданий\i \MPT4TaskMaker\m.');
Subgroup('Ввод и вывод данных, оператор присваивания');
CommentText('В этой подгруппе содержатся задания, импортированные');
CommentText('из группы Begin.\PПриводимый ниже абзац преамбулы');
CommentText('также импортирован из данной группы.\P');
Subgroup('Ввод и вывод данных, оператор присваивания');
CommentText('В этой подгруппе содержатся задания, импортированные');
CommentText('из группы Begin.\PПриводимый ниже абзац преамбулы');
CommentText('также импортирован из данной группы.\P');
UseComment('Begin');
</pre>
<p>Два первых вызова процедуры <a href="tmaker_proc1.html#CommentText">CommentText</a>
определяют текст преамбулы для группы MakerDemo. Обратите внимание на
<a href="tmaker_format.html"><i>управляющие последовательности</i></a>: пара последовательностей <code>\I</code>
и <code>\i</code> выделяет <i>курсивный</i> фрагмент,
а пара <code>\M</code> и <code>\m</code> выделяет фрагмент, в которым используется <code>моноширинный</code> шрифт.
Последующий вызов процедуры Subgroup устанавливает режим определения преамбулы для подгруппы с указанным именем.
В тексте этой преамбулы, который, как и текст преамбулы группы, определяется с помощью процедуры CommentText,
используется управляющая последовательность <code>\P</code>, обеспечивающая переход к новому абзацу.
<p>Два первых вызова процедуры <a href="tmaker_proc1.html#CommentText">CommentText</a>
определяют текст преамбулы для группы MakerDemo. Обратите внимание на
<a href="tmaker_format.html"><i>управляющие последовательности</i></a>: пара последовательностей <code>\I</code>
и <code>\i</code> выделяет <i>курсивный</i> фрагмент,
а пара <code>\M</code> и <code>\m</code> выделяет фрагмент, в которым используется <code>моноширинный</code> шрифт.
Последующий вызов процедуры Subgroup устанавливает режим определения преамбулы для подгруппы с указанным именем.
В тексте этой преамбулы, который, как и текст преамбулы группы, определяется с помощью процедуры CommentText,
используется управляющая последовательность <code>\P</code>, обеспечивающая переход к новому абзацу.
</p>
<p>Наконец, последняя процедура (<a href="tmaker_proc1.html#UseComment">UseComment</a>) импортирует преамбулу группы
Begin в преамбулу нашей подгруппы &laquo;Ввод и вывод данных, оператор присваивания&raquo;. Имеется также вариант процедуры
UseComment, позволяющий импортировать преамбулу подгруппы; в этом варианте следует указать два параметра: имя группы и
заголовок требуемой подгруппы, входящей в эту группу. Импортировать преамбулы подгрупп можно только для тех групп заданий, в которых
имеется разделение на подгруппы (обычно это группы, содержащие большое количество заданий). В группе Begin деления на подгруппы нет, поэтому
из нее можно импортировать только преамбулу самой группы.
<p>Наконец, последняя процедура (<a href="tmaker_proc1.html#UseComment">UseComment</a>) импортирует преамбулу группы
Begin в преамбулу нашей подгруппы &laquo;Ввод и вывод данных, оператор присваивания&raquo;. Имеется также вариант процедуры
UseComment, позволяющий импортировать преамбулу подгруппы; в этом варианте следует указать два параметра: имя группы и
заголовок требуемой подгруппы, входящей в эту группу. Импортировать преамбулы подгрупп можно только для тех групп заданий, в которых
имеется разделение на подгруппы (обычно это группы, содержащие большое количество заданий). В группе Begin деления на подгруппы нет, поэтому
из нее можно импортировать только преамбулу самой группы.
</p>
<p>Для того чтобы ознакомиться с результатом сделанных изменений, следует сгенерировать html-страницу с текстом группы MakerDemo.
Для этого достаточно внести небольшое изменение в тестирующую программу, а именно, следует
заменить символ &laquo;?&raquo; в параметре процедуры Task на &laquo;#&raquo;: <code>Task('MakerDemo?')</code>.
Теперь при запуске данной программы на экране вместо окна задачника появится html-браузер с описанием созданной группы:
<p>Для того чтобы ознакомиться с результатом сделанных изменений, следует сгенерировать html-страницу с текстом группы MakerDemo.
Для этого достаточно внести небольшое изменение в тестирующую программу, а именно, следует
заменить символ &laquo;?&raquo; в параметре процедуры Task на &laquo;#&raquo;: <code>Task('MakerDemo?')</code>.
Теперь при запуске данной программы на экране вместо окна задачника появится html-браузер с описанием созданной группы:
<p class="ris"><img border="1" src="images\pt4make7.png">
</p>
<p>Обратите внимание на последний абзац в описании подгруппы (&laquo;Все входные и выходные данные в заданиях этой группы являются
вещественными числами&raquo;), который был импортирован из группы Begin.
<p>Обратите внимание на последний абзац в описании подгруппы (&laquo;Все входные и выходные данные в заданиях этой группы являются
вещественными числами&raquo;), который был импортирован из группы Begin.
</p>
<p><b>Примечание</b>. Если указать в параметре процедуры Task символ &laquo;#&raquo;,
не удаляя номер задания (например, <code>Task('MakerDemo2#')</code>), то в html-описание
будет включено только задание с указанным номером. При этом будут также выведены комментарии ко всей группе и к той подгруппе, к
которой относится выбранное задание. Для включения в html-страницу нескольких заданий (или групп заданий) достаточно для каждого из них
вызвать процедуру Task с параметром, оканчивающимся символом &laquo;#&raquo;.
<p><b>Примечание</b>. Если указать в параметре процедуры Task символ &laquo;#&raquo;,
не удаляя номер задания (например, <code>Task('MakerDemo2#')</code>), то в html-описание
будет включено только задание с указанным номером. При этом будут также выведены комментарии ко всей группе и к той подгруппе, к
которой относится выбранное задание. Для включения в html-страницу нескольких заданий (или групп заданий) достаточно для каждого из них
вызвать процедуру Task с параметром, оканчивающимся символом &laquo;#&raquo;.
</p>
<h2>Добавление нового задания</h2>
<p>Добавим к нашей группе новое задание. Фактически это задание будет дублировать задание Begin3,
однако вместо импортирования этого задания мы разработаем его самостоятельно. Все действия по созданию
нового задания удобно реализовать во вспомогательной процедуре, которую можно назвать MakerDemo3
(таким образом, название процедуры будет соответствовать имени создаваемого задания, хотя это и не является обязательным):
<h2>Добавление нового задания</h2>
<p>Добавим к нашей группе новое задание. Фактически это задание будет дублировать задание Begin3,
однако вместо импортирования этого задания мы разработаем его самостоятельно. Все действия по созданию
нового задания удобно реализовать во вспомогательной процедуре, которую можно назвать MakerDemo3
(таким образом, название процедуры будет соответствовать имени создаваемого задания, хотя это и не является обязательным):
</p>
<pre>procedure MakerDemo3;
var
a, b: real;
begin
CreateTask('Ввод и вывод данных, оператор присваивания');
TaskText('Даны стороны прямоугольника~{a} и~{b}.', 0, 2);
TaskText('Найти его площадь {S}~=~{a}\*{b} и периметр {P}~=~2\*({a}\;+\;{b}).',
CreateTask('Ввод и вывод данных, оператор присваивания');
TaskText('Даны стороны прямоугольника~{a} и~{b}.', 0, 2);
TaskText('Найти его площадь {S}~=~{a}\*{b} и периметр {P}~=~2\*({a}\;+\;{b}).',
0, 4);
a := RandomN(1, 99) / 10;
b := RandomN(1, 99) / 10;
@ -225,25 +225,25 @@ begin
SetTestCount(3);
end;
</pre>
<p>Описание процедуры MakerDemo3 (как и описания всех других процедур, обеспечивающих формирование новых заданий)
следует разместить перед описанием процедуры InitTask.
<p>Описание процедуры MakerDemo3 (как и описания всех других процедур, обеспечивающих формирование новых заданий)
следует разместить перед описанием процедуры InitTask.
</p>
<p>Процедура MakerDemo3 включает все основные действия, используемые при формировании нового задания:
<p>Процедура MakerDemo3 включает все основные действия, используемые при формировании нового задания:
</p>
<ul><li><i>инициализацию</i> нового задания (процедура <a href="tmaker_proc1.html#CreateTask">CreateTask</a>;
мы указали в этой процедуре, что данное задание должно входить
в подгруппу &laquo;Ввод и вывод данных, оператор присваивания&raquo;, т.&nbsp;е. в ту же подгруппу, что и два
предыдущих задания);
<li>определение его <i>формулировки</i> (процедуры <a href="tmaker_proc1.html#TaskText">TaskText</a>; обратите внимание на используемые в
этих процедурах <a href="tmaker_format.html">управляющие последовательности</a>);
<li>определение исходных (процедуры <a href="tmaker_proc1.html#DataN">DataR</a>) и результирующих данных
(процедуры <a href="tmaker_proc1.html#ResultN">ResultR</a>); при этом исходные данные генерируются с помощью
датчика случайных чисел (процедура <a href="tmaker_proc1.html#Random">RandomN</a>);
<li>указание количества успешных тестовых запусков программы учащегося, достаточных для регистрации задания как выполненного
(процедура <a href="tmaker_proc1.html#SetTestCount">SetTestCount</a>;
для нашего простого задания достаточно трех <i>проведенных подряд</i> успешных тестовых запусков).
<ul><li><i>инициализацию</i> нового задания (процедура <a href="tmaker_proc1.html#CreateTask">CreateTask</a>;
мы указали в этой процедуре, что данное задание должно входить
в подгруппу &laquo;Ввод и вывод данных, оператор присваивания&raquo;, т.&nbsp;е. в ту же подгруппу, что и два
предыдущих задания);
<li>определение его <i>формулировки</i> (процедуры <a href="tmaker_proc1.html#TaskText">TaskText</a>; обратите внимание на используемые в
этих процедурах <a href="tmaker_format.html">управляющие последовательности</a>);
<li>определение исходных (процедуры <a href="tmaker_proc1.html#DataN">DataR</a>) и результирующих данных
(процедуры <a href="tmaker_proc1.html#ResultN">ResultR</a>); при этом исходные данные генерируются с помощью
датчика случайных чисел (процедура <a href="tmaker_proc1.html#Random">RandomN</a>);
<li>указание количества успешных тестовых запусков программы учащегося, достаточных для регистрации задания как выполненного
(процедура <a href="tmaker_proc1.html#SetTestCount">SetTestCount</a>;
для нашего простого задания достаточно трех <i>проведенных подряд</i> успешных тестовых запусков).
</ul>
<p>Необходимо также включить вызов созданной процедуры в основную процедуру группы MakerDemo, связав его с номером 3:
<p>Необходимо также включить вызов созданной процедуры в основную процедуру группы MakerDemo, связав его с номером 3:
</p>
<pre>procedure InitTask(num: integer);
begin
@ -253,35 +253,35 @@ begin
end;
end;
</pre>
<p>Наконец, следует откорректировать число заданий в вызове процедуры CreateGroup, изменив его на 3.
<p>Наконец, следует откорректировать число заданий в вызове процедуры CreateGroup, изменив его на 3.
</p>
<p>Запустив тестирующую программу, мы увидим в html-описании группы MakerDemo формулировки трех заданий,
а выполнив обратную замену в этой программе символа &laquo;#&raquo; на &laquo;?&raquo; (в результате
вызов процедуры Task опять примет вид <code>Task('MakerDemo?')</code>) и повторно запустив программу
на выполнение, мы увидим окно задачника
с загруженным заданием MakerDemo3. Заметим, что при последующих запусках проекта мы будем получать
в окне задачника различные исходные данные; это связано с тем, что при генерации исходных данных
используется датчик случайных чисел.
<p>Запустив тестирующую программу, мы увидим в html-описании группы MakerDemo формулировки трех заданий,
а выполнив обратную замену в этой программе символа &laquo;#&raquo; на &laquo;?&raquo; (в результате
вызов процедуры Task опять примет вид <code>Task('MakerDemo?')</code>) и повторно запустив программу
на выполнение, мы увидим окно задачника
с загруженным заданием MakerDemo3. Заметим, что при последующих запусках проекта мы будем получать
в окне задачника различные исходные данные; это связано с тем, что при генерации исходных данных
используется датчик случайных чисел.
</p>
<h2>Добавление заданий на обработку двумерных массивов и символьных строк</h2>
<p>Добавим к группе MakerDemo еще два задания: первое из них дублирует задание Matrix7
(подгруппа &laquo;Двумерные массивы (матрицы): вывод элементов&raquo;), а второе
не имеет полного аналога в группе String, однако может быть отнесено к ее первой
подгруппе: &laquo;Символы и строки: основные операции&raquo;. Реализуем эти задания
в процедурах MakerDemo4 и MakerDemo5:
<h2>Добавление заданий на обработку двумерных массивов и символьных строк</h2>
<p>Добавим к группе MakerDemo еще два задания: первое из них дублирует задание Matrix7
(подгруппа &laquo;Двумерные массивы (матрицы): вывод элементов&raquo;), а второе
не имеет полного аналога в группе String, однако может быть отнесено к ее первой
подгруппе: &laquo;Символы и строки: основные операции&raquo;. Реализуем эти задания
в процедурах MakerDemo4 и MakerDemo5:
</p>
<pre>procedure MakerDemo4;
var
m, n, i, j, k: integer;
a: array [1..5, 1..8] of real;
begin
CreateTask('Двумерные массивы (матрицы): вывод элементов');
TaskText('Дана матрица размера~{M}\;\x\;{N} и целое число~{K} (1~\l~{K}~\l~{M}).',
CreateTask('Двумерные массивы (матрицы): вывод элементов');
TaskText('Дана матрица размера~{M}\;\x\;{N} и целое число~{K} (1~\l~{K}~\l~{M}).',
0, 2);
TaskText('Вывести элементы {K}-й строки данной матрицы.', 0, 4);
TaskText('Вывести элементы {K}-й строки данной матрицы.', 0, 4);
m := RandomN(2, 5);
n := RandomN(4, 8);
k := 1;
@ -305,51 +305,51 @@ procedure MakerDemo5;
var
s: string;
begin
CreateTask('Символы и строки: основные операции');
TaskText('Дана непустая строка~{S}.', 0, 2);
TaskText('Вывести ее первый и последний символ.', 0, 4);
CreateTask('Символы и строки: основные операции');
TaskText('Дана непустая строка~{S}.', 0, 2);
TaskText('Вывести ее первый и последний символ.', 0, 4);
s := WordSample(RandomN(0, WordCount-1));
if CurrentTest = 3 then
while s[1] = s[Length(s)] do
s := WordSample(RandomN(0, WordCount-1));
DataS('S = ', s, 0, 3);
ResultC('Первый символ: ', s[1], xLeft, 3);
ResultC('Последний символ: ', s[Length(s)], xRight, 3);
ResultC('Первый символ: ', s[1], xLeft, 3);
ResultC('Последний символ: ', s[Length(s)], xRight, 3);
SetTestCount(4);
end;
</pre>
<p>Обратите внимание на использование вспомогательной функции <a href="tmaker_proc1.html#Center">Center</a>
для центрирования строк матрицы в области
исходных и результирующих данных: каждый элемент матрицы занимает 5 экранных позиций, а между
элементами размещается по одному пробелу. В процедуре MakerDemo4 не вызывается процедура SetTestCount; в этом случае
число успешных тестов, необходимых для регистрации задания как выполненного, по умолчанию полагается равным 5.
<p>Обратите внимание на использование вспомогательной функции <a href="tmaker_proc1.html#Center">Center</a>
для центрирования строк матрицы в области
исходных и результирующих данных: каждый элемент матрицы занимает 5 экранных позиций, а между
элементами размещается по одному пробелу. В процедуре MakerDemo4 не вызывается процедура SetTestCount; в этом случае
число успешных тестов, необходимых для регистрации задания как выполненного, по умолчанию полагается равным 5.
</p>
<p>При выводе элементов исходной матрицы и результирующей матричной строки дополнительные комментарии
указывать не требуется, поэтому используется вариант процедур DataR и ResultR, в котором комментарий
отсутствует (этот вариант процедур групп Data и Result добавлен в версию 4.11 конструктора учебных заданий).
<p>При выводе элементов исходной матрицы и результирующей матричной строки дополнительные комментарии
указывать не требуется, поэтому используется вариант процедур DataR и ResultR, в котором комментарий
отсутствует (этот вариант процедур групп Data и Result добавлен в версию 4.11 конструктора учебных заданий).
</p>
<p>В процедуре MakerDemo5 для получения исходных символьных строк используются
функции <a href="tmaker_proc1.html#Sample">WordCount и WordSample</a>. С помощью этих функций можно получать
различные варианты русских слов. Заметим, что в конструкторе PT4TaskMaker имеются также функции
EnWordCount и EnWordSample, с помощью которых можно получать варианты английских слов.
<p>В процедуре MakerDemo5 для получения исходных символьных строк используются
функции <a href="tmaker_proc1.html#Sample">WordCount и WordSample</a>. С помощью этих функций можно получать
различные варианты русских слов. Заметим, что в конструкторе PT4TaskMaker имеются также функции
EnWordCount и EnWordSample, с помощью которых можно получать варианты английских слов.
</p>
<p>В процедуре MakerDemo5 использована еще одна возможность, появившаяся в версии 4.11 конструктора:
функция <a href="tmaker_proc1.html#CurrentTest">CurrentTest</a>,
возвращающая порядковый номер текущего тестового запуска. Использование этой функции позволяет
связать какой-либо особый вариант теста с некоторым номером тестового испытания, и тем самым гарантировать,
что программа с решением задачи обязательно будет проверена на этом особом варианте теста.
В нашем случае строка S выбирается из набора слов-образцов, среди которых имеется
сравнительно большое число слов, начинающихся и оканчивающихся одной и той же буквой.
Для более надежного тестирования решения желательно гарантировать, что в наборе тестов
будет <i>хотя бы один тест</i>, в котором начальный и конечный символ исходной строки различаются.
Разумеется, можно было бы <i>всегда</i> выбирать подобные строки, используя соответствующий
цикл while. Однако при наличии функции CurrentTest
в этом нет необходимости: достаточно выполнять подобный цикл для единственного теста, например,
с номером 3, как это сделано в приведенной реализации задания.
В дальнейшем мы рассмотрим более содержательный пример использования функции CurrentTest.
<p>В процедуре MakerDemo5 использована еще одна возможность, появившаяся в версии 4.11 конструктора:
функция <a href="tmaker_proc1.html#CurrentTest">CurrentTest</a>,
возвращающая порядковый номер текущего тестового запуска. Использование этой функции позволяет
связать какой-либо особый вариант теста с некоторым номером тестового испытания, и тем самым гарантировать,
что программа с решением задачи обязательно будет проверена на этом особом варианте теста.
В нашем случае строка S выбирается из набора слов-образцов, среди которых имеется
сравнительно большое число слов, начинающихся и оканчивающихся одной и той же буквой.
Для более надежного тестирования решения желательно гарантировать, что в наборе тестов
будет <i>хотя бы один тест</i>, в котором начальный и конечный символ исходной строки различаются.
Разумеется, можно было бы <i>всегда</i> выбирать подобные строки, используя соответствующий
цикл while. Однако при наличии функции CurrentTest
в этом нет необходимости: достаточно выполнять подобный цикл для единственного теста, например,
с номером 3, как это сделано в приведенной реализации задания.
В дальнейшем мы рассмотрим более содержательный пример использования функции CurrentTest.
</p>
<p>Осталось изменить количество заданий в вызове процедуры CreateGroup на 5 и
включить вызовы новых процедур в основную процедуру группы InitTask:
<p>Осталось изменить количество заданий в вызове процедуры CreateGroup на 5 и
включить вызовы новых процедур в основную процедуру группы InitTask:
</p>
<pre>procedure InitTask(num: integer);
begin
@ -362,7 +362,7 @@ begin
end;
</pre>
<p>Приведем вид окна задачника для новых заданий:
<p>Приведем вид окна задачника для новых заданий:
</p>
<p class="ris"><img border="0" src="images\pt4make8.png">
</p>
@ -371,11 +371,11 @@ end;
<h2>Добавление заданий на обработку файлов</h2>
<p>Добавим к группе MakerDemo еще два задания: первое из них дублирует задание File63
(подгруппа &laquo;Символьные и строковые файлы&raquo;), а второе
&#151; задание Text16 (подгруппа &laquo;Текстовые файлы: основные операции&raquo;). Реализуем эти задания
в процедурах MakerDemo6 и MakerDemo7:
<h2>Добавление заданий на обработку файлов</h2>
<p>Добавим к группе MakerDemo еще два задания: первое из них дублирует задание File63
(подгруппа &laquo;Символьные и строковые файлы&raquo;), а второе
&#151; задание Text16 (подгруппа &laquo;Текстовые файлы: основные операции&raquo;). Реализуем эти задания
в процедурах MakerDemo6 и MakerDemo7:
</p>
<pre>function FileName(Len: integer): string;
@ -399,13 +399,13 @@ var
s: ShortString;
c: char;
begin
CreateTask('Символьные и строковые файлы');
CreateTask('Символьные и строковые файлы');
TaskText(
'Дано целое число~{K} (>\,0) и строковый файл.'#13 +
'Создать два новых файла: строковый, содержащий первые {K}~символов'#13 +
'каждой строки исходного файла, и символьный, содержащий {K}-й символ'#13 +
'каждой строки (если длина строки меньше~{K}, то в строковый файл'#13 +
'записывается вся строка, а в символьный файл записывается пробел).'
'Дано целое число~{K} (>\,0) и строковый файл.'#13 +
'Создать два новых файла: строковый, содержащий первые {K}~символов'#13 +
'каждой строки исходного файла, и символьный, содержащий {K}-й символ'#13 +
'каждой строки (если длина строки меньше~{K}, то в строковый файл'#13 +
'записывается вся строка, а в символьный файл записывается пробел).'
);
s1 := '1' + FileName(5) + '.tst';
s2 := '2' + FileName(5) + '.tst';
@ -437,14 +437,14 @@ begin
Close(fs2);
Close(fc3);
DataN('K = ', k, 0, 1, 1);
DataS('Имя исходного файла: ', s1, 3, 2);
DataS('Имя результирующего строкового файла: ', s2, 3, 4);
DataS('Имя результирующего символьного файла: ', s3, 3, 5);
DataComment('Содержимое исходного файла:', xRight, 2);
DataS('Имя исходного файла: ', s1, 3, 2);
DataS('Имя результирующего строкового файла: ', s2, 3, 4);
DataS('Имя результирующего символьного файла: ', s3, 3, 5);
DataComment('Содержимое исходного файла:', xRight, 2);
DataFileS(s1, 3, jmax + 3);
ResultComment('Содержимое результирующего строкового файла:',
ResultComment('Содержимое результирующего строкового файла:',
0, 2);
ResultComment('Содержимое результирующего символьного файла:',
ResultComment('Содержимое результирующего символьного файла:',
0, 4);
ResultFileS(s2, 3, k + 3);
ResultFileC(s3, 5, 4);
@ -456,9 +456,9 @@ var
s, s1, s2, s0: string;
t1, t2: text;
begin
CreateTask('Текстовые файлы: основные операции');
TaskText('Дан текстовый файл.', 0, 2);
TaskText('Удалить из него все пустые строки.', 0, 4);
CreateTask('Текстовые файлы: основные операции');
TaskText('Дан текстовый файл.', 0, 2);
TaskText('Удалить из него все пустые строки.', 0, 4);
s1 := FileName(6) + '.tst';
s2 := '#' + FileName(6) + '.tst';
s := TextSample(RandomN(0, TextCount-1));
@ -480,41 +480,41 @@ begin
ResultFileT(s1, 1, 5);
Rename(t2, s1);
DataFileT(s1, 2, 5);
DataS('Имя файла: ', s1, 0, 1);
DataS('Имя файла: ', s1, 0, 1);
SetTestCount(3);
end;
</pre>
<p>При реализации этих заданий используется вспомогательная функция FileName(Len), позволяющая
создать случайное имя файла длины Len (без расширения).
Имя файла при этом будет содержать только цифры и строчные (маленькие) латинские буквы.
<p>При реализации этих заданий используется вспомогательная функция FileName(Len), позволяющая
создать случайное имя файла длины Len (без расширения).
Имя файла при этом будет содержать только цифры и строчные (маленькие) латинские буквы.
</p>
<p>Имена файлов, полученные с помощью функции FileName, дополняются расширением .tst (заметим, что
в базовых группах File, Text и Param это расширение используется в именах всех исходных и результирующих файлов).
<p>Имена файлов, полученные с помощью функции FileName, дополняются расширением .tst (заметим, что
в базовых группах File, Text и Param это расширение используется в именах всех исходных и результирующих файлов).
</p>
<p>Функция FileName используется также для генерации элементов строкового файла в процедуре MakerDemo6.
<p>Функция FileName используется также для генерации элементов строкового файла в процедуре MakerDemo6.
</p>
<p>Для того чтобы предотвратить возможность случайного совпадения имен файлов, в процедуре MakerDemo6 к созданным именам
добавляются префиксы: <code>1</code> для первого файла, <code>2</code> для второго, <code>3</code> для третьего.
В процедуре MakerDemo7 имя
временного файла дополняется префиксом <code>#</code>, что также гарантирует его отличие от имени основного файла задания.
<p>Для того чтобы предотвратить возможность случайного совпадения имен файлов, в процедуре MakerDemo6 к созданным именам
добавляются префиксы: <code>1</code> для первого файла, <code>2</code> для второго, <code>3</code> для третьего.
В процедуре MakerDemo7 имя
временного файла дополняется префиксом <code>#</code>, что также гарантирует его отличие от имени основного файла задания.
</p>
<p>В процедуре MakerDemo6 использован новый вариант <a href="tmaker_proc1.html#TaskText">процедуры TaskText</a>,
появившийся в версии 4.11 задачника.
В этом варианте процедура TaskText принимает один строковый параметр, который определяет
<i>всю формулировку задания</i>, причем в качестве разделителей строк, входящих в формулировку, можно использовать
символы #13, #10 или их комбинацию #13#10 (в указанном порядке).
Новый вариант процедуры TaskText позволяет более наглядно отобразить формулировку задания и
не требует указания дополнительных параметров.
<p>В процедуре MakerDemo6 использован новый вариант <a href="tmaker_proc1.html#TaskText">процедуры TaskText</a>,
появившийся в версии 4.11 задачника.
В этом варианте процедура TaskText принимает один строковый параметр, который определяет
<i>всю формулировку задания</i>, причем в качестве разделителей строк, входящих в формулировку, можно использовать
символы #13, #10 или их комбинацию #13#10 (в указанном порядке).
Новый вариант процедуры TaskText позволяет более наглядно отобразить формулировку задания и
не требует указания дополнительных параметров.
</p>
<p>При реализации задания на обработку текстовых файлов для генерации содержимого файла используются
функции <a href="tmaker_proc1.html#Sample">TextCount и TextSample</a>. Строка, возвращаемая функцией TextSample,
представляет собой текст, содержащий <i>маркеры конца строки</i> &#151; символы #13#10. Указанные символы
<i>разделяют соседние строки текста</i> (в конце текста маркер конца строки не указывается).
Благодаря наличию маркеров конца строки полученный текст можно записать в текстовый файл с помощью единственной процедуры
writeln, которая, кроме записи текста, обеспечивает добавление маркера конца строки в конец файла.
<p>При реализации задания на обработку текстовых файлов для генерации содержимого файла используются
функции <a href="tmaker_proc1.html#Sample">TextCount и TextSample</a>. Строка, возвращаемая функцией TextSample,
представляет собой текст, содержащий <i>маркеры конца строки</i> &#151; символы #13#10. Указанные символы
<i>разделяют соседние строки текста</i> (в конце текста маркер конца строки не указывается).
Благодаря наличию маркеров конца строки полученный текст можно записать в текстовый файл с помощью единственной процедуры
writeln, которая, кроме записи текста, обеспечивает добавление маркера конца строки в конец файла.
</p>
<p>После разработки новых заданий необходимо изменить количество заданий в вызове процедуры CreateGroup на 7 и
включить вызовы новых процедур в основную процедуру группы InitTask:
<p>После разработки новых заданий необходимо изменить количество заданий в вызове процедуры CreateGroup на 7 и
включить вызовы новых процедур в основную процедуру группы InitTask:
</p>
<pre>procedure InitTask(num: integer);
begin
@ -529,28 +529,28 @@ begin
end;
</pre>
<p>Приведем вид окна задачника для новых заданий:
<p>Приведем вид окна задачника для новых заданий:
</p>
<p class="ris"><img border="0" src="images\pt4make10.png">
</p>
<p class="ris"><img border="0" src="images\pt4make11.png">
</p>
<a name="dynamic"></a><h2>Добавление заданий на обработку динамических структур данных</h2>
<a name="dynamic"></a><h2>Добавление заданий на обработку динамических структур данных</h2>
<p>Наконец, добавим в нашу группу задание,
посвященное обработке динамических структур данных, причем представим его в двух
вариантах: традиционном, основанном на использовании записей типа TNode
и связанных с ними указателей типа PNode, и &laquo;объектном&raquo;, характерном для .NET-языков
(C#, Visual Basic .NET, PascalABC.NET), а также языков Python и Java.
Следует подчеркнуть, что при <i>разработке</i> как традиционного, так и объектного варианта заданий
на динамические структуры надо использовать типы TNode и PNode и связанные с ними процедуры конструктора учебных заданий.
В то же время, при <i>выполнении</i> объектного варианта задания на соответствующем языке требуется
использовать объекты типа Node (которые при разработке задания не применяются).
<p>Наконец, добавим в нашу группу задание,
посвященное обработке динамических структур данных, причем представим его в двух
вариантах: традиционном, основанном на использовании записей типа TNode
и связанных с ними указателей типа PNode, и &laquo;объектном&raquo;, характерном для .NET-языков
(C#, Visual Basic .NET, PascalABC.NET), а также языков Python и Java.
Следует подчеркнуть, что при <i>разработке</i> как традиционного, так и объектного варианта заданий
на динамические структуры надо использовать типы TNode и PNode и связанные с ними процедуры конструктора учебных заданий.
В то же время, при <i>выполнении</i> объектного варианта задания на соответствующем языке требуется
использовать объекты типа Node (которые при разработке задания не применяются).
</p>
<p>Задание, которое мы реализуем, дублирует задание Dynamic30, посвященное преобразованию
односвязного списка в двусвязный (подгруппа &laquo;Динамические структуры данных: двусвязный список&raquo;).
Оформим два варианта этого задания в виде процедур MakerDemo8 и MakerDemo8Obj:
<p>Задание, которое мы реализуем, дублирует задание Dynamic30, посвященное преобразованию
односвязного списка в двусвязный (подгруппа &laquo;Динамические структуры данных: двусвязный список&raquo;).
Оформим два варианта этого задания в виде процедур MakerDemo8 и MakerDemo8Obj:
</p>
<pre>var WrongNode: TNode;
@ -583,7 +583,7 @@ begin
p2^.Next := nil;
SetPointer(1, p1);
SetPointer(2, p2);
ResultP('Последний элемент: ', 2, 0, 2);
ResultP('Последний элемент: ', 2, 0, 2);
ResultList(1, 0, 3);
ShowPointer(2);
DataP(1, 0, 2);
@ -599,109 +599,109 @@ end;
procedure MakerDemo8;
begin
CreateTask('Динамические структуры данных: двусвязный список');
TaskText('Дан указатель~{P}_1 на начало непустой цепочки ' +
'элементов-записей типа TNode,', 0, 1);
TaskText('связанных между собой с помощью поля Next. Используя ' +
'поле Prev записи TNode,', 0, 2);
TaskText('преобразовать исходную (\Iодносвязную\i) цепочку ' +
'в \Iдвусвязную\i, в которой каждый', 0, 3);
TaskText('элемент связан не только с последующим элементом ' +
'(с помощью поля Next),', 0, 4);
TaskText('но и с предыдущим (с помощью поля Prev). Поле Prev ' +
'первого элемента положить', 0, 5);
TaskText('равным \N. Вывести указатель на последний элемент ' +
'преобразованной цепочки.', 0, 0);
CreateTask('Динамические структуры данных: двусвязный список');
TaskText('Дан указатель~{P}_1 на начало непустой цепочки ' +
'элементов-записей типа TNode,', 0, 1);
TaskText('связанных между собой с помощью поля Next. Используя ' +
'поле Prev записи TNode,', 0, 2);
TaskText('преобразовать исходную (\Iодносвязную\i) цепочку ' +
'в \Iдвусвязную\i, в которой каждый', 0, 3);
TaskText('элемент связан не только с последующим элементом ' +
'(с помощью поля Next),', 0, 4);
TaskText('но и с предыдущим (с помощью поля Prev). Поле Prev ' +
'первого элемента положить', 0, 5);
TaskText('равным \N. Вывести указатель на последний элемент ' +
'преобразованной цепочки.', 0, 0);
MakerDemo8Data;
end;
procedure MakerDemo8Obj;
begin
CreateTask('Динамические структуры данных: двусвязный список');
CreateTask('Динамические структуры данных: двусвязный список');
TaskText(
'Дана ссылка~{A}_1 на начало непустой цепочки элементов-объектов типа Node,'#13 +
'связанных между собой с помощью своих свойств Next. Используя свойства Prev'#13 +
'данных объектов, преобразовать исходную (\Iодносвязную\i) цепочку в \Iдвусвязную\i,'#13 +
'в которой каждый элемент связан не только с последующим элементом (с помощью'#13 +
'свойства Next), но и с предыдущим (с помощью свойства Prev). Свойство Prev'#13 +
'первого элемента положить равным \O. Вывести ссылку~{A}_2 на последний'#13 +
'элемент преобразованной цепочки.'
'Дана ссылка~{A}_1 на начало непустой цепочки элементов-объектов типа Node,'#13 +
'связанных между собой с помощью своих свойств Next. Используя свойства Prev'#13 +
'данных объектов, преобразовать исходную (\Iодносвязную\i) цепочку в \Iдвусвязную\i,'#13 +
'в которой каждый элемент связан не только с последующим элементом (с помощью'#13 +
'свойства Next), но и с предыдущим (с помощью свойства Prev). Свойство Prev'#13 +
'первого элемента положить равным \O. Вывести ссылку~{A}_2 на последний'#13 +
'элемент преобразованной цепочки.'
);
SetObjectStyle;
MakerDemo8Data;
end;
</pre>
<p>Анализируя приведенные варианты процедур, легко заметить, что они отличаются лишь деталями формулировки задания.
Алгоритмы генерации исходных и контрольных данных
для традиционного и объектного вариантов совпадают, поэтому они выделены в отдельную вспомогательную процедуру MakerDemo8Data.
В то же время <i>представления</i> динамических структур и связанных с ними
указателей или объектов будут отличаться (см. рисунки, приведенные ниже). Необходимые корректировки в представлении
динамических структур выполняются задачником автоматически, с учетом используемого языка программирования.
<p>Анализируя приведенные варианты процедур, легко заметить, что они отличаются лишь деталями формулировки задания.
Алгоритмы генерации исходных и контрольных данных
для традиционного и объектного вариантов совпадают, поэтому они выделены в отдельную вспомогательную процедуру MakerDemo8Data.
В то же время <i>представления</i> динамических структур и связанных с ними
указателей или объектов будут отличаться (см. рисунки, приведенные ниже). Необходимые корректировки в представлении
динамических структур выполняются задачником автоматически, с учетом используемого языка программирования.
</p>
<p>Однако для
языка PascalABC.NET требуемую настройку необходимо выполнить явно, так как в нем можно использовать оба варианта
представления динамических структур: традиционный (как для обычного Паскаля в системах Delphi и Free Pascal Lazarus)
и объектный (как в языках C#, Visual Basic .NET, Python и Java).
Для того чтобы представление динамических данных при выполнении задания в среде PascalABC.NET соответствовало объектному
варианту, следует в начале процедуры, реализующей задание (перед вызовом любых процедур, связанных
с указателями и динамическими структурами), вызвать специальную процедуру без параметров
<a href="tmaker_proc2.html#SetObjectStyle">SetObjectStyle</a>. Для остальных языков данная процедура не выполняет никаких действий.
<p>Однако для
языка PascalABC.NET требуемую настройку необходимо выполнить явно, так как в нем можно использовать оба варианта
представления динамических структур: традиционный (как для обычного Паскаля в системах Delphi и Free Pascal Lazarus)
и объектный (как в языках C#, Visual Basic .NET, Python и Java).
Для того чтобы представление динамических данных при выполнении задания в среде PascalABC.NET соответствовало объектному
варианту, следует в начале процедуры, реализующей задание (перед вызовом любых процедур, связанных
с указателями и динамическими структурами), вызвать специальную процедуру без параметров
<a href="tmaker_proc2.html#SetObjectStyle">SetObjectStyle</a>. Для остальных языков данная процедура не выполняет никаких действий.
</p>
<p>Обратите внимание на возможность использования в формулировке задания более 5 экранных строк. Строки, которые
не умещаются в области формулировки задания, следует добавлять к заданию процедурой TaskText,
указывая в качестве последнего параметра процедуры число 0 (см. процедуру MakerDemo8).
Еще проще задавать &laquo;длинные&raquo; формулировки заданий с помощью нового варианта
процедуры TaskText с единственным строковым параметром, содержащим все строки формулировки (см. процедуру MakerDemo9).
При наличии подобных строк в окне задачника (если окно находится в режиме с фиксированной компоновкой)
слева от области формулировки появятся кнопки, обеспечивающие прокрутку формулировки задания;
кроме этих кнопок для прокрутки можно также использовать стандартные клавиши, в частности, клавиши со стрелками.
<p>Обратите внимание на возможность использования в формулировке задания более 5 экранных строк. Строки, которые
не умещаются в области формулировки задания, следует добавлять к заданию процедурой TaskText,
указывая в качестве последнего параметра процедуры число 0 (см. процедуру MakerDemo8).
Еще проще задавать &laquo;длинные&raquo; формулировки заданий с помощью нового варианта
процедуры TaskText с единственным строковым параметром, содержащим все строки формулировки (см. процедуру MakerDemo9).
При наличии подобных строк в окне задачника (если окно находится в режиме с фиксированной компоновкой)
слева от области формулировки появятся кнопки, обеспечивающие прокрутку формулировки задания;
кроме этих кнопок для прокрутки можно также использовать стандартные клавиши, в частности, клавиши со стрелками.
</p>
<p>Для того чтобы имя нулевого указателя (или объекта) соответствовало используемому языку программирования,
в формулировке задания применяются управляющие последовательности <code>\N</code> (имя нулевого указателя) и <code>\O</code> (имя нулевого объекта).
Для языка PascalABC.NET обе эти последовательности генерируют текст <code>nil</code>.
<p>Для того чтобы имя нулевого указателя (или объекта) соответствовало используемому языку программирования,
в формулировке задания применяются управляющие последовательности <code>\N</code> (имя нулевого указателя) и <code>\O</code> (имя нулевого объекта).
Для языка PascalABC.NET обе эти последовательности генерируют текст <code>nil</code>.
</p>
<p>Достаточно часто алгоритмы, разработанные учащимися для обработки динамических структур данных, дают неверные результаты
в случае особых (хотя и допустимых) структур, например, состоящих только из одного элемента. Поэтому желательно
предусмотреть появление подобных структур в тестовых наборах исходных данных.
В наших заданиях исходный список, состоящий из
<i>одного</i> элемента, будет предлагаться программе учащегося в среднем один раз при каждых четырех тестовых испытаниях.
Кроме того, благодаря использованию функции <a href="tmaker_proc1.html#CurrentTest">CurrentTest</a>, появившейся в
версии 4.11 конструктора, вариант списка с единственным элементом будет предложен программе учащегося для обработки
в тесте номер 2, а вариант списка с более чем одним элементом &#151; в тесте номер 4. Таким образом, можно гарантировать,
что при прохождении набора из 5 тестовых испытаний программе будут предложены как &laquo;стандартные&raquo;,
так и &laquo;особые&raquo; наборы исходных данных.
<p>Достаточно часто алгоритмы, разработанные учащимися для обработки динамических структур данных, дают неверные результаты
в случае особых (хотя и допустимых) структур, например, состоящих только из одного элемента. Поэтому желательно
предусмотреть появление подобных структур в тестовых наборах исходных данных.
В наших заданиях исходный список, состоящий из
<i>одного</i> элемента, будет предлагаться программе учащегося в среднем один раз при каждых четырех тестовых испытаниях.
Кроме того, благодаря использованию функции <a href="tmaker_proc1.html#CurrentTest">CurrentTest</a>, появившейся в
версии 4.11 конструктора, вариант списка с единственным элементом будет предложен программе учащегося для обработки
в тесте номер 2, а вариант списка с более чем одним элементом &#151; в тесте номер 4. Таким образом, можно гарантировать,
что при прохождении набора из 5 тестовых испытаний программе будут предложены как &laquo;стандартные&raquo;,
так и &laquo;особые&raquo; наборы исходных данных.
</p>
<p>При формировании односвязной структуры неиспользуемые поля Prev для каждого элемента структуры следует
положить равными адресу &laquo;фиктивного&raquo; элемента (в нашем случае &#151; переменной WrongNode),
не связанного с данной структурой. Заметим, что для всех элементов, кроме первого, значения поля Prev
можно было бы положить равными nil, однако это не подходит для
первого элемента: если поле Prev первого элемента будет равно nil, то слева от него будет выведен
&laquo;лишний&raquo; (в данной ситуации) текст <code>nil&lt;</code>.
<p>При формировании односвязной структуры неиспользуемые поля Prev для каждого элемента структуры следует
положить равными адресу &laquo;фиктивного&raquo; элемента (в нашем случае &#151; переменной WrongNode),
не связанного с данной структурой. Заметим, что для всех элементов, кроме первого, значения поля Prev
можно было бы положить равными nil, однако это не подходит для
первого элемента: если поле Prev первого элемента будет равно nil, то слева от него будет выведен
&laquo;лишний&raquo; (в данной ситуации) текст <code>nil&lt;</code>.
</p>
<p>Характерной особенностью разработки заданий на динамические структуры является <i>обратный порядок</i> создания этих структур:
вначале создаются <i>контрольные</i> структуры (которые сразу передаются в задачник), а затем они преобразуются в соответствующие
<i>исходные</i> структуры, которые должны не только передаваться в задачник, но и <i>оставаться в памяти</i>, чтобы в дальнейшем их можно было
использовать в программе учащегося, выполняющей это задание.
<p>Характерной особенностью разработки заданий на динамические структуры является <i>обратный порядок</i> создания этих структур:
вначале создаются <i>контрольные</i> структуры (которые сразу передаются в задачник), а затем они преобразуются в соответствующие
<i>исходные</i> структуры, которые должны не только передаваться в задачник, но и <i>оставаться в памяти</i>, чтобы в дальнейшем их можно было
использовать в программе учащегося, выполняющей это задание.
</p>
<p>Если в группу включаются задания на динамические структуры, то необходимо <i>анализировать текущий язык программирования</i>,
используемый задачником. Это обусловлено двумя причинами:
<p>Если в группу включаются задания на динамические структуры, то необходимо <i>анализировать текущий язык программирования</i>,
используемый задачником. Это обусловлено двумя причинами:
</p>
<ul><li> имеются языки, для которых отсутствует возможность выполнять
задания на обработку динамических структур (например, Visual Basic и 1C);
<li> в языках платформы .NET, а также Python и Java, необходимо использовать &laquo;объектный&raquo; стиль формулировок вместо
стиля, основанного на указателях и применяемого для языков Pascal и C++.
<ul><li> имеются языки, для которых отсутствует возможность выполнять
задания на обработку динамических структур (например, Visual Basic и 1C);
<li> в языках платформы .NET, а также Python и Java, необходимо использовать &laquo;объектный&raquo; стиль формулировок вместо
стиля, основанного на указателях и применяемого для языков Pascal и C++.
</ul>
<p>Кроме того, следует определиться с выбором стиля для языка PascalABC.NET, поскольку в нем
можно использовать как стиль указателей, так и стиль объектов. Можно, например, включить в группу заданий для языка
PascalABC.NET оба варианта каждого задания.
<p>Кроме того, следует определиться с выбором стиля для языка PascalABC.NET, поскольку в нем
можно использовать как стиль указателей, так и стиль объектов. Можно, например, включить в группу заданий для языка
PascalABC.NET оба варианта каждого задания.
</p>
<p>Отмеченные обстоятельства приводят к тому, что для разных языков программирования создаваемая группа
может содержать разное число заданий и, кроме того, для этих заданий будут использоваться разные
инициализирующие процедуры.
<p>Отмеченные обстоятельства приводят к тому, что для разных языков программирования создаваемая группа
может содержать разное число заданий и, кроме того, для этих заданий будут использоваться разные
инициализирующие процедуры.
</p>
<p>С учетом этих замечаний изменим основную процедуру группы InitTask следующим образом:
<p>С учетом этих замечаний изменим основную процедуру группы InitTask следующим образом:
</p>
@ -723,21 +723,21 @@ begin
end;
</pre>
<p>В этой процедуре используется функция <a href="tmaker_proc1.html#CurrentLanguage">CurrentLanguage</a>,
позволяющая определить текущий язык программирования,
используемый задачником. Если текущий язык относится к категории языков,
поддерживающих указатели (в том числе PascalABC.NET), то
в качестве задания номер 8 вызывается процедура MakerDemo8, в которой задание формулируется в терминах указателей.
В противном случае вызывается вариант задания, использующий объектную терминологию.
При использовании языка PascalABC.NET число заданий в группе будет равно 9; при этом дополнительное
задание номер 9 будет представлять собой &laquo;объектный&raquo; вариант задания номер 8.
<p>В этой процедуре используется функция <a href="tmaker_proc1.html#CurrentLanguage">CurrentLanguage</a>,
позволяющая определить текущий язык программирования,
используемый задачником. Если текущий язык относится к категории языков,
поддерживающих указатели (в том числе PascalABC.NET), то
в качестве задания номер 8 вызывается процедура MakerDemo8, в которой задание формулируется в терминах указателей.
В противном случае вызывается вариант задания, использующий объектную терминологию.
При использовании языка PascalABC.NET число заданий в группе будет равно 9; при этом дополнительное
задание номер 9 будет представлять собой &laquo;объектный&raquo; вариант задания номер 8.
</p>
<p>Функцию CurrentLanguage потребуется использовать и в начале процедуры inittaskgroup для того, чтобы
правильно определить количество заданий в группе для разных языков программирования.
Приведем фрагмент, на который надо заменить вызов процедуры CreateGroup и предшествующее ему ключевое слово begin
(обратите внимание на то, что теперь
в качестве предпоследнего параметра процедуры CreateGroup используется переменная n):
<p>Функцию CurrentLanguage потребуется использовать и в начале процедуры inittaskgroup для того, чтобы
правильно определить количество заданий в группе для разных языков программирования.
Приведем фрагмент, на который надо заменить вызов процедуры CreateGroup и предшествующее ему ключевое слово begin
(обратите внимание на то, что теперь
в качестве предпоследнего параметра процедуры CreateGroup используется переменная n):
</p>
<pre>var
n: integer;
@ -748,52 +748,52 @@ begin
else
if CurrentLanguage and (lgWithPointers or lgWithObjects) &lt;&gt; 0 then
n := 8;
CreateGroup('MakerDemo', 'Примеры различных задач',
'М. Э. Абрамян, 2013', 'qwqfsdf13dfttd', n, InitTask);
CreateGroup('MakerDemo', 'Примеры различных задач',
'М. Э. Абрамян, 2013', 'qwqfsdf13dfttd', n, InitTask);
</pre>
<p>Приведенный набор условий будет правильно определять количество заданий и в случае,
если состав языков, поддерживаемых задачником, будет расширен. Это обеспечивается тем, что
в условиях используются не константы для конкретных языков (за исключением константы lgPascalABCNET),
а битовые маски lgWithPointers и lgWithObjects. Первая из этих масок включает все языки, для которых
в задачнике можно использовать варианты заданий на динамические структуры, основанные на указателях,
а вторая &#151; все языки, позволяющие использовать варианты аналогичных заданий
в объектной терминологии.
<p>Приведенный набор условий будет правильно определять количество заданий и в случае,
если состав языков, поддерживаемых задачником, будет расширен. Это обеспечивается тем, что
в условиях используются не константы для конкретных языков (за исключением константы lgPascalABCNET),
а битовые маски lgWithPointers и lgWithObjects. Первая из этих масок включает все языки, для которых
в задачнике можно использовать варианты заданий на динамические структуры, основанные на указателях,
а вторая &#151; все языки, позволяющие использовать варианты аналогичных заданий
в объектной терминологии.
</p>
<p>В среде PascalABC.NET можно протестировать оба варианта реализованного задания.
Приведем вид окна задачника для этого задания (первый рисунок соответствует
варианту задания, использующему указатели, второй &#151; варианту, использующему объекты).
Обратите внимание
на кнопки, расположенные справа от формулировки задания и обеспечивающие ее прокрутку.
<p>В среде PascalABC.NET можно протестировать оба варианта реализованного задания.
Приведем вид окна задачника для этого задания (первый рисунок соответствует
варианту задания, использующему указатели, второй &#151; варианту, использующему объекты).
Обратите внимание
на кнопки, расположенные справа от формулировки задания и обеспечивающие ее прокрутку.
</p>
<p class="ris"><img border="0" src="images\pt4make12.png">
</p>
<p class="ris"><img border="0" src="images\pt4make13.png">
</p>
<p>Завершая оформление модуля PT4MakerDemo, добавим комментарии к новым подгруппам заданий (указанные операторы следует поместить
в конец процедуры inittaskgroup):
<p>Завершая оформление модуля PT4MakerDemo, добавим комментарии к новым подгруппам заданий (указанные операторы следует поместить
в конец процедуры inittaskgroup):
</p>
<pre> Subgroup('Двумерные массивы (матрицы): вывод элементов');
CommentText('Данное задание дублирует задание Matrix7.');
<pre> Subgroup('Двумерные массивы (матрицы): вывод элементов');
CommentText('Данное задание дублирует задание Matrix7.');
Subgroup('Символьные и строковые файлы');
CommentText('Данное задание дублирует задание File63.');
CommentText('Оно демонстрирует особенности, связанные с двоичными');
CommentText('\Iстроковыми\i файлами.');
Subgroup('Символьные и строковые файлы');
CommentText('Данное задание дублирует задание File63.');
CommentText('Оно демонстрирует особенности, связанные с двоичными');
CommentText('\Iстроковыми\i файлами.');
Subgroup('Текстовые файлы: основные операции');
CommentText('Данное задание дублирует задание Text16.');
Subgroup('Текстовые файлы: основные операции');
CommentText('Данное задание дублирует задание Text16.');
Subgroup('Динамические структуры данных: двусвязный список');
CommentText('Данное задание дублирует задание Dynamic30.');
CommentText('\PЗадание реализовано в двух вариантах: основанном на использовании указателей');
CommentText('(для языков Pascal и C++) и основанном на использовании объектов (для языков платформы .NET,');
CommentText('а также Python и Java). Для языка Visual Basic это задание недоступно.');
CommentText('В системе PascalABC.NET доступны оба варианта задания.');
Subgroup('Динамические структуры данных: двусвязный список');
CommentText('Данное задание дублирует задание Dynamic30.');
CommentText('\PЗадание реализовано в двух вариантах: основанном на использовании указателей');
CommentText('(для языков Pascal и C++) и основанном на использовании объектов (для языков платформы .NET,');
CommentText('а также Python и Java). Для языка Visual Basic это задание недоступно.');
CommentText('В системе PascalABC.NET доступны оба варианта задания.');
</pre>
<p>Приведем заключительную часть html-страницы с описанием данной группы:
<p>Приведем заключительную часть html-страницы с описанием данной группы:
</p>
<p class="ris"><img border="1" src="images\pt4make14.png">

View file

@ -11,131 +11,131 @@
</head>
<body>
<H1>Электронный задачник Programming Taskbook</H1>
<H1>Электронный задачник Programming Taskbook</H1>
<hr>
<H2>Общее описание</H2>
<H2>Общее описание</H2>
<p>Электронный задачник <b>Programming Taskbook</b> предназначен для обучения
программированию на языках Pascal, Visual Basic, C++, C#, Visual Basic&nbsp;.NET, Python и Java.
Он содержит 1300 учебных заданий, охватывающих все основные разделы базового
курса программирования: от скалярных типов и управляющих операторов до
сложных структур данных и рекурсивных алгоритмов. Начиная с версии 4.10, в базовый
набор заданий входят группы, связанные с <a href="Groups.html#exam">ЕГЭ по информатике и ИКТ</a>.
<p>Электронный задачник <b>Programming Taskbook</b> предназначен для обучения
программированию на языках Pascal, Visual Basic, C++, C#, Visual Basic&nbsp;.NET, Python и Java.
Он содержит 1300 учебных заданий, охватывающих все основные разделы базового
курса программирования: от скалярных типов и управляющих операторов до
сложных структур данных и рекурсивных алгоритмов. Начиная с версии 4.10, в базовый
набор заданий входят группы, связанные с <a href="Groups.html#exam">ЕГЭ по информатике и ИКТ</a>.
</p>
<p>Автором задачника <b>Programming Taskbook</b> является доцент
факультета математики, механики и компьютерных наук Южного федерального университета
Михаил Эдуардович Абрамян
<p>Автором задачника <b>Programming Taskbook</b> является доцент
факультета математики, механики и компьютерных наук Южного федерального университета
Михаил Эдуардович Абрамян
(<a href="mailto:mabr@math.sfedu.ru">mabr@math.sfedu.ru</a>). </p>
<p>Версия 4.11 задачника Programming Taskbook реализована для следующих сред:
<p>Версия 4.11 задачника Programming Taskbook реализована для следующих сред:
</p>
<ul><li>Borland Delphi 7.0 и 2006, в частности, Turbo Delphi 2006 for Windows,
<ul><li>Borland Delphi 7.0 и 2006, в частности, Turbo Delphi 2006 for Windows,
<li>Free Pascal Lazarus 1.0,
<li>Microsoft Visual Basic 5.0 и 6.0,
<li>Microsoft Visual Basic 5.0 и 6.0,
<li>Microsoft Visual C++ 6.0,
<li>Microsoft Visual Studio .NET 2003, 2005, 2008, 2010 и 2012 (языки Visual C++, Visual Basic .NET и Visual C# .NET),
<li>Microsoft Visual Studio .NET 2003, 2005, 2008, 2010 и 2012 (языки Visual C++, Visual Basic .NET и Visual C# .NET),
<li>Python 2.5, 2.6, 2.7, 3.2,
<li>NetBeans IDE 6.x и 7.x (язык Java).
<li>NetBeans IDE 6.x и 7.x (язык Java).
</ul>
<p>Задачник
включен в учебную систему программирования Pascal ABC (http://sunschool.mmcs.sfedu.ru,
автор доц. С.&nbsp;С.&nbsp;Михалкович), образуя единый программный комплекс &laquo;Pascal ABC &
<p>Задачник
включен в учебную систему программирования Pascal ABC (http://sunschool.mmcs.sfedu.ru,
автор доц. С.&nbsp;С.&nbsp;Михалкович), образуя единый программный комплекс &laquo;Pascal ABC &
Programming Taskbook&raquo;.
Задачник может также использоваться совместно
с системой программирования PascalABC.NET
и веб-средой разработки ProgrammingABC.NET WDE (http://www.pascalabc.net/WDE).
Задачник может также использоваться совместно
с системой программирования PascalABC.NET
и веб-средой разработки ProgrammingABC.NET WDE (http://www.pascalabc.net/WDE).
</p>
<p>Начиная с версии 4.9, к задачнику в качестве
дополнения можно подключать комплекс <b>Programming Taskbook for MPI</b> &#151; <i>электронный
задачник по параллельному программированию с использованием
технологии MPI</i>.
<p>Начиная с версии 4.9, к задачнику в качестве
дополнения можно подключать комплекс <b>Programming Taskbook for MPI</b> &#151; <i>электронный
задачник по параллельному программированию с использованием
технологии MPI</i>.
</p>
<p>Начиная с версии 4.10, к задачнику в качестве
дополнения можно подключать комплекс
<p>Начиная с версии 4.10, к задачнику в качестве
дополнения можно подключать комплекс
<b>Programming Taskbook for Bioinformatics</b> &#151;
<i>электронный задачник по строковым алгоритмам биоинформатики</i>.
<i>электронный задачник по строковым алгоритмам биоинформатики</i>.
</p>
<p>В версии 4.11 добавлена поддержка языков Python и Java
и дополнен интерфейс <a href="window.html">окна задачника</a> (в частности, реализован новый <a href="window.html#dynmode">режим
окна с динамической компоновкой</a>).
<p>В версии 4.11 добавлена поддержка языков Python и Java
и дополнен интерфейс <a href="window.html">окна задачника</a> (в частности, реализован новый <a href="window.html#dynmode">режим
окна с динамической компоновкой</a>).
</p>
<p>Задачник Programming Taskbook предоставляет учащимся следующие
возможности:
<p>Задачник Programming Taskbook предоставляет учащимся следующие
возможности:
<ul>
<li> отображение на экране текста задания и связанных с ним данных;
<li> демонстрация правильных результатов для каждого задания;
<li> предоставление исходных данных программе учащегося;
<li> выявление стандартных ошибок ввода-вывода, связанных с неверным количеством или неверным типом исходных или результирующих данных;
<li> проверка правильности результатов, полученных программой;
<li> запись в особый <i>файл результатов</i> информации о каждом тестовом
испытании программы;
<li> регистрация задания как выполненного после проведения серии
успешных тестовых испытаний программы.
<li> отображение на экране текста задания и связанных с ним данных;
<li> демонстрация правильных результатов для каждого задания;
<li> предоставление исходных данных программе учащегося;
<li> выявление стандартных ошибок ввода-вывода, связанных с неверным количеством или неверным типом исходных или результирующих данных;
<li> проверка правильности результатов, полученных программой;
<li> запись в особый <i>файл результатов</i> информации о каждом тестовом
испытании программы;
<li> регистрация задания как выполненного после проведения серии
успешных тестовых испытаний программы.
</ul>
</p>
<p>Использование электронного задачника существенно ускоряет процесс
выполнения заданий, так как избавляет учащегося от дополнительных усилий по
организации ввода-вывода, что особенно удобно при обработке массивов, строк,
файлов и динамических структур. Предлагая учащемуся готовые исходные
данные, задачник акцентирует его внимание на разработке и программной реализации
<i>алгоритма</i> решения заданий, причем разнообразие исходных данных обеспечивает
надежное <i>тестирование</i> предложенного алгоритма.
<p>Использование электронного задачника существенно ускоряет процесс
выполнения заданий, так как избавляет учащегося от дополнительных усилий по
организации ввода-вывода, что особенно удобно при обработке массивов, строк,
файлов и динамических структур. Предлагая учащемуся готовые исходные
данные, задачник акцентирует его внимание на разработке и программной реализации
<i>алгоритма</i> решения заданий, причем разнообразие исходных данных обеспечивает
надежное <i>тестирование</i> предложенного алгоритма.
</p>
<p>Программный комплекс &laquo;Электронный задачник по программированию Programming Taskbook 4&raquo;
зарегистрирован в Реестре программ для ЭВМ 28&nbsp;апреля 2007&nbsp;г. (свидетельство об официальной регистрации
программы для ЭВМ номер 2007611815).
<p>Программный комплекс &laquo;Электронный задачник по программированию Programming Taskbook 4&raquo;
зарегистрирован в Реестре программ для ЭВМ 28&nbsp;апреля 2007&nbsp;г. (свидетельство об официальной регистрации
программы для ЭВМ номер 2007611815).
</p>
<p>Подробная информация о задачнике, включающая его общее описание, формулировки всех учебных заданий, примеры
выполнения типовых заданий для различных языков программирования, содержится на сайте
<p>Подробная информация о задачнике, включающая его общее описание, формулировки всех учебных заданий, примеры
выполнения типовых заданий для различных языков программирования, содержится на сайте
<a href="http:\\ptaskbook.com">ptaskbook.com</a>.
</p>
<a name="tools"></a>
<h2>Программные модули
<h2>Программные модули
</h2>
<p>В состав задачника входят следующие программные модули:
<ul><li> <b>PT4Demo</b> &#151; позволяет просмотреть в <a href="Demo.html">демонстрационном режиме</a> все
задания, включенные в задачник;
<li> <b>PT4Load</b> &#151; обеспечивает <a href="Load.html">генерацию программы-шаблона</a> для
требуемого учебного задания и ее немедленную загрузку в выбранную среду программирования;
<li> <b>PT4Results</b> &#151; предназначен для расшифровки, анализа и отображения
на экране содержимого <a href="Results.html">файла результатов</a>, в который заносятся сведения о
ходе выполнения заданий.
<p>В состав задачника входят следующие программные модули:
<ul><li> <b>PT4Demo</b> &#151; позволяет просмотреть в <a href="Demo.html">демонстрационном режиме</a> все
задания, включенные в задачник;
<li> <b>PT4Load</b> &#151; обеспечивает <a href="Load.html">генерацию программы-шаблона</a> для
требуемого учебного задания и ее немедленную загрузку в выбранную среду программирования;
<li> <b>PT4Results</b> &#151; предназначен для расшифровки, анализа и отображения
на экране содержимого <a href="Results.html">файла результатов</a>, в который заносятся сведения о
ходе выполнения заданий.
</ul>
</p>
<p>В варианте задачника для PascalABC.NET эти модули
могут быть вызваны непосредственно из среды <b>PascalABC.NET</b> с помощью соответствующих команд
меню &laquo;Модули&raquo;, а также кнопок и горячих клавиш:</p>
<p>В варианте задачника для PascalABC.NET эти модули
могут быть вызваны непосредственно из среды <b>PascalABC.NET</b> с помощью соответствующих команд
меню &laquo;Модули&raquo;, а также кнопок и горячих клавиш:</p>
<ul>
<li><img border="0" src="gif/demo.gif" width="16" height="17"> или <b>Shift+Ctrl+D</b> для <b>PT4Demo</b>,
<li><img border="0" src="gif/load.gif" width="16" height="17"> или <b>Shift+Ctrl+L</b> для <b>PT4Load</b>,
<li><img border="0" src="gif/results.gif" width="16" height="17"> или <b>Shift+Ctrl+R</b> для <b>PT4Results</b>.
<li><img border="0" src="gif/demo.gif" width="16" height="17"> или <b>Shift+Ctrl+D</b> для <b>PT4Demo</b>,
<li><img border="0" src="gif/load.gif" width="16" height="17"> или <b>Shift+Ctrl+L</b> для <b>PT4Load</b>,
<li><img border="0" src="gif/results.gif" width="16" height="17"> или <b>Shift+Ctrl+R</b> для <b>PT4Results</b>.
</ul>
<p>Начиная с версии 4.11, программный модуль <b>PT4Results</b> можно вызывать непосредственно
из окна задачника, используя клавишу <b>F2</b>.
<p>Начиная с версии 4.11, программный модуль <b>PT4Results</b> можно вызывать непосредственно
из окна задачника, используя клавишу <b>F2</b>.
</p>
<h2><a name="mini"></a>
Мини-вариант задачника
Мини-вариант задачника
</h2>
<p>Часть заданий можно выполнять в&nbsp;<i>мини-варианте</i> задачника, не требующем приобретения лицензии
и регистрации лицензированной копии задачника с помощью программы настройки PT4Setup).
Задания, доступные для выполнения в мини-варианте, помечаются в <a href="window.html">окне задачника</a> символом &#171;&#176;&#187;.
В&nbsp;мини-вариант включены 310&nbsp;заданий, в&nbsp;том числе <i>все</i> задания групп Begin, Integer,
Boolean, а&nbsp;также 200 избранных заданий из&nbsp;других разделов задачника.
Ниже приводится список всех заданий, включенных в&nbsp;мини-вариант задачника:</p>
<p>Часть заданий можно выполнять в&nbsp;<i>мини-варианте</i> задачника, не требующем приобретения лицензии
и регистрации лицензированной копии задачника с помощью программы настройки PT4Setup).
Задания, доступные для выполнения в мини-варианте, помечаются в <a href="window.html">окне задачника</a> символом &#171;&#176;&#187;.
В&nbsp;мини-вариант включены 310&nbsp;заданий, в&nbsp;том числе <i>все</i> задания групп Begin, Integer,
Boolean, а&nbsp;также 200 избранных заданий из&nbsp;других разделов задачника.
Ниже приводится список всех заданий, включенных в&nbsp;мини-вариант задачника:</p>
<p>
Begin1&#150;Begin40, Integer1&#150;Integer30, Boolean1&#150;Boolean40, If4, If6, If8, If12, If22, If26,
@ -161,11 +161,11 @@ ExamTaskC53, ExamTaskC62, ExamTaskC68, ExamTaskC73, ExamTaskC81, ExamTaskC83, Ex
ExamTaskC92, ExamTaskC97, ExamTaskC100.
</p>
<p>Мини-вариант задачника можно рекомендовать для использования при самостоятельном изучении
программирования, так как он охватывает все основные темы и не содержит однотипных заданий.
Полный вариант задачника предназначен, прежде всего, для преподавателей программирования, поскольку
он позволяет легко создавать наборы индивидуальных заданий и существенно
повышает эффективность групповых практических занятий.
<p>Мини-вариант задачника можно рекомендовать для использования при самостоятельном изучении
программирования, так как он охватывает все основные темы и не содержит однотипных заданий.
Полный вариант задачника предназначен, прежде всего, для преподавателей программирования, поскольку
он позволяет легко создавать наборы индивидуальных заданий и существенно
повышает эффективность групповых практических занятий.
</p>

View file

@ -10,55 +10,55 @@
</head>
<body>
<h1>Демонстрационный режим</h1>
<h1>Демонстрационный режим</h1>
<hr>
<p>
Для запуска задачника в <i>демонстрационном режиме</i> следует
при указании имени задания в процедуре <code>Task</code>
дополнить это имя символом <code>?</code>, например:</p>
Для запуска задачника в <i>демонстрационном режиме</i> следует
при указании имени задания в процедуре <code>Task</code>
дополнить это имя символом <code>?</code>, например:</p>
<blockquote>
<code>Task('Begin12?');</code>
</blockquote>
<p>Можно также указать символ <code>?</code> сразу после имени темы, например, <code>'Begin?'</code>.
В этом случае в окне задачника сразу будет отображено <i>последнее</i> задание указанной группы.
<p>Можно также указать символ <code>?</code> сразу после имени темы, например, <code>'Begin?'</code>.
В этом случае в окне задачника сразу будет отображено <i>последнее</i> задание указанной группы.
</p>
<p>Демонстрационный режим задачника имеет следующие особенности:
<p>Демонстрационный режим задачника имеет следующие особенности:
</p>
<ul>
<li> даже если программа содержит решение задания, это решение
не анализируется и информация в файл результатов не
заносится;
<li> после отображения на экране окна задачника в разделе
результатов сразу будет выбрана вкладка &laquo;Пример верного
решения&raquo;;
<li> при одном запуске программы можно просмотреть несколько
вариантов исходных и контрольных данных; для смены набора
данных требуется нажать кнопку &laquo;Новые данные&raquo; или клавишу
пробела;
<li> при одном запуске программы можно последовательно
просмотреть все задания данной группы; для перехода к
заданию с бoльшим номером требуется нажать кнопку
&laquo;Следующее задание&raquo; или клавишу <b>Enter</b>, а для перехода к
заданию с меньшим номером требуется нажать кнопку
&laquo;Предыдущее задание&raquo; или клавишу <b>Backspace</b>. Задания
перебираются циклически.
<li> даже если программа содержит решение задания, это решение
не анализируется и информация в файл результатов не
заносится;
<li> после отображения на экране окна задачника в разделе
результатов сразу будет выбрана вкладка &laquo;Пример верного
решения&raquo;;
<li> при одном запуске программы можно просмотреть несколько
вариантов исходных и контрольных данных; для смены набора
данных требуется нажать кнопку &laquo;Новые данные&raquo; или клавишу
пробела;
<li> при одном запуске программы можно последовательно
просмотреть все задания данной группы; для перехода к
заданию с бoльшим номером требуется нажать кнопку
&laquo;Следующее задание&raquo; или клавишу <b>Enter</b>, а для перехода к
заданию с меньшим номером требуется нажать кнопку
&laquo;Предыдущее задание&raquo; или клавишу <b>Backspace</b>. Задания
перебираются циклически.
</ul>
<p>На рисунке приведен вид окна задачника в демонстрационном режиме.
<p>На рисунке приведен вид окна задачника в демонстрационном режиме.
</p>
<blockquote>
<img border="0" src="gif/demo_1.png">
</blockquote>
<p>При использовании <a href="window.html#dynmode">динамической компоновки</a>, появившейся в версии 4.11,
окно в демонстрационном режиме выглядит следующим образом:
<p>При использовании <a href="window.html#dynmode">динамической компоновки</a>, появившейся в версии 4.11,
окно в демонстрационном режиме выглядит следующим образом:
</p>
<blockquote>
<img border="0" src="gif/demo_1b.png">
@ -66,56 +66,56 @@
<p>Демонстрационный режим удобно использовать для быстрого просмотра всех
заданий требуемой группы, а также различных вариантов исходных данных для
требуемого задания.</p>
<p>Для демо-просмотра всех групп заданий, включенных в базовый набор, предназначен программный модуль
<b>PT4Demo</b>, который вызывается непосредственно из среды <b>PascalABC.NET</b> командой
меню &laquo;Модули | Просмотреть задания&raquo; (с данной командой связана также
кнопка <img border="0" src="gif/demo.gif" width="16" height="17"> и клавиатурная
комбинация <b>Shift+Ctrl+D</b>).
<p>Демонстрационный режим удобно использовать для быстрого просмотра всех
заданий требуемой группы, а также различных вариантов исходных данных для
требуемого задания.</p>
<p>Для демо-просмотра всех групп заданий, включенных в базовый набор, предназначен программный модуль
<b>PT4Demo</b>, который вызывается непосредственно из среды <b>PascalABC.NET</b> командой
меню &laquo;Модули | Просмотреть задания&raquo; (с данной командой связана также
кнопка <img border="0" src="gif/demo.gif" width="16" height="17"> и клавиатурная
комбинация <b>Shift+Ctrl+D</b>).
</p>
<p>Ниже приводится вид окна модуля PT4Demo. В данном окне можно выбрать
группу заданий (для быстрого перебора групп предназначены горячие клавиши
<b>Ctrl+[&lt;]</b> и <b>Ctrl+[&gt;]</b>) и номер задания в пределах группы (номера можно перебирать
с помощью комбинаций <b>Ctrl+Shift+[&lt;]</b> и <b>Ctrl+Shift+[&gt;]</b>).
<p>Ниже приводится вид окна модуля PT4Demo. В данном окне можно выбрать
группу заданий (для быстрого перебора групп предназначены горячие клавиши
<b>Ctrl+[&lt;]</b> и <b>Ctrl+[&gt;]</b>) и номер задания в пределах группы (номера можно перебирать
с помощью комбинаций <b>Ctrl+Shift+[&lt;]</b> и <b>Ctrl+Shift+[&gt;]</b>).
</p>
<blockquote>
<img border="0" src="gif/demo_2.png">
</blockquote>
<p>Если задачник не зарегистрирован, то он всегда запускается в демонстрационном режиме
(исключение составляют задания, доступные для выполнения в мини-варианте).
Переключение в демонстрационный режим автоматически происходит также в случае, если в каталоге
с выполняемой программой отсутствует <i>файл результатов</i> results.abc.</p>
<p>Если задачник не зарегистрирован, то он всегда запускается в демонстрационном режиме
(исключение составляют задания, доступные для выполнения в мини-варианте).
Переключение в демонстрационный режим автоматически происходит также в случае, если в каталоге
с выполняемой программой отсутствует <i>файл результатов</i> results.abc.</p>
<p>В версии 4.8 задачника добавлена возможность генерации текста формулировок учебных заданий и дополнительных пояснений к заданиям в виде html-страницы.
Для создания подобной страницы и ее немедленного отображения на экране (в html-браузере, установленном по умолчанию)
достаточно вызвать процедуру <code>Task</code>, указав в качестве ее параметра имя группы заданий или имя конкретного задания, дополненное
символом &laquo;#&raquo;, например, <code>Begin#</code> или <code>Begin3#</code>.
При указании группы генерируется текст всех заданий, включенных в эту группу.
Процедуру <code>Task</code> с параметром, оканчивающимся символом <code>#</code>,
можно вызывать несколько раз, указывая различные имена групп или конкретных заданий; в результате созданная html-страница
будет содержать тексты всех заданий, указанных при различных запусках процедуры <code>Task</code> (в том же порядке).
<p>В версии 4.8 задачника добавлена возможность генерации текста формулировок учебных заданий и дополнительных пояснений к заданиям в виде html-страницы.
Для создания подобной страницы и ее немедленного отображения на экране (в html-браузере, установленном по умолчанию)
достаточно вызвать процедуру <code>Task</code>, указав в качестве ее параметра имя группы заданий или имя конкретного задания, дополненное
символом &laquo;#&raquo;, например, <code>Begin#</code> или <code>Begin3#</code>.
При указании группы генерируется текст всех заданий, включенных в эту группу.
Процедуру <code>Task</code> с параметром, оканчивающимся символом <code>#</code>,
можно вызывать несколько раз, указывая различные имена групп или конкретных заданий; в результате созданная html-страница
будет содержать тексты всех заданий, указанных при различных запусках процедуры <code>Task</code> (в том же порядке).
</p>
<p>Если при каком-либо вызове будет указано неверное имя группы или неверный номер задания в пределах группы, то выведется сообщение об ошибке,
и html-страница создана не будет.
<p>Если при каком-либо вызове будет указано неверное имя группы или неверный номер задания в пределах группы, то выведется сообщение об ошибке,
и html-страница создана не будет.
</p>
<p>В создаваемую html-страницу включаются стилевые настройки, которые берутся из файла PT4Tasks.css,
который ищется в текущем каталоге, а при его отсутствии в этом каталоге &#151; в подкаталоге PT4 системного
каталога PascalABC.NET. Если данный стилевой файл не найден, то стилевые настройки в html-страницу не добавляются.
<p>В создаваемую html-страницу включаются стилевые настройки, которые берутся из файла PT4Tasks.css,
который ищется в текущем каталоге, а при его отсутствии в этом каталоге &#151; в подкаталоге PT4 системного
каталога PascalABC.NET. Если данный стилевой файл не найден, то стилевые настройки в html-страницу не добавляются.
</p>
<p>При успешной генерации html-страницы она сохраняется в файле со стандартным именем PT4Tasks.html в рабочем каталоге приложения.
Если в этом каталоге нельзя создать файл, то выводится сообщение об ошибке.
<p>При успешной генерации html-страницы она сохраняется в файле со стандартным именем PT4Tasks.html в рабочем каталоге приложения.
Если в этом каталоге нельзя создать файл, то выводится сообщение об ошибке.
</p>
<p>Возможность просмотра html-страниц с описанием текущей группы заданий добавлена и в программный модуль <b>PT4Demo</b>.
Для этого предусмотрена кнопка <img src="gif/demo_3.png"> (см. приведенный выше рисунок) и клавиша <b>F2</b>.
<p>Возможность просмотра html-страниц с описанием текущей группы заданий добавлена и в программный модуль <b>PT4Demo</b>.
Для этого предусмотрена кнопка <img src="gif/demo_3.png"> (см. приведенный выше рисунок) и клавиша <b>F2</b>.
</p>
</body>

View file

@ -9,116 +9,116 @@
<body>
<h1>Группы заданий</h1>
<h1>Группы заданий</h1>
<hr>
<p>Ниже перечислены все базовые группы заданий, включенные в электронный задачник <b>Programming Taskbook</b>
версии&nbsp;4.11 (в&nbsp;скобках указывается количество заданий в данной группе).
<p>Ниже перечислены все базовые группы заданий, включенные в электронный задачник <b>Programming Taskbook</b>
версии&nbsp;4.11 (в&nbsp;скобках указывается количество заданий в данной группе).
<ul>
<li><code>Begin</code> &#151; ввод и вывод данных, оператор присваивания (40),
<li><code>Integer</code> &#151; целые числа (30),
<li><code>For</code> &#151; цикл с параметром (40),
<li><code>Boolean</code> &#151; логические выражения (40),
<li><code>If</code> &#151; условный оператор (30),
<li><code>Case</code> &#151; оператор выбора (20),
<li><code>While</code> &#151; цикл с условием (30),
<li><code>Series</code> &#151; последовательности (40),
<li><code>Proc</code> &#151; процедуры и функции (60),
<li><code>Minmax</code> &#151; минимумы и максимумы (30),
<li><code>Array</code> &#151; одномерные массивы (140),
<li><code>Matrix</code> &#151; двумерные массивы (матрицы) (100),
<li><code>String</code> &#151; символы и строки (70),
<li><code>File</code> &#151; двоичные (типизированные) файлы (90),
<li><code>Text</code> &#151; текстовые файлы (60),
<li><code>Param</code> &#151; составные типы данных в процедурах и функциях (70),
<li><code>Recur</code> &#151; рекурсия (30),
<li><code>Dynamic</code> &#151; динамические структуры данных (80),
<li><code>Tree</code> &#151; деревья (100),
<li><code>ExamBegin</code> &#151; ЕГЭ по информатике: базовые алгоритмы (100),
<li><code>ExamTaskC</code> &#151; ЕГЭ по информатике: задачи повышенной сложности (100).
<li><code>Begin</code> &#151; ввод и вывод данных, оператор присваивания (40),
<li><code>Integer</code> &#151; целые числа (30),
<li><code>For</code> &#151; цикл с параметром (40),
<li><code>Boolean</code> &#151; логические выражения (40),
<li><code>If</code> &#151; условный оператор (30),
<li><code>Case</code> &#151; оператор выбора (20),
<li><code>While</code> &#151; цикл с условием (30),
<li><code>Series</code> &#151; последовательности (40),
<li><code>Proc</code> &#151; процедуры и функции (60),
<li><code>Minmax</code> &#151; минимумы и максимумы (30),
<li><code>Array</code> &#151; одномерные массивы (140),
<li><code>Matrix</code> &#151; двумерные массивы (матрицы) (100),
<li><code>String</code> &#151; символы и строки (70),
<li><code>File</code> &#151; двоичные (типизированные) файлы (90),
<li><code>Text</code> &#151; текстовые файлы (60),
<li><code>Param</code> &#151; составные типы данных в процедурах и функциях (70),
<li><code>Recur</code> &#151; рекурсия (30),
<li><code>Dynamic</code> &#151; динамические структуры данных (80),
<li><code>Tree</code> &#151; деревья (100),
<li><code>ExamBegin</code> &#151; ЕГЭ по информатике: базовые алгоритмы (100),
<li><code>ExamTaskC</code> &#151; ЕГЭ по информатике: задачи повышенной сложности (100).
</ul>
<p>В варианте задачника для системы PascalABC.NET имеются две дополнительные группы ObjDyn и ObjTree,
в содержательном отношении идентичные группам Dynamic и Tree, однако использующие
в формулировках объектную терминологию (группы Dynamic и Tree ориентированы на использование указателей).
<p>В варианте задачника для системы PascalABC.NET имеются две дополнительные группы ObjDyn и ObjTree,
в содержательном отношении идентичные группам Dynamic и Tree, однако использующие
в формулировках объектную терминологию (группы Dynamic и Tree ориентированы на использование указателей).
</p>
<p>Для выполнения заданий из задачника <b>Programming Taskbook</b> к программе необходимо подключить
<a href="IO.html">модуль <code>PT4</code></a>.
<p>Используя <a href="..\MakeModules\tmaker_main.htm"><i>конструктор учебных заданий</i> <b>PT4TaskMaker</b></a>, можно создавать новые группы заданий,
включая в них новые задания или импортируя имеющиеся задания из других групп.
<p>Для выполнения заданий из задачника <b>Programming Taskbook</b> к программе необходимо подключить
<a href="IO.html">модуль <code>PT4</code></a>.
<p>Используя <a href="..\MakeModules\tmaker_main.htm"><i>конструктор учебных заданий</i> <b>PT4TaskMaker</b></a>, можно создавать новые группы заданий,
включая в них новые задания или импортируя имеющиеся задания из других групп.
</p>
<h2>Замечания о формулировках заданий и используемых в них данных</h2></p>
<p>Если о типе исходных или результирующих числовых данных в задании ничего не сказано,
то предполагаются <i>вещественные</i> данные. Исключение составляет группы заданий
Dynamic и Tree (а также ObjDyn и ObjTree),
в которой все числовые данные считаются <i>целыми</i>, и в формулировках заданий это особо не оговаривается.</p>
<p>При обработке наборов <i>вещественных</i> чисел следует предполагать, что все элементы набора
являются <i>различными</i> (таким образом, любой набор вещественных чисел содержит единственный
минимальный и единственный максимальный элемент). В наборах <i>целых</i> чисел могут
присутствовать <i>одинаковые</i> элементы; в частности, наборы целых чисел могут содержать
несколько минимальных и максимальных элементов. Аналогичные предположения справедливы для числовых массивов,
а также для файлов, содержащих числовые данные.</p>
<p>Во всех заданиях на обработку <i>массивов</i> (как одномерных, так и двумерных) начальное значение
любого индекса считается равным&nbsp;1. Если в задании не указан максимальный размер исходных массивов,
то его можно считать равным&nbsp;10 для одномерных и&nbsp;10&nbsp;<font face="Symbol">&#180;</font>&nbsp;10 для двумерных массивов.</p>
<p>При описании элементов одномерных и двумерных массивов используется понятие <i>порядкового
номера элемента</i>, причем начальный элемент массива <i>A</i> размера <i>N</i> всегда имеет порядковый
номер&nbsp;1 и обозначается в формулировках заданий как <i>A</i><sub>1</sub>, а конечный элемент этого же
массива имеет порядковый номер&nbsp;<i>N</i> и обозначается как <i>A</i><sub><i>N</i></sub>. Аналогично,
начальный элемент двумерного массива <i>B</i> обозначается как <i>B</i><sub>1,1</sub>. Кроме того,
понятие порядкового номера применяется к <i>строкам</i> и <i>столбцам</i> двумерных массивов (матриц):
начальная строка и начальный столбец матрицы размера <i>M</i>&nbsp;&#215;&nbsp;<i>N</i> имеют порядковый номер&nbsp;1,
конечная строка &#151; номер&nbsp;<i>M</i>, а конечный столбец &#151; номер&nbsp;<i>N</i>. Подобный подход
не зависит от выбора языка программирования и соответствует традиционно используемой в математике
нумерации элементов векторов и матриц.</p>
<p>Максимальный размер исходных <i>файлов</i> не указывается, поэтому при решении заданий на файлы не следует
использовать вспомогательные массивы, содержащие все элементы исходных файлов, однако допускается
использование <i>вспомогательных файлов</i>. Все исходные файлы считаются существующими, за исключением
специально оговоренных случаев, в которых существование исходных файлов требуется проверять
в ходе выполнения задания.</p>
<p>Под <i>размером</i> двоичного типизированного файла всегда подразумевается количество
содержащихся в нем <i>элементов</i> указанного типа (а не количество байтов, как это принято
в операционной системе). В формулировках заданий предполагается, что элементы двоичных файлов,
как и элементы массивов, нумеруются от&nbsp;1.</p>
<h2>Замечания о формулировках заданий и используемых в них данных</h2></p>
<p>Если о типе исходных или результирующих числовых данных в задании ничего не сказано,
то предполагаются <i>вещественные</i> данные. Исключение составляет группы заданий
Dynamic и Tree (а также ObjDyn и ObjTree),
в которой все числовые данные считаются <i>целыми</i>, и в формулировках заданий это особо не оговаривается.</p>
<p>При обработке наборов <i>вещественных</i> чисел следует предполагать, что все элементы набора
являются <i>различными</i> (таким образом, любой набор вещественных чисел содержит единственный
минимальный и единственный максимальный элемент). В наборах <i>целых</i> чисел могут
присутствовать <i>одинаковые</i> элементы; в частности, наборы целых чисел могут содержать
несколько минимальных и максимальных элементов. Аналогичные предположения справедливы для числовых массивов,
а также для файлов, содержащих числовые данные.</p>
<p>Во всех заданиях на обработку <i>массивов</i> (как одномерных, так и двумерных) начальное значение
любого индекса считается равным&nbsp;1. Если в задании не указан максимальный размер исходных массивов,
то его можно считать равным&nbsp;10 для одномерных и&nbsp;10&nbsp;<font face="Symbol">&#180;</font>&nbsp;10 для двумерных массивов.</p>
<p>При описании элементов одномерных и двумерных массивов используется понятие <i>порядкового
номера элемента</i>, причем начальный элемент массива <i>A</i> размера <i>N</i> всегда имеет порядковый
номер&nbsp;1 и обозначается в формулировках заданий как <i>A</i><sub>1</sub>, а конечный элемент этого же
массива имеет порядковый номер&nbsp;<i>N</i> и обозначается как <i>A</i><sub><i>N</i></sub>. Аналогично,
начальный элемент двумерного массива <i>B</i> обозначается как <i>B</i><sub>1,1</sub>. Кроме того,
понятие порядкового номера применяется к <i>строкам</i> и <i>столбцам</i> двумерных массивов (матриц):
начальная строка и начальный столбец матрицы размера <i>M</i>&nbsp;&#215;&nbsp;<i>N</i> имеют порядковый номер&nbsp;1,
конечная строка &#151; номер&nbsp;<i>M</i>, а конечный столбец &#151; номер&nbsp;<i>N</i>. Подобный подход
не зависит от выбора языка программирования и соответствует традиционно используемой в математике
нумерации элементов векторов и матриц.</p>
<p>Максимальный размер исходных <i>файлов</i> не указывается, поэтому при решении заданий на файлы не следует
использовать вспомогательные массивы, содержащие все элементы исходных файлов, однако допускается
использование <i>вспомогательных файлов</i>. Все исходные файлы считаются существующими, за исключением
специально оговоренных случаев, в которых существование исходных файлов требуется проверять
в ходе выполнения задания.</p>
<p>Под <i>размером</i> двоичного типизированного файла всегда подразумевается количество
содержащихся в нем <i>элементов</i> указанного типа (а не количество байтов, как это принято
в операционной системе). В формулировках заданий предполагается, что элементы двоичных файлов,
как и элементы массивов, нумеруются от&nbsp;1.</p>
</p>
<a name="exam"></a>
<h2>Задания, связанные с ЕГЭ по информатике
<h2>Задания, связанные с ЕГЭ по информатике
</h2>
<p>Начиная с версии 4.10, задачник Programming Taskbook включает набор групп заданий, связанных с ЕГЭ по информатике
и ИКТ. Эти группы начинаются с префикса Exam; они доступны для программных сред языков
Pascal (в том числе PascalABC.NET) и C++.
<p>Начиная с версии 4.10, задачник Programming Taskbook включает набор групп заданий, связанных с ЕГЭ по информатике
и ИКТ. Эти группы начинаются с префикса Exam; они доступны для программных сред языков
Pascal (в том числе PascalABC.NET) и C++.
</p>
<p>В базовый набор заданий включены две группы Exam: группа ExamBegin,
содержащая задания на освоение базовых алгоритмов, включенных в кодификатор ЕГЭ по информатике и ИКТ,
и группа ExamTaskC, содержащая типовые задания повышенного уровня
сложности, включенных в ЕГЭ в качестве заданий группы С. Каждая из групп состоит из 100 учебных заданий;
20 заданий каждой группы доступны для выполнения в <a href="About.html#mini">мини-варианте задачника</a>.
<p>В базовый набор заданий включены две группы Exam: группа ExamBegin,
содержащая задания на освоение базовых алгоритмов, включенных в кодификатор ЕГЭ по информатике и ИКТ,
и группа ExamTaskC, содержащая типовые задания повышенного уровня
сложности, включенных в ЕГЭ в качестве заданий группы С. Каждая из групп состоит из 100 учебных заданий;
20 заданий каждой группы доступны для выполнения в <a href="About.html#mini">мини-варианте задачника</a>.
</p>
<p>Особенностью групп Exam является то, что при их выполнении не требуется использовать специальные
средства ввода-вывода, входящие в задачник. Для того чтобы максимально приблизить вид программы,
выполняющей задание, к виду, требуемому на экзамене, в задачнике реализован специальный механизм,
позволяющий оформлять ввод-вывод данных с применением <i>стандартных средств используемого языка
программирования</i>: процедур Read/Readln-Write/Writeln для языка Pascal и стандартных потоков
ввода-вывода cin-cout для языка C++.
<p>Особенностью групп Exam является то, что при их выполнении не требуется использовать специальные
средства ввода-вывода, входящие в задачник. Для того чтобы максимально приблизить вид программы,
выполняющей задание, к виду, требуемому на экзамене, в задачнике реализован специальный механизм,
позволяющий оформлять ввод-вывод данных с применением <i>стандартных средств используемого языка
программирования</i>: процедур Read/Readln-Write/Writeln для языка Pascal и стандартных потоков
ввода-вывода cin-cout для языка C++.
</p>
<p>При использовании заданий групп Exam сохраняются основные особенности задачника: автоматическое предоставление
программе учащегося исходных данных и автоматическая проверка правильности предложенного решения.
Следует отметить, что эти особенности оказываются наиболее полезными при решении задач повышенной
сложности (группа ExamTaskC), так как в них, как правило,
должны использоваться наборы исходных данных большого размера.
<p>При использовании заданий групп Exam сохраняются основные особенности задачника: автоматическое предоставление
программе учащегося исходных данных и автоматическая проверка правильности предложенного решения.
Следует отметить, что эти особенности оказываются наиболее полезными при решении задач повышенной
сложности (группа ExamTaskC), так как в них, как правило,
должны использоваться наборы исходных данных большого размера.
</p>
<p>При выполнении заданий групп Exam учащийся должен обеспечивать надлежащее <i>форматирование</i> выходных данных
(в других группах заданий это не требуется, поскольку
средства вывода электронного задачника выполняют форматирование автоматически).
<p>При выполнении заданий групп Exam учащийся должен обеспечивать надлежащее <i>форматирование</i> выходных данных
(в других группах заданий это не требуется, поскольку
средства вывода электронного задачника выполняют форматирование автоматически).
</p>
<p>Отказ от использовании специальных средств ввода-вывода приводит к тому, что любые ошибки ввода-вывода
уже не обрабатываются задачником и обычно приводят к сообщениям об ошибке времени выполнения.
Это обстоятельство несколько затрудняет поиск ошибок, но в то же время
позволяет приблизить его к реальному процессу отладки программы, не использующему &laquo;подсказки&raquo;
задачника.
<p>Отказ от использовании специальных средств ввода-вывода приводит к тому, что любые ошибки ввода-вывода
уже не обрабатываются задачником и обычно приводят к сообщениям об ошибке времени выполнения.
Это обстоятельство несколько затрудняет поиск ошибок, но в то же время
позволяет приблизить его к реальному процессу отладки программы, не использующему &laquo;подсказки&raquo;
задачника.
</p>

View file

@ -36,14 +36,14 @@
</head>
<body>
<h1>Модуль PT4</h1>
<h1>Модуль PT4</h1>
<hr>
<p>Описанные в данном разделе типы и процедуры
будут доступны в программе, если к ней с помощью оператора <code><b>uses</b></code>
подключен модуль <code>PT4</code> (см. <a href="..\CheckedTasks\checkedtasks1.htm">пример</a> программы, использующей задачник
<p>Описанные в данном разделе типы и процедуры
будут доступны в программе, если к ней с помощью оператора <code><b>uses</b></code>
подключен модуль <code>PT4</code> (см. <a href="..\CheckedTasks\checkedtasks1.htm">пример</a> программы, использующей задачник
<b>Programming Taskbook</b>).
<a name="node"></a><h2>Дополнительные типы данных PNode и TNode</h2>
<a name="node"></a><h2>Дополнительные типы данных PNode и TNode</h2>
<hr noshade size="1">
<blockquote>
<code><b>type</b><br>
@ -58,62 +58,62 @@
&nbsp; <b>end</b>;
</code></blockquote>
<p>Типы <code>PNode</code> и <code>TNode</code> используются в заданиях групп Dynamic и Tree. В заданиях на стеки и очереди
(Dynamic1&#150;Dynamic28) при работе с записями типа <code>TNode</code> используются только поля <code>Data</code> и <code>Next</code>;
в заданиях на двусвязные списки (Dynamic29&#150;Dynamic80) используются поля <code>Data</code>, <code>Next</code> и <code>Prev</code>.
В большинстве заданий на бинарные деревья (группа Tree) используются поля <code>Data</code>, <code>Left</code> и <code>Right</code>;
в заданиях на обработку бинарных деревьев с обратной связью (Tree48&#150;Tree56 и Tree70&#150;Tree71) дополнительно используется
поле <code>Parent</code>.
<p>Типы <code>PNode</code> и <code>TNode</code> используются в заданиях групп Dynamic и Tree. В заданиях на стеки и очереди
(Dynamic1&#150;Dynamic28) при работе с записями типа <code>TNode</code> используются только поля <code>Data</code> и <code>Next</code>;
в заданиях на двусвязные списки (Dynamic29&#150;Dynamic80) используются поля <code>Data</code>, <code>Next</code> и <code>Prev</code>.
В большинстве заданий на бинарные деревья (группа Tree) используются поля <code>Data</code>, <code>Left</code> и <code>Right</code>;
в заданиях на обработку бинарных деревьев с обратной связью (Tree48&#150;Tree56 и Tree70&#150;Tree71) дополнительно используется
поле <code>Parent</code>.
</p>
<p>Все исходные и результирующие данные-указатели в заданиях имеют тип <code>PNode</code>;
их ввод и вывод должен осуществляться с помощью процедур <code>GetP</code> и <code>PutP</code> (в системе <b>PascalABC.NET</b>
указатели, как и другие данные,
можно получать из задачника и передавать ему с помощью стандартных процедур ввода-вывода <code>read</code>
и <code>write</code>).
<p>Все исходные и результирующие данные-указатели в заданиях имеют тип <code>PNode</code>;
их ввод и вывод должен осуществляться с помощью процедур <code>GetP</code> и <code>PutP</code> (в системе <b>PascalABC.NET</b>
указатели, как и другие данные,
можно получать из задачника и передавать ему с помощью стандартных процедур ввода-вывода <code>read</code>
и <code>write</code>).
</p>
<p>В программе учащегося не следует повторно описывать типы <code>PNode</code> и <code>TNode</code>.
<p>В программе учащегося не следует повторно описывать типы <code>PNode</code> и <code>TNode</code>.
</p>
<h2>Инициализация задания, ввод&#150;вывод данных</h2>
<h2>Инициализация задания, ввод&#150;вывод данных</h2>
<a name="task"></a><hr noshade size="1">
<blockquote>
<code><b>procedure</b> Task(Name: <b>string</b>);
</code></blockquote>
<p>Процедура инициализирует задание с именем <code>Name</code>. Она должна
вызываться в начале программы, выполняющей это задание (до вызова
процедур ввода-вывода). Если в программе, подключившей
модуль <code>PT4</code>, не указана процедура <code>Task</code>, то при запуске программы
будет выведено окно с сообщением &laquo;<i>Не вызвана процедура Task с
именем задания</i>&raquo;.</p>
<p>Процедура инициализирует задание с именем <code>Name</code>. Она должна
вызываться в начале программы, выполняющей это задание (до вызова
процедур ввода-вывода). Если в программе, подключившей
модуль <code>PT4</code>, не указана процедура <code>Task</code>, то при запуске программы
будет выведено окно с сообщением &laquo;<i>Не вызвана процедура Task с
именем задания</i>&raquo;.</p>
<p>
Имя задания <code>Name</code> должно включать имя темы и порядковый
номер в пределах темы (например, <code>'Begin3'</code>). Регистр букв в имени темы
может быть произвольным. Если указана неверная тема задания, то
программа выведет сообщение об ошибке, в котором будут
перечислены названия всех имеющихся тем. Если указан
недопустимый номер задания, то программа выведет сообщение, в
котором будет указан диапазон допустимых номеров для данной темы.
Если после имени задания в параметре <code>Name</code> указан символ <code>?</code>
(например, <code>'Begin1?'</code>), то программа будет работать в
<a href="Demo.html"><i>демонстрационном режиме</i></a>.
Имя задания <code>Name</code> должно включать имя темы и порядковый
номер в пределах темы (например, <code>'Begin3'</code>). Регистр букв в имени темы
может быть произвольным. Если указана неверная тема задания, то
программа выведет сообщение об ошибке, в котором будут
перечислены названия всех имеющихся тем. Если указан
недопустимый номер задания, то программа выведет сообщение, в
котором будет указан диапазон допустимых номеров для данной темы.
Если после имени задания в параметре <code>Name</code> указан символ <code>?</code>
(например, <code>'Begin1?'</code>), то программа будет работать в
<a href="Demo.html"><i>демонстрационном режиме</i></a>.
</p>
<p>Начиная с версии 4.8, процедура <code>Task</code> может также использоваться для
генерации и вывода на экран html-страницы с текстом задания или группы заданий.
Для этого необходимо указать в качестве параметра <code>Name</code> имя конкретного задания или группы
заданий и символ <code>#</code>, например, <code>'Begin3#'</code> или
<code>'Begin#'</code>. Дополнительные сведения о генерации html-страниц с описаниями заданий приводятся
в разделе, посвященном демонстрационному режиму задачника.
<p>Начиная с версии 4.8, процедура <code>Task</code> может также использоваться для
генерации и вывода на экран html-страницы с текстом задания или группы заданий.
Для этого необходимо указать в качестве параметра <code>Name</code> имя конкретного задания или группы
заданий и символ <code>#</code>, например, <code>'Begin3#'</code> или
<code>'Begin#'</code>. Дополнительные сведения о генерации html-страниц с описаниями заданий приводятся
в разделе, посвященном демонстрационному режиму задачника.
</p>
<p>Если при первом вызове процедуры <code>Task</code> в параметре не указывается символ <code>#</code>, то
все последующие вызовы процедуры <code>Task</code> игнорируются. Если при первом вызове процедуры
<code>Task</code> в параметре указывается символ <code>#</code>,
то игнорируются все последующие вызовы процедуры <code>Task</code>, не содержащие этот символ.
С помощью нескольких вызовов процедуры <code>Task</code>, содержащей в параметре символ <code>#</code>, можно обеспечить
генерацию html-страницы с описанием нескольких групп заданий, причем в каждой группе при этом можно отображать только
некоторые задания.
<p>Если при первом вызове процедуры <code>Task</code> в параметре не указывается символ <code>#</code>, то
все последующие вызовы процедуры <code>Task</code> игнорируются. Если при первом вызове процедуры
<code>Task</code> в параметре указывается символ <code>#</code>,
то игнорируются все последующие вызовы процедуры <code>Task</code>, не содержащие этот символ.
С помощью нескольких вызовов процедуры <code>Task</code>, содержащей в параметре символ <code>#</code>, можно обеспечить
генерацию html-страницы с описанием нескольких групп заданий, причем в каждой группе при этом можно отображать только
некоторые задания.
</p>
<hr noshade size="1">
@ -127,26 +127,26 @@
<b>procedure</b> GetP(<b>var</b> X: PNode);<br>
</code></blockquote>
<p>
Процедуры обеспечивают ввод исходных данных в программу,
выполняющую учебное задание. Они должны вызываться после вызова
процедуры <code>Task</code>;
в случае их вызова до вызова процедуры <code>Task</code> при запуске программы
будет выведено сообщение об ошибке &laquo;<i>В начале программы не
вызвана процедура Task с именем задания</i>&raquo;.</p>
Процедуры обеспечивают ввод исходных данных в программу,
выполняющую учебное задание. Они должны вызываться после вызова
процедуры <code>Task</code>;
в случае их вызова до вызова процедуры <code>Task</code> при запуске программы
будет выведено сообщение об ошибке &laquo;<i>В начале программы не
вызвана процедура Task с именем задания</i>&raquo;.</p>
<p>Используемая процедура ввода должна соответствовать типу
очередного элемента исходных данных; в противном случае выводится
сообщение об ошибке &laquo;<i>Неверно указан тип при вводе исходных
данных</i>&raquo; (такое сообщение будет выведено, например, если очередной
элемент данных является символом, а для его ввода используется
процедура <code>GetN</code>).</p>
<p>При попытке ввести больше исходных данных, чем это
предусмотрено в задании, выводится сообщение об ошибке &laquo;<i>Попытка
ввести лишние исходные данные</i>&raquo;. Если исходные данные,
необходимые для решения задания, введены не полностью, то
выводится сообщение &laquo;<i>Введены не все требуемые исходные данные</i>&raquo;.</p>
<p>При использовании задачника в системе <b>PascalABC.NET</b> вместо процедур группы <code>Get</code>
можно использовать обычные процедуры ввода <code>read</code>.
<p>Используемая процедура ввода должна соответствовать типу
очередного элемента исходных данных; в противном случае выводится
сообщение об ошибке &laquo;<i>Неверно указан тип при вводе исходных
данных</i>&raquo; (такое сообщение будет выведено, например, если очередной
элемент данных является символом, а для его ввода используется
процедура <code>GetN</code>).</p>
<p>При попытке ввести больше исходных данных, чем это
предусмотрено в задании, выводится сообщение об ошибке &laquo;<i>Попытка
ввести лишние исходные данные</i>&raquo;. Если исходные данные,
необходимые для решения задания, введены не полностью, то
выводится сообщение &laquo;<i>Введены не все требуемые исходные данные</i>&raquo;.</p>
<p>При использовании задачника в системе <b>PascalABC.NET</b> вместо процедур группы <code>Get</code>
можно использовать обычные процедуры ввода <code>read</code>.
<hr noshade size="1">
<blockquote>
@ -159,52 +159,52 @@
<b>procedure</b> PutP(X: PNode);<br>
</code></blockquote>
<p>
Процедуры обеспечивают вывод на экран результирующих
данных, найденных программой, и их сравнение с <i>контрольными
данными</i> (то есть с правильным решением). Как и процедуры группы
<code>Get</code>, эти процедуры должны вызываться после вызова процедуры <code>Task</code>;
в противном случае при запуске программы будет выведено сообщение
об ошибке «<i>В начале программы не вызвана процедура Task
с именем задания</i>».</p>
<p>В отличие от процедур группы <code>Get</code>, в качестве параметра процедур
группы <code>Put</code> можно указывать не только переменные, но и <i>выражения</i>
частности, <i>константы</i> соответствующего типа). Используемая
процедура должна соответствовать типу очередного элемента
результирующих данных, в противном случае выводится сообщение об
ошибке «<i>Неверно указан тип при выводе результатов</i>».</p>
<p>Как и в случае процедур группы <code>Get</code>, при вызовах процедур
группы <code>Put</code> программа осуществляет контроль за соответствием
количества требуемых и выведенных результирующих данных. Если
программа выведет недостаточное или избыточное количество
результирующих данных, то после проверки этих данных появится
сообщение «<i>Выведены не все результирующие данные</i>» или,
соответственно, «<i>Попытка вывести лишние результирующие данные</i>».
<p>При использовании задачника в системе <b>PascalABC.NET</b> вместо процедур группы <code>Put</code>
можно использовать обычные процедуры вывода <code>write</code>.
Процедуры обеспечивают вывод на экран результирующих
данных, найденных программой, и их сравнение с <i>контрольными
данными</i> (то есть с правильным решением). Как и процедуры группы
<code>Get</code>, эти процедуры должны вызываться после вызова процедуры <code>Task</code>;
в противном случае при запуске программы будет выведено сообщение
об ошибке «<i>В начале программы не вызвана процедура Task
с именем задания</i>».</p>
<p>В отличие от процедур группы <code>Get</code>, в качестве параметра процедур
группы <code>Put</code> можно указывать не только переменные, но и <i>выражения</i>
частности, <i>константы</i> соответствующего типа). Используемая
процедура должна соответствовать типу очередного элемента
результирующих данных, в противном случае выводится сообщение об
ошибке «<i>Неверно указан тип при выводе результатов</i>».</p>
<p>Как и в случае процедур группы <code>Get</code>, при вызовах процедур
группы <code>Put</code> программа осуществляет контроль за соответствием
количества требуемых и выведенных результирующих данных. Если
программа выведет недостаточное или избыточное количество
результирующих данных, то после проверки этих данных появится
сообщение «<i>Выведены не все результирующие данные</i>» или,
соответственно, «<i>Попытка вывести лишние результирующие данные</i>».
<p>При использовании задачника в системе <b>PascalABC.NET</b> вместо процедур группы <code>Put</code>
можно использовать обычные процедуры вывода <code>write</code>.
<hr noshade size="1">
<blockquote>
<code>
<b>procedure</b> Dispose(<b>var</b> P: PNode);
</code></blockquote>
<p>
Данная процедура переопределяет стандартную процедуру <code>Dispose</code> для того, чтобы
контролировать действия учащегося по освобождению памяти при выполнении заданий групп Dynamic и Tree.</p>
Данная процедура переопределяет стандартную процедуру <code>Dispose</code> для того, чтобы
контролировать действия учащегося по освобождению памяти при выполнении заданий групп Dynamic и Tree.</p>
<h2>Класс Node и альтернативный ввод&#150;вывод в стиле .NET</h2>
<h2>Класс Node и альтернативный ввод&#150;вывод в стиле .NET</h2>
<p>В варианте задачника <b>Programming Taskbook</b>, включенном в систему <b>PascalABC.NET</b>, предусмотрен
альтернативный способ организации ввода-вывода, характерный не для традиционного Паскаля,
а для языков платформы .NET. Наличие двух способов ввода-вывода обусловлено тем обстоятельством, что
система <b>PascalABC.NET</b> позволяет разрабатывать программы как в стиле, характерном для
традиционного Паскаля, так и в .NET-стиле, ориентированном на использование стандартных средств платформы
.NET, в том числе ее библиотеки классов.
<p>В варианте задачника <b>Programming Taskbook</b>, включенном в систему <b>PascalABC.NET</b>, предусмотрен
альтернативный способ организации ввода-вывода, характерный не для традиционного Паскаля,
а для языков платформы .NET. Наличие двух способов ввода-вывода обусловлено тем обстоятельством, что
система <b>PascalABC.NET</b> позволяет разрабатывать программы как в стиле, характерном для
традиционного Паскаля, так и в .NET-стиле, ориентированном на использование стандартных средств платформы
.NET, в том числе ее библиотеки классов.
</p>
<p>Кроме новых средств ввода-вывода в варианте задачника для системы <b>PascalABC.NET</b> предусмотрен
класс <code>Node</code>, который следует использовать вместо типов <code>PNode</code> и <code>TNode</code> при
выполнении заданий на динамические структуры &laquo;в объектном стиле&raquo;. Заметим, что в этом случае
необходимо пользоваться группами ObjDyn и ObjTree, в которых (в отличие от групп Dynamic и Tree)
применяется &laquo;объектная&raquo; терминология, ориентированная на применение классов платформы .NET.
<p>Кроме новых средств ввода-вывода в варианте задачника для системы <b>PascalABC.NET</b> предусмотрен
класс <code>Node</code>, который следует использовать вместо типов <code>PNode</code> и <code>TNode</code> при
выполнении заданий на динамические структуры &laquo;в объектном стиле&raquo;. Заметим, что в этом случае
необходимо пользоваться группами ObjDyn и ObjTree, в которых (в отличие от групп Dynamic и Tree)
применяется &laquo;объектная&raquo; терминология, ориентированная на применение классов платформы .NET.
</p>
<hr noshade size="1">
@ -214,49 +214,49 @@
&nbsp; Node = <b>class</b>(IDisposable)<br>
&nbsp;&nbsp;. . .<br>
&nbsp;&nbsp;<b>public</b><br>
&nbsp;&nbsp;// <i>Конструкторы:</i><br>
&nbsp;&nbsp;// <i>Конструкторы:</i><br>
&nbsp; &nbsp; <b>constructor</b> Create;<br>
&nbsp; &nbsp; <b>constructor</b> Create(aData: integer);<br>
&nbsp; &nbsp; <b>constructor</b> Create(aData: integer; aNext: Node);<br>
&nbsp; &nbsp; <b>constructor</b> Create(aData: integer; aNext, aPrev: Node);<br>
&nbsp; &nbsp; <b>constructor</b> Create(aLeft, aRight: Node; aData: integer);<br>
&nbsp; &nbsp; <b>constructor</b> Create(aLeft, aRight: Node; aData: integer; aParent: Node);<br>
&nbsp;&nbsp;// <i>Свойства (доступны для чтения и записи):</i><br>
&nbsp;&nbsp;// <i>Свойства (доступны для чтения и записи):</i><br>
&nbsp; &nbsp; <b>property</b> Data: integer;<br>
&nbsp; &nbsp; <b>property</b> Next: Node;<br>
&nbsp; &nbsp; <b>property</b> Prev: Node;<br>
&nbsp; &nbsp; <b>property</b> Left: Node;<br>
&nbsp; &nbsp; <b>property</b> Right: Node;<br>
&nbsp; &nbsp; <b>property</b> Parent: Node;<br>
&nbsp;&nbsp;// <i>Метод, освобождающий ресурсы, используемые объектом Node:</i><br>
&nbsp;&nbsp;// <i>Метод, освобождающий ресурсы, используемые объектом Node:</i><br>
&nbsp; &nbsp; <b>procedure</b> Dispose;<br>
&nbsp; <b>end</b>;
</code></blockquote>
<p>Класс <code>Node</code> используется в заданиях групп ObjDyn и ObjTree. В заданиях на
стеки и очереди (ObjDyn1&#150;ObjDyn28) при работе с объектами типа <code>Node</code>
используются только свойства <code>Data</code> и <code>Next</code>; в заданиях на двусвязные списки
(ObjDyn29&#150;ObjDyn80) используются свойства <code>Data</code>, <code>Next</code> и <code>Prev</code>. В большинстве заданий на
бинарные деревья (группа ObjTree) используются свойства <code>Data</code>, <code>Left</code> и <code>Right</code>;
в заданиях на обработку бинарных деревьев с обратной связью
(ObjTree48&#150;ObjTree56 и ObjTree70&#150;ObjTree71) дополнительно используется свойство <code>Parent</code>.
<p>Класс <code>Node</code> используется в заданиях групп ObjDyn и ObjTree. В заданиях на
стеки и очереди (ObjDyn1&#150;ObjDyn28) при работе с объектами типа <code>Node</code>
используются только свойства <code>Data</code> и <code>Next</code>; в заданиях на двусвязные списки
(ObjDyn29&#150;ObjDyn80) используются свойства <code>Data</code>, <code>Next</code> и <code>Prev</code>. В большинстве заданий на
бинарные деревья (группа ObjTree) используются свойства <code>Data</code>, <code>Left</code> и <code>Right</code>;
в заданиях на обработку бинарных деревьев с обратной связью
(ObjTree48&#150;ObjTree56 и ObjTree70&#150;ObjTree71) дополнительно используется свойство <code>Parent</code>.
</p>
<p>Варианты конструктора класса <code>Node</code> позволяют задавать значения требуемых свойств при создании
объекта; прочие свойства инициализируются нулевыми значениями
(числом&nbsp;0 для свойства <code>Data</code>, нулевой ссылкой <code>nil</code> для остальных свойств).
<p>Варианты конструктора класса <code>Node</code> позволяют задавать значения требуемых свойств при создании
объекта; прочие свойства инициализируются нулевыми значениями
(числом&nbsp;0 для свойства <code>Data</code>, нулевой ссылкой <code>nil</code> для остальных свойств).
</p>
<p>Следует обратить внимание на то, что данный класс реализует интерфейс
<code>IDisposable</code>, поэтому при завершении работы с объектом типа <code>Node</code> требуется вызвать
его метод <code>Dispose</code>, освобождающий <i>неуправляемые ресурсы</i>, выделенные для этого
объекта (исключение делается только для тех объектов, которые передаются обратно
задачнику в качестве результирующих данных). Если в задании требуется вызвать
метод <code>Dispose</code> для некоторых объектов, но этот вызов не выполняется, то при запуске
программы выводится сообщение об ошибке &laquo;<i>Не вызван метод Dispose для
объекта типа Node</i>&raquo;.
<p>Следует обратить внимание на то, что данный класс реализует интерфейс
<code>IDisposable</code>, поэтому при завершении работы с объектом типа <code>Node</code> требуется вызвать
его метод <code>Dispose</code>, освобождающий <i>неуправляемые ресурсы</i>, выделенные для этого
объекта (исключение делается только для тех объектов, которые передаются обратно
задачнику в качестве результирующих данных). Если в задании требуется вызвать
метод <code>Dispose</code> для некоторых объектов, но этот вызов не выполняется, то при запуске
программы выводится сообщение об ошибке &laquo;<i>Не вызван метод Dispose для
объекта типа Node</i>&raquo;.
</p>
<p>Все исходные и результирующие данные-ссылки в заданиях группы ObjDyn и ObjTree
имеют тип <code>Node</code>; их ввод и вывод должен осуществляться с помощью функции
<code>GetNode</code> и процедуры <code>Put</code>, описанных ниже.
<p>Все исходные и результирующие данные-ссылки в заданиях группы ObjDyn и ObjTree
имеют тип <code>Node</code>; их ввод и вывод должен осуществляться с помощью функции
<code>GetNode</code> и процедуры <code>Put</code>, описанных ниже.
</p>
<hr noshade size="1">
@ -270,91 +270,91 @@
<b>function</b> GetString: string;<br>
</code></blockquote>
<p>Функции обеспечивают ввод исходных данных в программу,
выполняющую учебное задание, причем ввод организуется в стиле,
характерном для платформы .NET (поскольку
в стандартной библиотеке .NET ввод данных <i>всегда</i> выполняется с помощью функций).
Эти функции должны вызываться после вызова процедуры <code>Task</code>;
в случае их вызова до вызова процедуры <code>Task</code> при запуске программы будет выведено
сообщение об ошибке &laquo;<i>В начале программы не вызвана процедура Task с
именем задания</i>&raquo;.
<p>Функции обеспечивают ввод исходных данных в программу,
выполняющую учебное задание, причем ввод организуется в стиле,
характерном для платформы .NET (поскольку
в стандартной библиотеке .NET ввод данных <i>всегда</i> выполняется с помощью функций).
Эти функции должны вызываться после вызова процедуры <code>Task</code>;
в случае их вызова до вызова процедуры <code>Task</code> при запуске программы будет выведено
сообщение об ошибке &laquo;<i>В начале программы не вызвана процедура Task с
именем задания</i>&raquo;.
</p>
<p>Используемая функция ввода должна соответствовать типу очередного элемента
исходных данных; в противном случае выводится сообщение об ошибке
&laquo;<i>Неверно указан тип при вводе исходных данных</i>&raquo; (такое сообщение
будет выведено, например, если очередной элемент данных является символом, а для
его ввода используется функция <code>GetInt</code>).
<p>Используемая функция ввода должна соответствовать типу очередного элемента
исходных данных; в противном случае выводится сообщение об ошибке
&laquo;<i>Неверно указан тип при вводе исходных данных</i>&raquo; (такое сообщение
будет выведено, например, если очередной элемент данных является символом, а для
его ввода используется функция <code>GetInt</code>).
</p>
<p>При попытке ввести больше исходных данных, чем это предусмотрено в
задании, выводится сообщение об ошибке &laquo;<i>Попытка ввести лишние исходные
данные</i>&raquo;. Если исходные данные, необходимые для решения задания, введены
не полностью, то выводится сообщение &laquo;<i>Введены не все требуемые исходные
данные</i>&raquo;.
<p>При попытке ввести больше исходных данных, чем это предусмотрено в
задании, выводится сообщение об ошибке &laquo;<i>Попытка ввести лишние исходные
данные</i>&raquo;. Если исходные данные, необходимые для решения задания, введены
не полностью, то выводится сообщение &laquo;<i>Введены не все требуемые исходные
данные</i>&raquo;.
</p>
<hr noshade size="1">
<blockquote>
<code>
<b>procedure</b> Put(<b>params</b> A: <b>array of</b> object);
</code></blockquote>
<p>Процедура <code>Put</code> обеспечивает вывод на экран результирующих данных, найденных
программой, и их сравнение с <i>контрольными данными</i> (то есть с правильным
решением). Как и описанные выше функции группы <code>Get</code>, процедура <code>Put</code> должна вызываться после вызова
процедуры <code>Task</code>; в противном случае при запуске программы будет выведено сообщение
об ошибке &laquo;<i>В начале программы не вызвана процедура Task с именем
задания</i>&raquo;.
<p>Процедура <code>Put</code> обеспечивает вывод на экран результирующих данных, найденных
программой, и их сравнение с <i>контрольными данными</i> (то есть с правильным
решением). Как и описанные выше функции группы <code>Get</code>, процедура <code>Put</code> должна вызываться после вызова
процедуры <code>Task</code>; в противном случае при запуске программы будет выведено сообщение
об ошибке &laquo;<i>В начале программы не вызвана процедура Task с именем
задания</i>&raquo;.
</p>
<p>Благодаря использованию параметра-массива, снабженного атрибутом <code><b>params</b></code>,
при вызове процедуры <code>Put</code> можно указывать <i>произвольное</i> число параметров. Параметры
могут иметь тип <code>boolean</code>, <code>integer</code>, <code>real</code>, <code>char</code>, <code>string</code>, <code>Node</code>.
В качестве параметров процедуры <code>Put</code>
можно указывать не только переменные, но и <i>выражения</i> (в частности, <i>константы</i>
соответствующего типа, а также <i>нулевую ссылку</i> <code>nil</code>. Заметим, что нулевые ссылки, как и объекты типа <code>Node</code>, требуется
выводить только в заданиях групп ObjDyn и ObjTree. Если в списке параметров указываются
параметры недопустимого типа, то при выполнении программы выводится
сообщение об ошибке &laquo;<i>В методе Put указан параметр недопустимого
типа</i>&raquo;.
<p>Благодаря использованию параметра-массива, снабженного атрибутом <code><b>params</b></code>,
при вызове процедуры <code>Put</code> можно указывать <i>произвольное</i> число параметров. Параметры
могут иметь тип <code>boolean</code>, <code>integer</code>, <code>real</code>, <code>char</code>, <code>string</code>, <code>Node</code>.
В качестве параметров процедуры <code>Put</code>
можно указывать не только переменные, но и <i>выражения</i> (в частности, <i>константы</i>
соответствующего типа, а также <i>нулевую ссылку</i> <code>nil</code>. Заметим, что нулевые ссылки, как и объекты типа <code>Node</code>, требуется
выводить только в заданиях групп ObjDyn и ObjTree. Если в списке параметров указываются
параметры недопустимого типа, то при выполнении программы выводится
сообщение об ошибке &laquo;<i>В методе Put указан параметр недопустимого
типа</i>&raquo;.
</p>
<p>Тип параметра должен не только быть допустимым, но и соответствовать типу
очередного элемента результирующих данных; в противном случае выводится
сообщение об ошибке &laquo;<i>Неверно указан тип при выводе результатов</i>&raquo;.
<p>Тип параметра должен не только быть допустимым, но и соответствовать типу
очередного элемента результирующих данных; в противном случае выводится
сообщение об ошибке &laquo;<i>Неверно указан тип при выводе результатов</i>&raquo;.
</p>
<p>Как и в случае функций группы <code>Get</code>, при вызовах процедуры <code>Put</code> программа
осуществляет контроль за соответствием количества требуемых и выведенных
результирующих данных. Если программа выведет недостаточное или избыточное
количество результирующих данных, то после проверки этих данных появится
сообщение &laquo;<i>Выведены не все результирующие данные</i>&raquo; или,
соответственно, &laquo;<i>Попытка вывести лишние результирующие данные</i>&raquo;.
<p>Как и в случае функций группы <code>Get</code>, при вызовах процедуры <code>Put</code> программа
осуществляет контроль за соответствием количества требуемых и выведенных
результирующих данных. Если программа выведет недостаточное или избыточное
количество результирующих данных, то после проверки этих данных появится
сообщение &laquo;<i>Выведены не все результирующие данные</i>&raquo; или,
соответственно, &laquo;<i>Попытка вывести лишние результирующие данные</i>&raquo;.
</p>
<a name="debug"></a><h2>Вывод отладочной информации
<a name="debug"></a><h2>Вывод отладочной информации
</h2>
<p>Описываемые далее отладочные средства появились в версии 4.9 задачника Programming Taskbook.
С их помощью можно выводить отладочную информацию
непосредственно в окно задачника (в специальный <a href="debug.html"><i>раздел отладки</i></a>).</p>
<p>Описываемые далее отладочные средства появились в версии 4.9 задачника Programming Taskbook.
С их помощью можно выводить отладочную информацию
непосредственно в окно задачника (в специальный <a href="debug.html"><i>раздел отладки</i></a>).</p>
<a name="show"></a>
<hr noshade size="1">
<blockquote>
<code><b>procedure</b> Show(S: string);
</code></blockquote>
<p>Отображает текстовую строку <code>S</code> в разделе отладки окна задачника.
<p>Отображает текстовую строку <code>S</code> в разделе отладки окна задачника.
</p>
<p>Если текущая экранная строка в разделе отладки уже содержит некоторый текст, то
строка <code>S</code> снабжается начальным пробелом и приписывается к этому тексту,
за исключением случая, когда при таком приписывании размер
полученного текста превысит ширину области данных (равную 80&nbsp;символам).
В последнем случае вывод строки <code>S</code> осуществляется с начала
следующей экранной строки; если же и в этой ситуации строка <code>S</code> превысит
ширину области данных, то строка <code>S</code> будет выведена на нескольких
экранных строках, причем разрывы текста будут выполняться по
пробельным символам строки <code>S</code>, а при отсутствии пробелов &#151; при
достижении очередного фрагмента строки длины, равной 80.
<p>Если текущая экранная строка в разделе отладки уже содержит некоторый текст, то
строка <code>S</code> снабжается начальным пробелом и приписывается к этому тексту,
за исключением случая, когда при таком приписывании размер
полученного текста превысит ширину области данных (равную 80&nbsp;символам).
В последнем случае вывод строки <code>S</code> осуществляется с начала
следующей экранной строки; если же и в этой ситуации строка <code>S</code> превысит
ширину области данных, то строка <code>S</code> будет выведена на нескольких
экранных строках, причем разрывы текста будут выполняться по
пробельным символам строки <code>S</code>, а при отсутствии пробелов &#151; при
достижении очередного фрагмента строки длины, равной 80.
</p>
<p>Строка <code>S</code> может содержать явные команды перехода на новую
экранную строку. В качестве таких команд можно использовать или
символ с кодом 13 (&laquo;возврат каретки&raquo;), или символ с кодом 10 (&laquo;переход на новую
строку&raquo;), или их комбинацию в
указанном порядке (<code>#13#10</code>).
<p>Строка <code>S</code> может содержать явные команды перехода на новую
экранную строку. В качестве таких команд можно использовать или
символ с кодом 13 (&laquo;возврат каретки&raquo;), или символ с кодом 10 (&laquo;переход на новую
строку&raquo;), или их комбинацию в
указанном порядке (<code>#13#10</code>).
</p>
<a name="shownumber"></a>
@ -363,36 +363,36 @@
<code><b>procedure</b> Show(<b>[</b>S: string;<b>]</b> A: integer<b>[</b>; W: integer<b>]</b>);<br>
<b>procedure</b> Show(<b>[</b>S: string;<b>]</b> A: real<b>[</b>; W: integer<b>]</b>);
</code></blockquote>
<p>Перегруженные варианты процедуры Show, предназначенные для вывода числовых отладочных данных.
Использование этих вариантов позволяет максимально упростить действия
учащегося, связанные с выводом числовых данных, поскольку избавляет
его от необходимости применять стандартные средства языка Pascal,
предназначенные для преобразования чисел в их строковые
представления.
<p>Перегруженные варианты процедуры Show, предназначенные для вывода числовых отладочных данных.
Использование этих вариантов позволяет максимально упростить действия
учащегося, связанные с выводом числовых данных, поскольку избавляет
его от необходимости применять стандартные средства языка Pascal,
предназначенные для преобразования чисел в их строковые
представления.
</p>
<p>При вызове приведенных вариантов можно не указывать один или оба параметра,
заключенные в квадратные скобки.
<p>При вызове приведенных вариантов можно не указывать один или оба параметра,
заключенные в квадратные скобки.
</p>
<p>Строковый параметр <code>S</code> определяет необязательный комментарий,
который указывается перед выводимым числом; если параметр <code>S</code>
отсутствует, то комментарий полагается равным пустой строке.
<p>Строковый параметр <code>S</code> определяет необязательный комментарий,
который указывается перед выводимым числом; если параметр <code>S</code>
отсутствует, то комментарий полагается равным пустой строке.
</p>
<p>Числовой параметр <code>A</code> определяет выводимое число.
<p>Числовой параметр <code>A</code> определяет выводимое число.
</p>
<p>Необязательный целочисленный параметр <code>W</code> определяет
<i>ширину поля вывода</i> (т.&nbsp;е. количество экранных
позиций, отводимое для вывода числа). Если указанной ширины <code>W</code> поля вывода недостаточно, то
значение параметра <code>W</code> игнорируется; в этом случае (а также в случае, если параметр <code>W</code> отсутствует)
используется ширина поля вывода, минимально необходимая для
отображения данного числа. Если число не занимает всего поля вывода, то
оно дополняется слева пробелами (т.&nbsp;е. выравнивается по
<i>правой</i> границе поля вывода). В качестве десятичного разделителя
для чисел с дробной частью используется <i>точка</i>.
<p>Необязательный целочисленный параметр <code>W</code> определяет
<i>ширину поля вывода</i> (т.&nbsp;е. количество экранных
позиций, отводимое для вывода числа). Если указанной ширины <code>W</code> поля вывода недостаточно, то
значение параметра <code>W</code> игнорируется; в этом случае (а также в случае, если параметр <code>W</code> отсутствует)
используется ширина поля вывода, минимально необходимая для
отображения данного числа. Если число не занимает всего поля вывода, то
оно дополняется слева пробелами (т.&nbsp;е. выравнивается по
<i>правой</i> границе поля вывода). В качестве десятичного разделителя
для чисел с дробной частью используется <i>точка</i>.
</p>
<p>Вещественные числа по умолчанию выводятся в формате с
фиксированной точкой и двумя дробными знаками. Изменить формат
вывода вещественных чисел можно с помощью вспомогательной
процедуры <code>SetPrecision</code>, описываемой далее.
<p>Вещественные числа по умолчанию выводятся в формате с
фиксированной точкой и двумя дробными знаками. Изменить формат
вывода вещественных чисел можно с помощью вспомогательной
процедуры <code>SetPrecision</code>, описываемой далее.
</p>
<a name="showline"></a>
@ -402,12 +402,12 @@
<b>procedure</b> ShowLine(<b>[</b>S: string;<b>]</b> A: integer<b>[</b>; W: integer<b>]</b>);<br>
<b>procedure</b> ShowLine(<b>[</b>S: string;<b>]</b> A: real<b>[</b>; W: integer<b>]</b>);<br>
</code></blockquote>
<p>Модификации ранее описанных процедур <code>Show</code>; после вывода указанных данных в раздел отладки
дополнительно осуществляют автоматический переход на следующую экранную строку.
Смысл параметров &#151; тот же, что и для соответствующих вариантов процедуры <code>Show</code>.
Параметры, указанные в квадратных скобках, могут отсутствовать.
Если процедура <code>ShowLine</code> вызывается без параметров, то она
просто обеспечивает переход на новую экранную строку в разделе отладки.
<p>Модификации ранее описанных процедур <code>Show</code>; после вывода указанных данных в раздел отладки
дополнительно осуществляют автоматический переход на следующую экранную строку.
Смысл параметров &#151; тот же, что и для соответствующих вариантов процедуры <code>Show</code>.
Параметры, указанные в квадратных скобках, могут отсутствовать.
Если процедура <code>ShowLine</code> вызывается без параметров, то она
просто обеспечивает переход на новую экранную строку в разделе отладки.
</p>
<a name="hidetask"></a>
@ -415,16 +415,16 @@
<blockquote>
<code><b>procedure</b> HideTask;
</code></blockquote>
<p>Вызов данной процедуры обеспечивает автоматическое скрытие всех разделов окна
задачника, кроме раздела отладки. Если раздел отладки в окне задачника
не отображается (в частности, если программа запущена в
демонстрационном режиме), то вызов процедуры <code>HideTask</code> игнорируется.
Игнорируются также все повторные вызовы данной процедуры.
<p>Вызов данной процедуры обеспечивает автоматическое скрытие всех разделов окна
задачника, кроме раздела отладки. Если раздел отладки в окне задачника
не отображается (в частности, если программа запущена в
демонстрационном режиме), то вызов процедуры <code>HideTask</code> игнорируется.
Игнорируются также все повторные вызовы данной процедуры.
</p>
<p>Скрыть/восстановить основные разделы окна
задачника после его отображения на экране можно также с помощью клавиши
пробела или соответствующей команды контекстного меню раздела
отладки.
<p>Скрыть/восстановить основные разделы окна
задачника после его отображения на экране можно также с помощью клавиши
пробела или соответствующей команды контекстного меню раздела
отладки.
</p>
@ -435,36 +435,36 @@
<code><b>procedure</b> SetPrecision(N: integer);
</code></blockquote>
<p>Процедура предназначена для настройки формата вывода
<i>вещественных</i> отладочных данных. Если параметр <code>N</code> положителен, то он
определяет количество выводимых дробных разрядов; при этом число
выводится в формате с фиксированной точкой. Если параметр <code>N</code> равен
нулю, то число выводится в формате с
плавающей точкой (экспоненциальном формате); при этом число
дробных знаков для экспоненциального формата
определяется шириной поля вывода (т.&nbsp;е. параметром <code>W</code> процедуры
<code>Show</code> или <code>ShowLine</code>). При отрицательных значениях параметра <code>N</code> выполняется та же
настройка, что и при <code>N&nbsp;=&nbsp;0</code>.
<p>Процедура предназначена для настройки формата вывода
<i>вещественных</i> отладочных данных. Если параметр <code>N</code> положителен, то он
определяет количество выводимых дробных разрядов; при этом число
выводится в формате с фиксированной точкой. Если параметр <code>N</code> равен
нулю, то число выводится в формате с
плавающей точкой (экспоненциальном формате); при этом число
дробных знаков для экспоненциального формата
определяется шириной поля вывода (т.&nbsp;е. параметром <code>W</code> процедуры
<code>Show</code> или <code>ShowLine</code>). При отрицательных значениях параметра <code>N</code> выполняется та же
настройка, что и при <code>N&nbsp;=&nbsp;0</code>.
</p>
<p>Действие текущей настройки числового формата, определенной
процедурой <code>SetPrecision</code>, продолжается до очередного вызова этой
процедуры. До первого вызова процедуры <code>SetPrecision</code> вещественные
числа выводятся в формате с фиксированной точкой и двумя дробными
знаками.
<p>Действие текущей настройки числового формата, определенной
процедурой <code>SetPrecision</code>, продолжается до очередного вызова этой
процедуры. До первого вызова процедуры <code>SetPrecision</code> вещественные
числа выводятся в формате с фиксированной точкой и двумя дробными
знаками.
</p>
<h2>Особенности модуля PT4Exam</h2>
<p>При выполнении заданий групп ExamBegin и ExamTaskC, связанных с ЕГЭ по информатике,
к программам вместо модуля PT4 подключается модуль <code>PT4Exam</code>. В этом модуле реализована единственная дополнительная
процедура <a href="#task"><code>Task</code></a>, обеспечивающая инициализацию задания с указанным
именем. Все действия по вводу-выводу должны выполняться с использование стандартных
процедур языка Pascal. Отладочные средства модуля <code>PT4</code> в модуле <code>PT4Exam</code> также недоступны,
однако имеется возможность выводить дополнительные данные можно непосредственно в раздел результатов
(хотя при этом решение будет считаться ошибочным).
<h2>Особенности модуля PT4Exam</h2>
<p>При выполнении заданий групп ExamBegin и ExamTaskC, связанных с ЕГЭ по информатике,
к программам вместо модуля PT4 подключается модуль <code>PT4Exam</code>. В этом модуле реализована единственная дополнительная
процедура <a href="#task"><code>Task</code></a>, обеспечивающая инициализацию задания с указанным
именем. Все действия по вводу-выводу должны выполняться с использование стандартных
процедур языка Pascal. Отладочные средства модуля <code>PT4</code> в модуле <code>PT4Exam</code> также недоступны,
однако имеется возможность выводить дополнительные данные можно непосредственно в раздел результатов
(хотя при этом решение будет считаться ошибочным).
</p>
<p>Описанные выше ограничения модуля <code>PT4Exam</code> позволяют максимально приблизить полученное
решение к виду, требуемому на экзамене (программа содержит всего две дополнительные конструкции:
директиву подключения модуля <code>PT4Exam</code> и оператор вызова процедуры <code>Task</code>, инициализирующей требуемое задание).
<p>Описанные выше ограничения модуля <code>PT4Exam</code> позволяют максимально приблизить полученное
решение к виду, требуемому на экзамене (программа содержит всего две дополнительные конструкции:
директиву подключения модуля <code>PT4Exam</code> и оператор вызова процедуры <code>Task</code>, инициализирующей требуемое задание).
</p>
</body>
</html>

View file

@ -10,30 +10,30 @@
</head>
<body>
<h1>Создание шаблона программы</h1>
<h1>Создание шаблона программы</h1>
<hr>
<p>
Входящий в состав задачника <b>Programming Taskbook</b> программный модуль <b>PT4Load</b> позволяет быстро
создавать программы-заготовки для выполнения требуемого задания. Этот модуль можно
вызвать непосредственно из среды <b>PascalABC.NET</b> командой
меню &laquo;Модули | Создать шаблон программы&raquo; (с данной командой связана также
кнопка <img border="0" src="gif/Load.gif" width="16" height="17"> и клавиатурная
комбинация <b>Shift+Ctrl+L</b>).</p>
Входящий в состав задачника <b>Programming Taskbook</b> программный модуль <b>PT4Load</b> позволяет быстро
создавать программы-заготовки для выполнения требуемого задания. Этот модуль можно
вызвать непосредственно из среды <b>PascalABC.NET</b> командой
меню &laquo;Модули | Создать шаблон программы&raquo; (с данной командой связана также
кнопка <img border="0" src="gif/Load.gif" width="16" height="17"> и клавиатурная
комбинация <b>Shift+Ctrl+L</b>).</p>
<p>При запуске данного модуля появляется окно, в котором требуется указать имя задания
(в нижней части окна отображаются имена всех имеющихся групп заданий).</p>
<p>При запуске данного модуля появляется окно, в котором требуется указать имя задания
(в нижней части окна отображаются имена всех имеющихся групп заданий).</p>
<blockquote>
<img border="0" src="gif/PT4Load.png">
</blockquote>
<p>
При вводе допустимого
имени задания (то есть имени группы и порядкового номера, например, <code>Begin1</code>)
кнопка &laquo;Загрузка&raquo; становится доступной, и после ее нажатия (или нажатия клавиши <b>Enter</b>)
в рабочем каталоге создается
файл, содержащий шаблон программы для выполнения выбранного задания (имя файла совпадает с именем задания).
Созданная программа-шаблон сразу загружается в редактор <b>PascalABC.NET</b>; ее можно немедленно запустить, чтобы
увидеть формулировку задания и пример исходных данных.</p>
<p>Приведем пример шаблона, созданного для задания Begin3 (этот шаблон будет записан в файл <b>Begin3.pas</b>):</p>
При вводе допустимого
имени задания (то есть имени группы и порядкового номера, например, <code>Begin1</code>)
кнопка &laquo;Загрузка&raquo; становится доступной, и после ее нажатия (или нажатия клавиши <b>Enter</b>)
в рабочем каталоге создается
файл, содержащий шаблон программы для выполнения выбранного задания (имя файла совпадает с именем задания).
Созданная программа-шаблон сразу загружается в редактор <b>PascalABC.NET</b>; ее можно немедленно запустить, чтобы
увидеть формулировку задания и пример исходных данных.</p>
<p>Приведем пример шаблона, созданного для задания Begin3 (этот шаблон будет записан в файл <b>Begin3.pas</b>):</p>
<blockquote>
<code>
@ -45,33 +45,33 @@
<b>end</b>.<br>
</code></blockquote>
<p>Ввод имени задания для исполнителей Робот и Чертежник имеет следующую особенность: для них надо вначале
ввести <i>префикс исполнителя</i> (<code>RB</code> для Робота или <code>DM</code> для Чертежника),
после чего ввести имя набора заданий
для соответствующего исполнителя и номер этого задания (например, <code>RBa1</code>).</p>
<p>Ввод имени задания для исполнителей Робот и Чертежник имеет следующую особенность: для них надо вначале
ввести <i>префикс исполнителя</i> (<code>RB</code> для Робота или <code>DM</code> для Чертежника),
после чего ввести имя набора заданий
для соответствующего исполнителя и номер этого задания (например, <code>RBa1</code>).</p>
<p>Если введено имя задания, для которого уже имеется файл с программой, то именно этот файл и будет
загружен в редактор.</p>
<p>Если введено имя задания, для которого уже имеется файл с программой, то именно этот файл и будет
загружен в редактор.</p>
<p>Особая группа <code>PAS</code> (последняя в списке групп заданий) позволяет загрузить в редактор
любой файл с расширением <code>.pas</code> из рабочего каталога. При вводе имени этой группы и нажатии
кнопки &laquo;Загрузка&raquo; появляется список
всех pas-файлов; после выбора любого из этих файлов он немедленно загружается в редактор.
Таким образом, использование группы <code>PAS</code> равносильно команде &laquo;Файл | Открыть&raquo;.
<p>Особая группа <code>PAS</code> (последняя в списке групп заданий) позволяет загрузить в редактор
любой файл с расширением <code>.pas</code> из рабочего каталога. При вводе имени этой группы и нажатии
кнопки &laquo;Загрузка&raquo; появляется список
всех pas-файлов; после выбора любого из этих файлов он немедленно загружается в редактор.
Таким образом, использование группы <code>PAS</code> равносильно команде &laquo;Файл | Открыть&raquo;.
<p> В версии 4.11 задачника появилась возможность фильтрации групп в процессе ввода их названий.
Фильтрация производится по уже введенным символам. Например, при вводе первого символа &laquo;m&raquo; в
списке возможных групп останутся только группы, имена которых начинаются с этого символа; при
этом перед списком отфильтрованных групп будет выведен текст &laquo;(фильтр)&raquo;:
<p> В версии 4.11 задачника появилась возможность фильтрации групп в процессе ввода их названий.
Фильтрация производится по уже введенным символам. Например, при вводе первого символа &laquo;m&raquo; в
списке возможных групп останутся только группы, имена которых начинаются с этого символа; при
этом перед списком отфильтрованных групп будет выведен текст &laquo;(фильтр)&raquo;:
</p>
<blockquote>
<img border="0" src="gif/load_3.png">
</blockquote>
<p> Как только в списке останется единственный вариант, будет выведена подсказка о том, что для
завершения ввода имени данной группы достаточно нажать пробел:
<p> Как только в списке останется единственный вариант, будет выведена подсказка о том, что для
завершения ввода имени данной группы достаточно нажать пробел:
</p>
<blockquote>
@ -79,7 +79,7 @@
</blockquote>
После нажатия пробела произойдет автоматическое дополнение введенной части имени группы:
После нажатия пробела произойдет автоматическое дополнение введенной части имени группы:
<blockquote>
<img border="0" src="gif/load_6.png">

View file

@ -10,74 +10,74 @@
</head>
<body>
<h1>Просмотр результатов</h1>
<h1>Просмотр результатов</h1>
<hr>
<p>
Результаты выполнения всех заданий из задачника <b>Programming Taskbook</b>
заносятся в специальный <i>файл результатов</i> <b>results.abc</b>, который должен находиться в том каталоге, из которого
запускаются программы с заданиями.</p>
Результаты выполнения всех заданий из задачника <b>Programming Taskbook</b>
заносятся в специальный <i>файл результатов</i> <b>results.abc</b>, который должен находиться в том каталоге, из которого
запускаются программы с заданиями.</p>
<p>Данный файл автоматически создается в рабочем каталоге системы <b>PascalABC.NET</b>
(по умолчанию рабочим каталогом является каталог PABCWork.NET, находящийся на диске C). При смене рабочего каталога
(это можно сделать с помощью программы настройки задачника
PT4Setup) в новом рабочем каталоге
также создается файл результатов.
<p>Данный файл автоматически создается в рабочем каталоге системы <b>PascalABC.NET</b>
(по умолчанию рабочим каталогом является каталог PABCWork.NET, находящийся на диске C). При смене рабочего каталога
(это можно сделать с помощью программы настройки задачника
PT4Setup) в новом рабочем каталоге
также создается файл результатов.
</p>
<p>
Данные хранятся в файле результатов в зашифрованном виде, поэтому его непосредственный просмотр и корректировка
невозможны. Для просмотра содержимого файла результатов предназначен программный модуль <b>PT4Results</b>,
который вызывается непосредственно из среды <b>PascalABC.NET</b> командой
меню &laquo;Модули | Просмотреть результаты&raquo; (с данной командой связана также
кнопка <img border="0" src="gif/Results.gif" width="16" height="17"> и клавиатурная
комбинация <b>Shift+Ctrl+R</b>).</p>
Данные хранятся в файле результатов в зашифрованном виде, поэтому его непосредственный просмотр и корректировка
невозможны. Для просмотра содержимого файла результатов предназначен программный модуль <b>PT4Results</b>,
который вызывается непосредственно из среды <b>PascalABC.NET</b> командой
меню &laquo;Модули | Просмотреть результаты&raquo; (с данной командой связана также
кнопка <img border="0" src="gif/Results.gif" width="16" height="17"> и клавиатурная
комбинация <b>Shift+Ctrl+R</b>).</p>
<p>При просмотре файла результатов с помощью модуля <b>PT4Results</b> содержащаяся в нем информация отображается в двух
вариантах.</p>
<p><b>Вариант с полной информацией</b> представляет собой перечень всех запусков программ с учебными заданиями;
для каждого запуска указывается
имя задания, дата и время запуска, а также результат запуска. Например:
<p>При просмотре файла результатов с помощью модуля <b>PT4Results</b> содержащаяся в нем информация отображается в двух
вариантах.</p>
<p><b>Вариант с полной информацией</b> представляет собой перечень всех запусков программ с учебными заданиями;
для каждого запуска указывается
имя задания, дата и время запуска, а также результат запуска. Например:
<blockquote>
<code>
= Иванов Петр&nbsp;&nbsp;&nbsp;&nbsp; (C:\PABCWork)<br>
Begin1 A27/09 19:07 Выведены не все результирующие данные.<br>
Begin1 A27/09 19:07 Ошибочное решение.--2<br>
Begin1 A27/09 19:07 Задание выполнено!<br>
For1&nbsp;&nbsp; A27/09 19:07 Ознакомительный запуск.<br>
For1&nbsp;&nbsp; A27/09 19:08 Выведены не все результирующие данные.<br>
For1&nbsp;&nbsp; A27/09 19:10 Ошибочное решение.--3<br>
For1&nbsp;&nbsp; A27/09 19:13 Задание выполнено!<br>
For5&nbsp;&nbsp; A27/09 19:15 Неверно указан тип при вводе исходных данных.--2<br>
For5&nbsp;&nbsp; A27/09 19:16 Выведены не все результирующие данные.<br>
For5&nbsp;&nbsp; A27/09 19:19 Задание выполнено!<br>
For10&nbsp; A27/09 19:21 Неверно указан тип при вводе исходных данных.<br>
For10&nbsp; A27/09 19:22 Ошибочное решение.<br>
= Иванов Петр&nbsp;&nbsp;&nbsp;&nbsp; (C:\PABCWork)<br>
Begin1 A27/09 19:07 Выведены не все результирующие данные.<br>
Begin1 A27/09 19:07 Ошибочное решение.--2<br>
Begin1 A27/09 19:07 Задание выполнено!<br>
For1&nbsp;&nbsp; A27/09 19:07 Ознакомительный запуск.<br>
For1&nbsp;&nbsp; A27/09 19:08 Выведены не все результирующие данные.<br>
For1&nbsp;&nbsp; A27/09 19:10 Ошибочное решение.--3<br>
For1&nbsp;&nbsp; A27/09 19:13 Задание выполнено!<br>
For5&nbsp;&nbsp; A27/09 19:15 Неверно указан тип при вводе исходных данных.--2<br>
For5&nbsp;&nbsp; A27/09 19:16 Выведены не все результирующие данные.<br>
For5&nbsp;&nbsp; A27/09 19:19 Задание выполнено!<br>
For10&nbsp; A27/09 19:21 Неверно указан тип при вводе исходных данных.<br>
For10&nbsp; A27/09 19:22 Ошибочное решение.<br>
</code></blockquote>
<p>Буква <code>A</code> перед датой означает, что задание выполнялось в системе <b>PascalABC.NET</b>, а числа в конце
некоторых строк указывают на то, что было проведено подряд несколько запусков программы с одинаковым результатом.</p>
<p><b>Вариант со сводной информацией</b> позволяет быстро узнать время выполнения заданий, количество
выполненных и незавершенных заданий, а также получить сводку о выполненных заданиях по каждой группе. Например:</p>
<p>Буква <code>A</code> перед датой означает, что задание выполнялось в системе <b>PascalABC.NET</b>, а числа в конце
некоторых строк указывают на то, что было проведено подряд несколько запусков программы с одинаковым результатом.</p>
<p><b>Вариант со сводной информацией</b> позволяет быстро узнать время выполнения заданий, количество
выполненных и незавершенных заданий, а также получить сводку о выполненных заданиях по каждой группе. Например:</p>
<blockquote>
<code>
= Иванов Петр&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (C:\PABCWork.NET)<br>
-1- ВРЕМЯ ЗАНЯТИЙ:<br>
27/09(19:07-19:22)[3/16]&nbsp;&nbsp; ВСЕГО: 0:16 [3/16]<br>
-2- ВЫПОЛНЕННЫЕ ЗАДАНИЯ:<br>
= Иванов Петр&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (C:\PABCWork.NET)<br>
-1- ВРЕМЯ ЗАНЯТИЙ:<br>
27/09(19:07-19:22)[3/16]&nbsp;&nbsp; ВСЕГО: 0:16 [3/16]<br>
-2- ВЫПОЛНЕННЫЕ ЗАДАНИЯ:<br>
Begin1 A27/09 [4]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; For1 A27/09 [6] &nbsp;&nbsp;&nbsp; For5 A27/09 [4]<br>
-3- НЕЗАВЕРШЕННЫЕ ЗАДАНИЯ:<br>
-3- НЕЗАВЕРШЕННЫЕ ЗАДАНИЯ:<br>
For10 27/09 [2]<br>
-5- СВОДКА ПО ГРУППАМ ЗАДАНИЙ:<br>
Begin 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; For 2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ВСЕГО: 3<br>
-5- СВОДКА ПО ГРУППАМ ЗАДАНИЙ:<br>
Begin 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; For 2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ВСЕГО: 3<br>
</code></blockquote>
<p>При использовании задачника в системе <b>PascalABC.NET</b> в файл результатов заносится также информация
о выполненных заданиях для исполнителей Робот и Чертежник.</p>
<p>При использовании задачника в системе <b>PascalABC.NET</b> в файл результатов заносится также информация
о выполненных заданиях для исполнителей Робот и Чертежник.</p>
</p>
<p>Начиная с версии 4.11, программный модуль <b>PT4Results</b> можно вызвать непосредственно из <a href="window.html">окна задачника</a>,
нажав клавишу <b>F2</b>.
<p>Начиная с версии 4.11, программный модуль <b>PT4Results</b> можно вызвать непосредственно из <a href="window.html">окна задачника</a>,
нажав клавишу <b>F2</b>.
</p>
</body>
</html>

View file

@ -8,182 +8,182 @@
<body>
<a name="main"></a>
<h1>Раздел отладки</h1>
<h1>Раздел отладки</h1>
<hr>
<p>В версии 4.9 задачника Programming Taskbook появились средства,
позволяющие выводить отладочную информацию непосредственно в окно
задачника (в специальный <i>раздел отладки</i>). Необходимость в
подобных дополнительных средствах возникает, прежде всего,
при работе с комплексом Programming Taskbook for MPI
при отладке
<i>параллельных программ</i>, поскольку для них нельзя использовать такие
стандартные средства отладки, как точки останова, пошаговое выполнение
программы и окна просмотра значений переменных. Следует также
отметить, что возможность вывода информации в раздел отладки
позволяет использовать задачник для написания и отладки параллельных
программ, не связанных с выполнением конкретных учебных заданий.
<p>В версии 4.9 задачника Programming Taskbook появились средства,
позволяющие выводить отладочную информацию непосредственно в окно
задачника (в специальный <i>раздел отладки</i>). Необходимость в
подобных дополнительных средствах возникает, прежде всего,
при работе с комплексом Programming Taskbook for MPI
при отладке
<i>параллельных программ</i>, поскольку для них нельзя использовать такие
стандартные средства отладки, как точки останова, пошаговое выполнение
программы и окна просмотра значений переменных. Следует также
отметить, что возможность вывода информации в раздел отладки
позволяет использовать задачник для написания и отладки параллельных
программ, не связанных с выполнением конкретных учебных заданий.
</p>
<p>Отладочные средства задачника могут оказаться полезными и для
обычных, непараллельных программ. В этом случае их можно применять в
качестве дополнения к средствам встроенного отладчика.
<p>Отладочные средства задачника могут оказаться полезными и для
обычных, непараллельных программ. В этом случае их можно применять в
качестве дополнения к средствам встроенного отладчика.
</p>
<p>Раздел отладки представляет собой одну или несколько
многострочных текстовых областей вывода. Он располагается под
основными разделами задачника и выводится на экран только в случае,
если в нем содержится какой-либо текст:
<p>Раздел отладки представляет собой одну или несколько
многострочных текстовых областей вывода. Он располагается под
основными разделами задачника и выводится на экран только в случае,
если в нем содержится какой-либо текст:
</p>
<blockquote>
<img border="0" src="gif\debug_1.png">
</blockquote>
<p>При демонстрационном запуске программы все процедуры, связанные
с разделом отладки, игнорируются, поэтому раздел отладки на экране не
отображается.
<p>При демонстрационном запуске программы все процедуры, связанные
с разделом отладки, игнорируются, поэтому раздел отладки на экране не
отображается.
</p>
<p>Имеется возможность скрыть в окне задачника все его разделы, кроме
раздела отладки; для этого достаточно нажать клавишу пробела.
Повторное нажатие пробела восстанавливает в окне задачника ранее
скрытые разделы. Для скрытия/отображения основных разделов окна
задачника можно также использовать соответствующую команду
контекстного меню, связанного с разделом отладки. Скрыть все разделы
окна задачника, кроме раздела отладки, можно также программным
способом, вызвав процедуру HideTask.
<p>Имеется возможность скрыть в окне задачника все его разделы, кроме
раздела отладки; для этого достаточно нажать клавишу пробела.
Повторное нажатие пробела восстанавливает в окне задачника ранее
скрытые разделы. Для скрытия/отображения основных разделов окна
задачника можно также использовать соответствующую команду
контекстного меню, связанного с разделом отладки. Скрыть все разделы
окна задачника, кроме раздела отладки, можно также программным
способом, вызвав процедуру HideTask.
</p>
<p>Прокрутка содержимого раздела отладки может осуществляться с
помощью вертикальной полосы прокрутки, расположенной у его правой
границы. Можно также использовать колесико мыши и клавиатурные
комбинации <b>Alt+Up</b>, <b>Alt+Down</b> (прокрутка на одну экранную строку),
<b>Alt+PgUp</b>, <b>Alt+PgDn</b> (прокрутка на 10 экранных строк),
<b>Alt+Home</b>, <b>Alt+End</b> (прокрутка к первой или последней строке
области вывода).
<p>Прокрутка содержимого раздела отладки может осуществляться с
помощью вертикальной полосы прокрутки, расположенной у его правой
границы. Можно также использовать колесико мыши и клавиатурные
комбинации <b>Alt+Up</b>, <b>Alt+Down</b> (прокрутка на одну экранную строку),
<b>Alt+PgUp</b>, <b>Alt+PgDn</b> (прокрутка на 10 экранных строк),
<b>Alt+Home</b>, <b>Alt+End</b> (прокрутка к первой или последней строке
области вывода).
</p>
<p>Предусмотрена возможность изменения размера шрифта,
используемого в разделе отладки. Шрифт может изменяться от 7 до 14
пунктов с шагом 1. Для увеличения шрифта предназначена клавиатурная
комбинация <b>Alt+[+]</b>, для уменьшения &#151; комбинация <b>Alt+[&#150;]</b>.
Соответствующие команды имеются также в контекстном меню раздела
отладки. Информация о текущем размере шрифта сохраняется в файле
результатов и учитывается при последующих запусках программы.
<p>Предусмотрена возможность изменения размера шрифта,
используемого в разделе отладки. Шрифт может изменяться от 7 до 14
пунктов с шагом 1. Для увеличения шрифта предназначена клавиатурная
комбинация <b>Alt+[+]</b>, для уменьшения &#151; комбинация <b>Alt+[&#150;]</b>.
Соответствующие команды имеются также в контекстном меню раздела
отладки. Информация о текущем размере шрифта сохраняется в файле
результатов и учитывается при последующих запусках программы.
</p>
<p>Для &laquo;непараллельных&raquo; заданий раздел отладки содержит
единственную область вывода. Для заданий по параллельному
программированию число областей вывода равно числу параллельных
процессов плюс 1; при этом в каждый момент времени в разделе отладки
отображается одна из областей. Если областей вывода больше одной, то в
нижней части раздела отладки выводится набор ярлычков, позволяющих
переключиться на любую из имеющихся областей вывода:
<p>Для &laquo;непараллельных&raquo; заданий раздел отладки содержит
единственную область вывода. Для заданий по параллельному
программированию число областей вывода равно числу параллельных
процессов плюс 1; при этом в каждый момент времени в разделе отладки
отображается одна из областей. Если областей вывода больше одной, то в
нижней части раздела отладки выводится набор ярлычков, позволяющих
переключиться на любую из имеющихся областей вывода:
</p>
<blockquote>
<img border="0" src="gif\debug_2.png">
</blockquote>
<p>Ярлычки с номерами (от 0 до N&#150;1, где N &#151; количество
процессов) позволяют просмотреть содержимое области вывода, связанной
с процессом соответствующего ранга; ярлычок с символом
&laquo;*&raquo; позволяет просмотреть область вывода, содержащую
объединенный текст всех других областей:
<p>Ярлычки с номерами (от 0 до N&#150;1, где N &#151; количество
процессов) позволяют просмотреть содержимое области вывода, связанной
с процессом соответствующего ранга; ярлычок с символом
&laquo;*&raquo; позволяет просмотреть область вывода, содержащую
объединенный текст всех других областей:
</p>
<blockquote>
<img border="0" src="gif\debug_3.png">
</blockquote>
<p>Для переключения на нужную область вывода достаточно щелкнуть
мышью на соответствующем ярлычке. Кроме того, для последовательного
перебора ярлычков слева направо или справа налево можно использовать
комбинации <b>Alt+Right</b> и <b>Alt+Left</b> соответственно (перебор
осуществляется циклически). Можно также сразу перейти к нужной
области вывода, нажав соответствующую клавишу: для области
&laquo;*&raquo; &#151; клавишу <b>[*]</b>, для областей
&laquo;0&raquo;&#150;&laquo;9&raquo; &#151; цифровые клавиши
<b>0</b>&#150;<b>9</b>, а для областей &laquo;10&raquo;&#150;&laquo;35&raquo;
&#151; буквенные клавиши от <b>A</b> до <b>Z</b> (при выполнении
заданий по параллельному программированию максимально возможное
число процессов равно 36).
<p>Для переключения на нужную область вывода достаточно щелкнуть
мышью на соответствующем ярлычке. Кроме того, для последовательного
перебора ярлычков слева направо или справа налево можно использовать
комбинации <b>Alt+Right</b> и <b>Alt+Left</b> соответственно (перебор
осуществляется циклически). Можно также сразу перейти к нужной
области вывода, нажав соответствующую клавишу: для области
&laquo;*&raquo; &#151; клавишу <b>[*]</b>, для областей
&laquo;0&raquo;&#150;&laquo;9&raquo; &#151; цифровые клавиши
<b>0</b>&#150;<b>9</b>, а для областей &laquo;10&raquo;&#150;&laquo;35&raquo;
&#151; буквенные клавиши от <b>A</b> до <b>Z</b> (при выполнении
заданий по параллельному программированию максимально возможное
число процессов равно 36).
</p>
<p>Если в основных разделах окна задачника отсутствуют
прокручиваемые элементы или основные разделы являются скрытыми, то
дополнительную клавишу <b>Alt</b> в перечисленных выше клавиатурных
<b>Alt</b>-комбинациях можно не использовать.
<p>Если в основных разделах окна задачника отсутствуют
прокручиваемые элементы или основные разделы являются скрытыми, то
дополнительную клавишу <b>Alt</b> в перечисленных выше клавиатурных
<b>Alt</b>-комбинациях можно не использовать.
</p>
<p>Отладочная информация, получаемая из
подчиненных процессов параллельной программы, предварительно
сохраняется в специальных
временных файлах в каталоге учащегося, поэтому она будет доступна для
просмотра, даже если на каком-либо этапе выполнения
программы произойдет зависание некоторых ее подчиненных процессов.
Отладочная информация, получаемая из главного процесса, выводится
непосредственно в раздел отладки.
<p>Отладочная информация, получаемая из
подчиненных процессов параллельной программы, предварительно
сохраняется в специальных
временных файлах в каталоге учащегося, поэтому она будет доступна для
просмотра, даже если на каком-либо этапе выполнения
программы произойдет зависание некоторых ее подчиненных процессов.
Отладочная информация, получаемая из главного процесса, выводится
непосредственно в раздел отладки.
</p>
<p>Количество отладочных строк для каждого процесса не должно
превышать 999; если некоторый процесс пытается вывести данные в
строку с номером, превышающим 999, то в связанной с этим процессом
области отладки выводится сообщение об ошибке, и последующий вывод
отладочных данных для этого процесса блокируется. Указанное
ограничение позволяет, в частности, избежать проблем, возникающих при
&laquo;бесконечном&raquo; выводе отладочной информации из какого-либо
зациклившегося подчиненного процесса во временный файл.
<p>Количество отладочных строк для каждого процесса не должно
превышать 999; если некоторый процесс пытается вывести данные в
строку с номером, превышающим 999, то в связанной с этим процессом
области отладки выводится сообщение об ошибке, и последующий вывод
отладочных данных для этого процесса блокируется. Указанное
ограничение позволяет, в частности, избежать проблем, возникающих при
&laquo;бесконечном&raquo; выводе отладочной информации из какого-либо
зациклившегося подчиненного процесса во временный файл.
</p>
<p>Каждая экранная строка, отображаемая в разделе отладки, состоит из
служебной области и области данных. Ширина служебной области равна 6&nbsp;экранным позициям
для &laquo;непараллельных&raquo; заданий и 9&nbsp;позициям для заданий по параллельному программированию. Ширина
области данных равна 80 позициям.
<p>Каждая экранная строка, отображаемая в разделе отладки, состоит из
служебной области и области данных. Ширина служебной области равна 6&nbsp;экранным позициям
для &laquo;непараллельных&raquo; заданий и 9&nbsp;позициям для заданий по параллельному программированию. Ширина
области данных равна 80 позициям.
</p>
<p>Служебная область состоит из следующих частей (см. рисунки,
приведенные выше):
<p>Служебная область состоит из следующих частей (см. рисунки,
приведенные выше):
</p>
<ul><li> <i>область нумерации процессов</i> (только для заданий по
параллельному программированию): 2 экранные позиции,
отводимые для ранга процесса, и символ &laquo;|&raquo;;
<li> <i>область нумерации строк</i>: 3 экранные позиции, отводимые
для номера строки данных, после которых следует символ
&laquo;&gt;&raquo; и символ пробела;
<li> <i>область признака сообщения об ошибке</i>: одна экранная
позиция, в которой может содержаться либо пробел (признак
обычного отладочного текста), либо символ &laquo;!&raquo;
(признак сообщения об ошибке).
<ul><li> <i>область нумерации процессов</i> (только для заданий по
параллельному программированию): 2 экранные позиции,
отводимые для ранга процесса, и символ &laquo;|&raquo;;
<li> <i>область нумерации строк</i>: 3 экранные позиции, отводимые
для номера строки данных, после которых следует символ
&laquo;&gt;&raquo; и символ пробела;
<li> <i>область признака сообщения об ошибке</i>: одна экранная
позиция, в которой может содержаться либо пробел (признак
обычного отладочного текста), либо символ &laquo;!&raquo;
(признак сообщения об ошибке).
</ul>
<p>Если в разделе отладки выводится текст, связанный со всеми
процессами параллельного приложения (этот текст связан с ярлычком
&laquo;*&raquo;), то нумерация строк для каждого процесса производится
независимо.
<p>Если в разделе отладки выводится текст, связанный со всеми
процессами параллельного приложения (этот текст связан с ярлычком
&laquo;*&raquo;), то нумерация строк для каждого процесса производится
независимо.
</p>
<p>При переключении между областями вывода, связанными с
различными процессами параллельного приложения, сохраняется номер
первой отображаемой строки (за исключением ситуации, когда в новой
области вывода отсутствует строка с требуемым номером; в этом случае в
новой области вывод осуществляется, начиная с первой строки данных).
Отмеченная особенность позволяет быстро просмотреть (и сравнить) один
и тот же фрагмент отладочных данных для различных процессов.
<p>При переключении между областями вывода, связанными с
различными процессами параллельного приложения, сохраняется номер
первой отображаемой строки (за исключением ситуации, когда в новой
области вывода отсутствует строка с требуемым номером; в этом случае в
новой области вывод осуществляется, начиная с первой строки данных).
Отмеченная особенность позволяет быстро просмотреть (и сравнить) один
и тот же фрагмент отладочных данных для различных процессов.
</p>
<p>Содержимое области вывода, отображаемой в разделе отладки, можно
копировать в буфер Windows; для этого предназначена стандартная
клавиатурная комбинация <b>Ctrl+C</b> и соответствующая команда
контекстного меню раздела отладки.
<p>Содержимое области вывода, отображаемой в разделе отладки, можно
копировать в буфер Windows; для этого предназначена стандартная
клавиатурная комбинация <b>Ctrl+C</b> и соответствующая команда
контекстного меню раздела отладки.
</p>
<p>Для вывода данных в раздел отладки предназначены процедуры Show и ShowLine.
Описания этих процедур приводятся
в разделе, посвященном <a href="IO.html#debug">типам и процедурам модуля PT4</a>.
<p>Для вывода данных в раздел отладки предназначены процедуры Show и ShowLine.
Описания этих процедур приводятся
в разделе, посвященном <a href="IO.html#debug">типам и процедурам модуля PT4</a>.
</p>
<p>Возможность использования раздела отладки сохранена и в появившемся в версии 4.11
<a href="window.html#dynmode">режиме окна с динамической компоновкой</a>. Как и в окне с фиксированной компоновкой,
раздел отладки отображается ниже разделов с заданием, однако в данном случае
для всех разделов окна используется общая полоса прокрутки. В окне с динамической
компоновкой доступны почти все описанные выше действия по управлению разделом отладки,
в частности, настройка размера шрифта в разделе отладки, копирование содержимого раздела отладки
в буфер Windows, скрытие разделов окна с заданием.
<p>Возможность использования раздела отладки сохранена и в появившемся в версии 4.11
<a href="window.html#dynmode">режиме окна с динамической компоновкой</a>. Как и в окне с фиксированной компоновкой,
раздел отладки отображается ниже разделов с заданием, однако в данном случае
для всех разделов окна используется общая полоса прокрутки. В окне с динамической
компоновкой доступны почти все описанные выше действия по управлению разделом отладки,
в частности, настройка размера шрифта в разделе отладки, копирование содержимого раздела отладки
в буфер Windows, скрытие разделов окна с заданием.
</p>
<blockquote>
@ -191,12 +191,12 @@
</blockquote>
<p>В режиме с динамической компоновкой отсутствует возможность
просмотра областей вывода, связанных с отдельными процессами параллельной программы:
раздел отладки всегда содержит объединенный текст, полученный
из всех областей. Для просмотра содержимого отдельных областей вывода
следует переключиться в режим окна с фиксированной компоновкой, нажав
клавишу <b>F4</b>.
<p>В режиме с динамической компоновкой отсутствует возможность
просмотра областей вывода, связанных с отдельными процессами параллельной программы:
раздел отладки всегда содержит объединенный текст, полученный
из всех областей. Для просмотра содержимого отдельных областей вывода
следует переключиться в режим окна с фиксированной компоновкой, нажав
клавишу <b>F4</b>.
</p>

File diff suppressed because it is too large Load diff

View file

@ -8,41 +8,41 @@
<body>
<h1>Анализ Кода Времени Разработки (Intellisense)</h1>
<p>1. Подсказка по
Ctrl+пробел выводит список всех доступных имен. </p>
<h1>Анализ Кода Времени Разработки (Intellisense)</h1>
<p>1. Подсказка по
Ctrl+пробел выводит список всех доступных имен. </p>
<p>
<img src="../images/intellisense1.png">
</p>
<p>
2. Подсказка по Shift+пробел выводит
список всех доступных имен из текущего модуля. Также добавился комментарий ///
который позволяет связать подсказку с элементом программы (процедура, функция,
переменная) </span></p>
2. Подсказка по Shift+пробел выводит
список всех доступных имен из текущего модуля. Также добавился комментарий ///
который позволяет связать подсказку с элементом программы (процедура, функция,
переменная) </span></p>
<p><img src="../images/intellisense2.png">
</p>
<p>3. Подсказка по &quot;точке&quot;. Если после имени
была нажата точка, то выдается список его членов.</p>
<p>3. Подсказка по &quot;точке&quot;. Если после имени
была нажата точка, то выдается список его членов.</p>
<p><img src="../images/intellisense3.png" border="0"></p>
4. Подсказка параметров функций
4. Подсказка параметров функций
<p>
<img src="../images/intellisense4.png">
</p>
<p>
5. Нажатие пробела после операции
new приводит к появлению подсказки,
состоящей только из имен типов только
с типами. Если из контекста понятен тип выражения, то курсор позиционируется
сразу на нужный тип. </span></p>
5. Нажатие пробела после операции
new приводит к появлению подсказки,
состоящей только из имен типов только
с типами. Если из контекста понятен тип выражения, то курсор позиционируется
сразу на нужный тип. </span></p>
<p>
<img src="../images/intellisense5.png"> </p>
<p>
6. Пункты меню &quot;Найти
все ссылки&quot;, &quot;Перейти
к определению&quot;, &quot;Перейти
к реализации&quot;.</span></p>
6. Пункты меню &quot;Найти
все ссылки&quot;, &quot;Перейти
к определению&quot;, &quot;Перейти
к реализации&quot;.</span></p>
<p>
<img src="../images/intellisense6.png"></p>

View file

@ -6946,327 +6946,327 @@
<param name="Local" value="LangGuide\PABCSystemUnit\Files\Extension methods for sequence of T.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Àáñòðàêòíûé ìåòîä">
<param name="Name" value="Абстрактный метод">
<param name="Local" value="LangGuide\Classes\abstractmethods.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Àâòîâûâåäåíèå òèïà ïðè îïèñàíèè">
<param name="Name" value="Автовыведение типа при описании">
<param name="Local" value="LangGuide\Operators\var_statement.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Àâòîêëàññû">
<param name="Name" value="Автоклассы">
<param name="Local" value="LangGuide\Classes\autoclasses.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Àíîíèìíûå êëàññû">
<param name="Name" value="Анонимные классы">
<param name="Local" value="LangGuide\Classes\anontypes.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Àòðèáóò">
<param name="Name" value="Атрибут">
<param name="Local" value="LangGuide\Classes\attributes.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Áåçîïàñíûé ñðåç">
<param name="Name" value="Безопасный срез">
<param name="Local" value="LangGuide\Operations_Expressions\Slice.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Áåñòèïîâûå óêàçàòåëè">
<param name="Name" value="Бестиповые указатели">
<param name="Local" value="LangGuide\Types\pointers.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Áëîê">
<param name="Name" value="Блок">
<param name="Local" value="LangGuide\Operators\beginend.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Âèðòóàëüíûé ìåòîä">
<param name="Name" value="Виртуальный метод">
<param name="Local" value="LangGuide\Classes\virtual.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Âíóòðèáëî÷íîå îïèñàíèå ïåðåìåííîé">
<param name="Name" value="Внутриблочное описание переменной">
<param name="Local" value="LangGuide\Operators\var_statement.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Âîçâåäåíèå â ñòåïåíü">
<param name="Name" value="Возведение в степень">
<param name="Local" value="LangGuide\Operations_Expressions\arithmop.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Äåñòðóêòîð">
<param name="Name" value="Деструктор">
<param name="Local" value="LangGuide\Classes\constrdestr.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Äèíàìè÷åñêèé òèï">
<param name="Name" value="Динамический тип">
<param name="Local" value="LangGuide\Classes\virtual.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Äèðåêòèâû êîìïèëÿòîðà">
<param name="Name" value="Директивы компилятора">
<param name="Local" value="LangGuide\CompilerDirectives\index_directives.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Çàõâàò ïåðåìåííûõ â yield">
<param name="Name" value="Захват переменных в yield">
<param name="Local" value="LangGuide\Operators\yield.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Èìåíîâàííûå àðãóìåíòû">
<param name="Name" value="Именованные аргументы">
<param name="Local" value="LangGuide\ProcFunc\namedarguments.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Èíäåêñíûå ñâîéñòâà">
<param name="Name" value="Индексные свойства">
<param name="Local" value="LangGuide\Classes\indexedproperties.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Èòåðàòîð">
<param name="Name" value="Итератор">
<param name="Local" value="LangGuide\Operators\yield.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Êëþ÷åâûå ñëîâà">
<param name="Name" value="Ключевые слова">
<param name="Local" value="LangGuide\_ProgrStruct_Defs\identifiers.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Êîâàðèàíòíîñòü">
<param name="Name" value="Ковариантность">
<param name="Local" value="LangGuide\Generics\covariance.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Êîììåíòàðèè">
<param name="Name" value="Комментарии">
<param name="Local" value="LangGuide\_ProgrStruct_Defs\comments.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Êîíêàòåíàöèÿ ñòðîê">
<param name="Name" value="Конкатенация строк">
<param name="Local" value="LangGuide\Operations_Expressions\stringop.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Êîíñòðóêòîð">
<param name="Name" value="Конструктор">
<param name="Local" value="LangGuide\Classes\constrdestr.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Êîðîòêèå ñòðîêè">
<param name="Name" value="Короткие строки">
<param name="Local" value="LangGuide\Types\valuestrings.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Êîðòåæ">
<param name="Name" value="Кортеж">
<param name="Local" value="LangGuide\Types\tuples.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Êîðòåæíîå ïðèñâàèâàíèå">
<param name="Name" value="Кортежное присваивание">
<param name="Local" value="LangGuide\Types\tuples.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Ëåêñèêîãðàôè÷åñêîå ñðàâíåíèå ñòðîê">
<param name="Name" value="Лексикографическое сравнение строк">
<param name="Local" value="LangGuide\Types\string.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Ìåòîäû ðàñøèðåíèÿ">
<param name="Name" value="Методы расширения">
<param name="Local" value="LangGuide\Classes\extensionmethods.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Íàñëåäîâàíèå">
<param name="Name" value="Наследование">
<param name="Local" value="LangGuide\Classes\inheritance.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Îáëàñòü äåéñòâèÿ èìåíè">
<param name="Name" value="Область действия имени">
<param name="Local" value="LangGuide\_ProgrStruct_Defs\scope.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Îêíî çàäà÷íèêà">
<param name="Name" value="Окно задачника">
<param name="Local" value="ForEducation\PT4\Window.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Îïåðàòîð âûáîðà">
<param name="Name" value="Оператор выбора">
<param name="Local" value="LangGuide\Operators\case.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Îïåðàòîð îïèñàíèÿ ïåðåìåííîé">
<param name="Name" value="Оператор описания переменной">
<param name="Local" value="LangGuide\Operators\var_statement.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Îïåðàòîð ïðèñâàèâàíèÿ">
<param name="Name" value="Оператор присваивания">
<param name="Local" value="LangGuide\Operators\assign.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Îïåðàòîðíûå ñêîáêè">
<param name="Name" value="Операторные скобки">
<param name="Local" value="LangGuide\Operators\beginend.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Îïåðàöèè ñ ïðîöåäóðíûìè ïåðåìåííûìè">
<param name="Name" value="Операции с процедурными переменными">
<param name="Local" value="LangGuide\Types\proctype.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Îïåðàöèè ñðàâíåíèÿ">
<param name="Name" value="Операции сравнения">
<param name="Local" value="LangGuide\Operations_Expressions\relop.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="îïåðàöèÿ ðàçûìåíîâàíèÿ">
<param name="Name" value="операция разыменования">
<param name="Local" value="LangGuide\Operations_Expressions\pointerop.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Ïàðàìåòðû">
<param name="Name" value="Параметры">
<param name="Local" value="PABCUnits\GraphWPF\Files\BrushType class.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Ïàðàìåòðû ïî óìîë÷àíèþ">
<param name="Name" value="Параметры по умолчанию">
<param name="Local" value="LangGuide\ProcFunc\defaultparams.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Ïåðåãðóçêà èìåí">
<param name="Name" value="Перегрузка имен">
<param name="Local" value="LangGuide\ProcFunc\overloading.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Ïåðåãðóçêà îïåðàöèé">
<param name="Name" value="Перегрузка операций">
<param name="Local" value="LangGuide\Classes\operoverloading.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Ïåðåäà÷à ïàðàìåòðà ïî çíà÷åíèþ">
<param name="Name" value="Передача параметра по значению">
<param name="Local" value="LangGuide\ProcFunc\params.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Ïåðåäà÷à ïàðàìåòðà ïî ññûëêå">
<param name="Name" value="Передача параметра по ссылке">
<param name="Local" value="LangGuide\ProcFunc\params.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Ïîäïðîãðàììà">
<param name="Name" value="Подпрограмма">
<param name="Local" value="LangGuide\ProcFunc\procdef.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Ïîçäíåå ñâÿçûâàíèå">
<param name="Name" value="Позднее связывание">
<param name="Local" value="LangGuide\Classes\virtual.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Ïîëèìîðôèçì">
<param name="Name" value="Полиморфизм">
<param name="Local" value="LangGuide\Classes\virtual.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Ïîðÿäêîâûå òèïû">
<param name="Name" value="Порядковые типы">
<param name="Local" value="LangGuide\Types\index_types.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Ïðèîðèòåò îïåðàöèé">
<param name="Name" value="Приоритет операций">
<param name="Local" value="LangGuide\Operations_Expressions\oppriority.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Ïðîñòðàíñòâî èìåí">
<param name="Name" value="Пространство имен">
<param name="Local" value="LangGuide\_ProgrStruct_Defs\scope.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Ïðîöåäóðà">
<param name="Name" value="Процедура">
<param name="Local" value="LangGuide\ProcFunc\procdef.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Ïðîöåäóðíûé òèï è ïðîöåäóðíûå ïåðåìåííûå">
<param name="Name" value="Процедурный тип и процедурные переменные">
<param name="Local" value="LangGuide\Types\proctype.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Ïóñòîé îïåðàòîð">
<param name="Name" value="Пустой оператор">
<param name="Local" value="LangGuide\Operators\emptyop.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Ðàçäåë èíòåðôåéñà">
<param name="Name" value="Раздел интерфейса">
<param name="Local" value="LangGuide\Modules\indexmodule.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Ðàçäåë ðåàëèçàöèè">
<param name="Name" value="Раздел реализации">
<param name="Local" value="LangGuide\Modules\indexmodule.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Ðàçìåðíûå òèïû">
<param name="Name" value="Размерные типы">
<param name="Local" value="LangGuide\Types\value_ref_types.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Ðàííåå ñâÿçûâàíèå">
<param name="Name" value="Раннее связывание">
<param name="Local" value="LangGuide\Classes\virtual.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Ðàñïàêîâêà êîðòåæà â ïåðåìåííûå">
<param name="Name" value="Распаковка кортежа в переменные">
<param name="Local" value="LangGuide\Types\tuples.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="ðàñøèðåíèå">
<param name="Name" value="расширение">
<param name="Local" value="LangGuide\PABCSystemUnit\Files\Extension methods for array of T.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Ðàñøèðåííûå èíäåêñíûå ñâîéñòâà">
<param name="Name" value="Расширенные индексные свойства">
<param name="Local" value="LangGuide\Classes\indexedproperties.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Ðàñøèðåííûå ñâîéñòâà">
<param name="Name" value="Расширенные свойства">
<param name="Local" value="LangGuide\Classes\properties.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Ðîáîò">
<param name="Name" value="Робот">
<param name="Local" value="ForEducation\Executors\robotstart.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Ñáîðùèê ìóñîðà">
<param name="Name" value="Сборщик мусора">
<param name="Local" value="LangGuide\MemoryManagement\index_memory.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Ñâîéñòâà">
<param name="Name" value="Свойства">
<param name="Local" value="LangGuide\Classes\properties.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Ñîñòàâíîé îïåðàòîð">
<param name="Name" value="Составной оператор">
<param name="Local" value="LangGuide\Operators\beginend.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Ñðåç">
<param name="Name" value="Срез">
<param name="Local" value="LangGuide\Operations_Expressions\Slice.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Ññûëî÷íûå òèïû">
<param name="Name" value="Ссылочные типы">
<param name="Local" value="LangGuide\Types\value_ref_types.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="ñòàòè÷åñêèé">
<param name="Name" value="статический">
<param name="Local" value="LangGuide\Classes\classconstr.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Ñòðóêòóðèðîâàííûå òèïû">
<param name="Name" value="Структурированные типы">
<param name="Local" value="LangGuide\Types\index_types.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Òèï">
<param name="Name" value="Тип">
<param name="Local" value="PABCUnits\GraphWPF\Files\BrushType class.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Òèïèçèðîâàííûå óêàçàòåëè">
<param name="Name" value="Типизированные указатели">
<param name="Local" value="LangGuide\Types\pointers.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Óïðîùåííûé ñèíòàêñèñ ìîäóëåé">
<param name="Name" value="Упрощенный синтаксис модулей">
<param name="Local" value="LangGuide\Modules\simplemodule.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Óïðîùåííûé ñèíòàêñèñ îïèñàíèÿ ïîäïðîãðàìì">
<param name="Name" value="Упрощенный синтаксис описания подпрограмм">
<param name="Local" value="LangGuide\ProcFunc\shortfundef.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Óñëîâíàÿ îïåðàöèÿ">
<param name="Name" value="Условная операция">
<param name="Local" value="LangGuide\Operations_Expressions\IfOperation.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Ôàêòè÷åñêèå ïàðàìåòðû">
<param name="Name" value="Фактические параметры">
<param name="Local" value="LangGuide\ProcFunc\params.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Ôîðìàëüíûå ïàðàìåòðû">
<param name="Name" value="Формальные параметры">
<param name="Local" value="LangGuide\ProcFunc\params.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Ôóíêöèÿ">
<param name="Name" value="Функция">
<param name="Local" value="LangGuide\ProcFunc\procdef.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Öâåò">
<param name="Name" value="Цвет">
<param name="Local" value="PABCUnits\GraphWPF\Files\BrushType class.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Öèêëè÷åñêàÿ çàâèñèìîñòü ìåæäó ìîäóëÿìè">
<param name="Name" value="Циклическая зависимость между модулями">
<param name="Local" value="LangGuide\Modules\cyclemodules.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="×åðòåæíèê">
<param name="Name" value="Чертежник">
<param name="Local" value="ForEducation\Executors\dmstart.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Ýêñïîíåíöèàëüíàÿ ôîðìà âåùåñòâåííîãî ÷èñëà">
<param name="Name" value="Экспоненциальная форма вещественного числа">
<param name="Local" value="LangGuide\Types\real.html">
</OBJECT>
</UL>

View file

@ -2,7 +2,7 @@
<head>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="Keyword" value="Абстрактный метод">
<param name="Keyword" value="Абстрактный метод">
<param name="Keyword" value="abstract">
</object>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
@ -11,13 +11,13 @@
</head>
<body>
<H1><span lang="ru">Абстрактные </span><span lang="ru">м</span>етоды и классы</H1>
<p>Методы<span lang="ru">, предназначенные для переопределения в подклассах,
объявляются с ключевым словом </span><code><b>abstract</b></code>
<span lang="ru">и называются абстрактными. Данные методы являются
<a href="virtual.html">виртуальными</a>,
но ключевое слово </span><code><b>virtual</b></code><span lang="ru">
использовать не нужно. Например:</span></p>
<H1><span lang="ru">Абстрактные </span><span lang="ru">м</span>етоды и классы</H1>
<p>Методы<span lang="ru">, предназначенные для переопределения в подклассах,
объявляются с ключевым словом </span><code><b>abstract</b></code>
<span lang="ru">и называются абстрактными. Данные методы являются
<a href="virtual.html">виртуальными</a>,
но ключевое слово </span><code><b>virtual</b></code><span lang="ru">
использовать не нужно. Например:</span></p>
<blockquote>
<p><code><b>type</b> <br>
&nbsp; Shape = <b>class</b><br>
@ -32,10 +32,10 @@
&nbsp;&nbsp;&nbsp; <b>procedure</b> Draw; <b>abstract</b>;<br>
&nbsp; <b>end</b>;</code></p>
</blockquote>
<p><span lang="ru">Классы, содержащие абстрактные методы, также называются
<em>абстрактными</em>. Экземпляры этих классов создавать нельзя. </span></p>
<p><span lang="ru">Классы с абстрактными методами используются как
&quot;полуфабрикаты&quot; для создания других классов. Например:</span></p>
<p><span lang="ru">Классы, содержащие абстрактные методы, также называются
<em>абстрактными</em>. Экземпляры этих классов создавать нельзя. </span></p>
<p><span lang="ru">Классы с абстрактными методами используются как
&quot;полуфабрикаты&quot; для создания других классов. Например:</span></p>
<blockquote>
<p><code><b>type</b> <br>
&nbsp; Point = <b>class</b>(Shape)<br>
@ -46,12 +46,12 @@
&nbsp;&nbsp;&nbsp; <b>end</b>;<br>
&nbsp; <b>end</b>;</code></p>
</blockquote>
<p><span lang="ru">Использование </span><code><b>override</b></code>
<span lang="ru">при переопределении абстрактных методов обязательно, поскольку
абстрактные методы являются разновидностью виртуальных. </span></p>
<p>Класс можно явно объявить абстрактным, используя ключевое слово <code>
<strong>abstract</strong></code>. Обычно абстрактные классы содержат абстрактные
методы, но необязательно:</p>
<p><span lang="ru">Использование </span><code><b>override</b></code>
<span lang="ru">при переопределении абстрактных методов обязательно, поскольку
абстрактные методы являются разновидностью виртуальных. </span></p>
<p>Класс можно явно объявить абстрактным, используя ключевое слово <code>
<strong>abstract</strong></code>. Обычно абстрактные классы содержат абстрактные
методы, но необязательно:</p>
<blockquote>
<p><code><b>type</b> <br>
&nbsp; A = <strong>abstract</strong><b> class</b>(Shape)<br>

View file

@ -2,7 +2,7 @@
<head>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="Keyword" value="Анонимные классы">
<param name="Keyword" value="Анонимные классы">
</object>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title></title>
@ -10,27 +10,27 @@
</head>
<body>
<H1>Анонимные классы</H1>
<p>Иногда необходимо сгенерировать объект класса на лету, не описывая класс. У
такого класса нет имени (он анонимный), но известен набор полей. </p>
<p>Объект анонимного класса создаётся следующим образом:</p>
<blockquote><code><b>var </b>p := new <strong>class</strong>(Name := 'Иванов',
<H1>Анонимные классы</H1>
<p>Иногда необходимо сгенерировать объект класса на лету, не описывая класс. У
такого класса нет имени (он анонимный), но известен набор полей. </p>
<p>Объект анонимного класса создаётся следующим образом:</p>
<blockquote><code><b>var </b>p := new <strong>class</strong>(Name := 'Иванов',
Age := 20);<br>Println(p.Name,p.Age);</code></blockquote>
<p>У объекта p автоматически генерируются публичные поля Name и Age
соответствующих типов.</p>
<p>Два объекта принадлежат к одному анонимному классу если они имеют одинаковый
набор полей, и эти поля принадлежат к одинаковым типам. Например:</p>
<blockquote><code><b>var </b>p1 := new <strong>class</strong>(Name := 'Петров',
<p>У объекта p автоматически генерируются публичные поля Name и Age
соответствующих типов.</p>
<p>Два объекта принадлежат к одному анонимному классу если они имеют одинаковый
набор полей, и эти поля принадлежат к одинаковым типам. Например:</p>
<blockquote><code><b>var </b>p1 := new <strong>class</strong>(Name := 'Петров',
Age := 21);<br>p1 := p;</code></blockquote>
<p>Если поля безымянного класса инициализируются переменными, то имена полей
можно не писать - они генерируются автоматически и их имена и типы совпадают с
именами и типами переменных. Например:</p>
<blockquote><code><b>var </b>Name := 'Попова';<b><br>var </b>Age := 23;<b><br>
<p>Если поля безымянного класса инициализируются переменными, то имена полей
можно не писать - они генерируются автоматически и их имена и типы совпадают с
именами и типами переменных. Например:</p>
<blockquote><code><b>var </b>Name := 'Попова';<b><br>var </b>Age := 23;<b><br>
var </b>p := new <strong>class</strong>(Name, Age);<br>
Println(p.Name,p.Age);</code></blockquote>
<p>Поля безымянного класса можно также инициализировать переменной с составным
именем, имеющим точечную нотацию. В этом случае в качестве имен полей берутся
последние имена в точечной нотации. Например:</p>
<p>Поля безымянного класса можно также инициализировать переменной с составным
именем, имеющим точечную нотацию. В этом случае в качестве имен полей берутся
последние имена в точечной нотации. Например:</p>
<blockquote><code><strong>var</strong> d := new DateTime(2015,5,15);<br><strong>
var</strong> p := new <strong>class</strong>(d.Day, d.Month, d.Year);<br>Println(p.Day,
p.Month, p.Year);<br>Println(p);</code></blockquote>

View file

@ -3,7 +3,7 @@
<head>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="Keyword" value="Attribute">
<param name="Keyword" value="Атрибут">
<param name="Keyword" value="Атрибут">
</object>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title></title>
@ -11,38 +11,38 @@
</head>
<body>
<H1>Атрибуты</H1>
<p>В языке имеется ограниченное число стандартных атрибутов, задаваемых
ключевыми словами - например: атрибуты уровня доступа public, private и
protected, атрибуты static, virtual и override для методов. </p>
<p>Пользовательские атрибуты (далее просто атрибуты) - специальные языковые
конструкции, позволяющие помечать классы, методы, подпрограммы, параметры
некоторым именем (возможно с параметрами).</p>
<p>Например, для механизма сериализации класс помечается атрибутом
[Serializable], а поля, которые не следует сериализовывать, атрибутом
[NonSerialized]. При Unit-тестировании тестовый метод помечается атрибутом
[Test] или атрибутом [TestCase]. Распознаются атрибуты методом отражения
(рефлексии).</p>
<p>Атрибут - это обычный класс, унаследованный от System.Atribute. Например: </p>
<H1>Атрибуты</H1>
<p>В языке имеется ограниченное число стандартных атрибутов, задаваемых
ключевыми словами - например: атрибуты уровня доступа public, private и
protected, атрибуты static, virtual и override для методов. </p>
<p>Пользовательские атрибуты (далее просто атрибуты) - специальные языковые
конструкции, позволяющие помечать классы, методы, подпрограммы, параметры
некоторым именем (возможно с параметрами).</p>
<p>Например, для механизма сериализации класс помечается атрибутом
[Serializable], а поля, которые не следует сериализовывать, атрибутом
[NonSerialized]. При Unit-тестировании тестовый метод помечается атрибутом
[Test] или атрибутом [TestCase]. Распознаются атрибуты методом отражения
(рефлексии).</p>
<p>Атрибут - это обычный класс, унаследованный от System.Atribute. Например: </p>
<blockquote>
<p><code><b>type </b>AuthorAttribute = <strong>class</strong>(System.Attribute)<br>&nbsp;
<strong>auto</strong> property Name: string;<br>&nbsp; <strong>constructor</strong> (n: string);<br>&nbsp;
<strong>begin</strong><br>&nbsp;&nbsp;&nbsp; name := n;<br>&nbsp; <strong>end</strong>;&nbsp; <strong><br>end</strong>;</code></p>
</blockquote>
<p>Следует обратить внимание, что класс атрибута принято оканчивать на <code>
<p>Следует обратить внимание, что класс атрибута принято оканчивать на <code>
Attribute</code>.</p>
<p>При пометке сущности атрибутом имя атрибута заключается в квадратные скобки. Конструктор атрибута предоставляет
также возможность использовать атрибуты с
параметрами. Например, можно пометить класс
атрибутом <code>AuthorAttribute</code>. </p>
<p>При пометке сущности атрибутом имя атрибута заключается в квадратные скобки. Конструктор атрибута предоставляет
также возможность использовать атрибуты с
параметрами. Например, можно пометить класс
атрибутом <code>AuthorAttribute</code>. </p>
<blockquote>
<p><code>[Author('Alex')]<b><br>type </b>My = <strong>class</strong><br>&nbsp; // ...<strong><br>
end</strong>;</code></p>
</blockquote>
<p>Следует обратить внимание, что окончание <code>Attribute</code> можно не
указывать.</p>
<p>Распознать, помечен ли данный класс атрибутом, можно, используя
отражение: </p>
<p>Следует обратить внимание, что окончание <code>Attribute</code> можно не
указывать.</p>
<p>Распознать, помечен ли данный класс атрибутом, можно, используя
отражение: </p>
<blockquote>
<p><code><strong>begin</strong> <br>&nbsp; <strong>var</strong> t := typeof(My);
<br>&nbsp; <strong>var</strong> attrs := t.GetCustomAttributes(false); <br>&nbsp;
@ -51,7 +51,7 @@ Attribute</code>.</p>
<strong>then</strong> <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Print(auth.Name);
<br><strong>end</strong>.</code></p>
</blockquote>
<p>След</p>
<p>След</p>
</body>
</html>

View file

@ -2,7 +2,7 @@
<head>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="Keyword" value="Автоклассы">
<param name="Keyword" value="Автоклассы">
<param name="Keyword" value="auto">
</object>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
@ -18,19 +18,19 @@
</head>
<body>
<H1>Автоклассы</H1>
<p>При описании класса перед словом <code><strong>class</strong></code> можно поставить слово <code>
<strong>auto</strong></code>. Такие
классы называются автоклассами. Для автоклассов автоматически генерируется
конструктор с параметрами, инициализирующими все поля класса, а также метод
<span class="auto-style1">ToString</span>, выводящий значения всех полей класса. Например:</p>
<H1>Автоклассы</H1>
<p>При описании класса перед словом <code><strong>class</strong></code> можно поставить слово <code>
<strong>auto</strong></code>. Такие
классы называются автоклассами. Для автоклассов автоматически генерируется
конструктор с параметрами, инициализирующими все поля класса, а также метод
<span class="auto-style1">ToString</span>, выводящий значения всех полей класса. Например:</p>
<blockquote><code><b>type</b> Person = <strong>auto class</strong><br>&nbsp;
name: string;<br>&nbsp; age: integer;<br><strong>end</strong>;<br><strong>
var</strong> p := new Person('Иванов',20); // конструктор автокласса
генерируется автоматически<br>Writeln(p); // вызывается сгенерированный
автоматически метод ToString</code></blockquote>
<p>Здесь в отличие от действия writeln по умолчанию выводятся значения не только
публичных, а всех полей.</p>
var</strong> p := new Person('Иванов',20); // конструктор автокласса
генерируется автоматически<br>Writeln(p); // вызывается сгенерированный
автоматически метод ToString</code></blockquote>
<p>Здесь в отличие от действия writeln по умолчанию выводятся значения не только
публичных, а всех полей.</p>
</body>
</html>

View file

@ -2,7 +2,7 @@
<head>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="Keyword" value="Приведение типов в иерархии Предок-Потомок">
<param name="Keyword" value="Приведение типов в иерархии Предок-Потомок">
</object>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
@ -11,12 +11,12 @@
</head>
<body>
<H1>Приведение типов объектов</H1>
<p>Объект производного класса неявно преобразуется к типу
базового класса. Обратное преобразование от типа базового класса
к типу производного класса может быть выполнено только явно с помощью
<a href="../Operations_Expressions/typecast.html">операции приведения типа</a>.</p>
<p>Например:</p>
<H1>Приведение типов объектов</H1>
<p>Объект производного класса неявно преобразуется к типу
базового класса. Обратное преобразование от типа базового класса
к типу производного класса может быть выполнено только явно с помощью
<a href="../Operations_Expressions/typecast.html">операции приведения типа</a>.</p>
<p>Например:</p>
<blockquote>
<p><code><b>type</b><br>
&nbsp; Person =<b> class<br>
@ -31,30 +31,30 @@
&nbsp; </b>p: Person;<br>
&nbsp; s: Student;<br>
<b>begin</b><br>
&nbsp; p := new Student('Иванов',20,3,1); //
неявное преобразование к типу базового класса<br>
&nbsp; s := Student(p); // явное
приведение к типу производного класса <br>
&nbsp; p := new Student('Иванов',20,3,1); //
неявное преобразование к типу базового класса<br>
&nbsp; s := Student(p); // явное
приведение к типу производного класса <br>
<b>end</b>.</code></p>
</blockquote>
<p>При выполнении приведения к производному классу может
возникнуть исключение (если приведение невозможно;
например, если в переменной <code>p</code> на момент
выполнения операции будет храниться объект типа <code>Person</code>).
<p>При выполнении приведения к производному классу может
возникнуть исключение (если приведение невозможно;
например, если в переменной <code>p</code> на момент
выполнения операции будет храниться объект типа <code>Person</code>).
</p>
<p>После приведения к типу производного класса можно обращаться
к любым полям, свойствам и методам производного класса:</p>
<p>После приведения к типу производного класса можно обращаться
к любым полям, свойствам и методам производного класса:</p>
<blockquote>
<p><code>s.IncCourse;</code></p>
</blockquote>
<p>или без присваивания промежуточной переменной:</p>
<p>или без присваивания промежуточной переменной:</p>
<blockquote>
<p><code>Student(p)</code><code>.IncCourse;</code></p>
</blockquote>
<p>Проверка на возможность приведения к типу производного класса
и безопасное приведение к типу производного класса осуществляется с помощью <a href="../Operations_Expressions/isasop.html">операций
<p>Проверка на возможность приведения к типу производного класса
и безопасное приведение к типу производного класса осуществляется с помощью <a href="../Operations_Expressions/isasop.html">операций
</a><a href="../Operations_Expressions/isasop.html"><b><code>is</code></b>
и <code><b>as</b></code></a>.</p>
и <code><b>as</b></code></a>.</p>
</body>
</html>

View file

@ -3,7 +3,7 @@
<head>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="Keyword" value="static">
<param name="Keyword" value="статический">
<param name="Keyword" value="статический">
</object>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title></title>
@ -11,18 +11,18 @@
</head>
<body>
<H1>Статические классы, поля, методы, свойства и конструкторы</H1>
<p>В классе можно объявить так называемые <i>статические</i>
поля, свойства и методы. Они не принадлежат конкретному экземпляру класса, а связаны с
классом. Для их вызова используется точечная нотация, причем, перед точкой
используется не имя объекта, а имя класса. Чтобы поле или свойство или метод сделать
статическим, перед его именем следует указать ключевое слово <code>
<b>static</b></code>. При описании статических свойств в секциях read и write
можно указывать только статические поля или методы.</p>
<p>Например, определим для класса <span lang="en-us">Person </span>количество
созданных объектов этого класса как статическое поле и организуем доступ к этому
полю на чтение с помощью статической функции<span lang="en-us">. </span>После
каждого вызова конструктора значение статического поля будет увеличиваться на 1:</p>
<H1>Статические классы, поля, методы, свойства и конструкторы</H1>
<p>В классе можно объявить так называемые <i>статические</i>
поля, свойства и методы. Они не принадлежат конкретному экземпляру класса, а связаны с
классом. Для их вызова используется точечная нотация, причем, перед точкой
используется не имя объекта, а имя класса. Чтобы поле или свойство или метод сделать
статическим, перед его именем следует указать ключевое слово <code>
<b>static</b></code>. При описании статических свойств в секциях read и write
можно указывать только статические поля или методы.</p>
<p>Например, определим для класса <span lang="en-us">Person </span>количество
созданных объектов этого класса как статическое поле и организуем доступ к этому
полю на чтение с помощью статической функции<span lang="en-us">. </span>После
каждого вызова конструктора значение статического поля будет увеличиваться на 1:</p>
<p><code><b>type</b> <br>
&nbsp; Person = <b>class</b><br>
&nbsp; <b>private</b><br>
@ -43,24 +43,24 @@ property</span></b><span lang="en-us"> Coun: integer <b>read</b> cnt;</span><br>
&nbsp;&nbsp;&nbsp; <b>end</b>;</span><br>
&nbsp; <span lang="en-us"><b>end</b>;</span></code></p>
<p><code><span lang="en-us"><b>begin</b><br>
&nbsp; <b>var</b> p: Person := new Person('</span>Иванов<span lang="en-us">',20);<br>
&nbsp; <b>var</b> p1: Person := new Person('</span>Петров<span lang="en-us">',18);<br>
&nbsp; Writeln(Person.Count); // </span>обращение к классовому методу
&nbsp; <b>var</b> p: Person := new Person('</span>Иванов<span lang="en-us">',20);<br>
&nbsp; <b>var</b> p1: Person := new Person('</span>Петров<span lang="en-us">',18);<br>
&nbsp; Writeln(Person.Count); // </span>обращение к классовому методу
<span lang="en-us">Count<br>
<b>end</b>.</span></code></p>
<p>В отличие от статических полей и методов, обычные поля и методы называются
экземплярными. Из обычных методов можно обращаться к экземплярным и статическим
полям, но из статических методов можно обращаться только к статическим полям.</p>
<p>Аналогично можно определить также статический конструктор,
предназначенный для автоматической инициализации классовых полей. Статический
конструктор<span lang="ru"> описывается с ключевым
словом <code>
<b>static</b></code> и гарантированно вызывается перед вызовом
любого статического метода и&nbsp;созданием первого объекта этого класса.</span></p>
<p>Например, определим в классе <code>Person</code><span lang="en-us">
статическое</span> поле - массив объектов типа <code>Person</code> - и инициализируем его
в статическом конструкторе. Потом указанный массив можно использовать в реализации
статической функции <code>RandomPerson</code>, возвращающей случайный объект типа
<p>В отличие от статических полей и методов, обычные поля и методы называются
экземплярными. Из обычных методов можно обращаться к экземплярным и статическим
полям, но из статических методов можно обращаться только к статическим полям.</p>
<p>Аналогично можно определить также статический конструктор,
предназначенный для автоматической инициализации классовых полей. Статический
конструктор<span lang="ru"> описывается с ключевым
словом <code>
<b>static</b></code> и гарантированно вызывается перед вызовом
любого статического метода и&nbsp;созданием первого объекта этого класса.</span></p>
<p>Например, определим в классе <code>Person</code><span lang="en-us">
статическое</span> поле - массив объектов типа <code>Person</code> - и инициализируем его
в статическом конструкторе. Потом указанный массив можно использовать в реализации
статической функции <code>RandomPerson</code>, возвращающей случайный объект типа
<code>Person</code><span lang="en-us">:</span><span lang="ru"> </span></p>
<blockquote>
<p><code><b>type</b> <br>
@ -73,9 +73,9 @@ property</span></b><span lang="en-us"> Coun: integer <b>read</b> cnt;</span><br>
&nbsp;&nbsp;&nbsp; <b>static</b> constructor; <br>
&nbsp;&nbsp;&nbsp; <b>begin</b><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SetLength(arr,3);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arr[0] := <b>new</b> Person('Иванов',20);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arr[1] := <b>new</b> Person('Петрова',19);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arr[2] := <b>new</b> Person('Попов',35);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arr[0] := <b>new</b> Person('Иванов',20);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arr[1] := <b>new</b> Person('Петрова',19);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arr[2] := <b>new</b> Person('Попов',35);<br>
&nbsp;&nbsp;&nbsp; <b>end</b>;<br>
<span lang="en-us">&nbsp;&nbsp;&nbsp; //...</span><br>
&nbsp;&nbsp;&nbsp; <b>static</b> <b>function</b> RandomPerson: Person; <br>
@ -91,21 +91,21 @@ property</span></b><span lang="en-us"> Coun: integer <b>read</b> cnt;</span><br>
&nbsp;&nbsp;&nbsp; a[i] := Person.RandomPerson;<br>
</span><b>end</b><span lang="en-us">.</span></code></p>
</blockquote>
<p>Класс также можно описывать как статический:</p>
<p>Класс также можно описывать как статический:</p>
<blockquote>
<p><code><b>type</b> <br>
&nbsp; MyStatic = <b>static class<br>&nbsp;&nbsp;&nbsp; static</b> Pi<b>:</b>
real := 3.14;<b><br>&nbsp;&nbsp;&nbsp; static</b> <strong>function</strong>
Pi2 := Pi * Pi;<b><br>&nbsp; end;</b></code></p>
</blockquote>
<p>В этом случает все его методы, поля, свойства и конструкторы должны быть
статическими. Запрещается создавать экземпляры статических классов. Кроме того,
от статических классов нельзя наследовать, статический класс не может быть
предком и статическим классом нельзя инстанцировать обобщенный класс.</p>
<p>Для совместимости с Delphi статические члены класса можно также объявлять с
ключевым словом <code>
<span lang="ru"> <b>c</b></span><b>lass</b></code>, которое в этом контексте
является синонимом <span lang="ru"> <code>
<p>В этом случает все его методы, поля, свойства и конструкторы должны быть
статическими. Запрещается создавать экземпляры статических классов. Кроме того,
от статических классов нельзя наследовать, статический класс не может быть
предком и статическим классом нельзя инстанцировать обобщенный класс.</p>
<p>Для совместимости с Delphi статические члены класса можно также объявлять с
ключевым словом <code>
<span lang="ru"> <b>c</b></span><b>lass</b></code>, которое в этом контексте
является синонимом <span lang="ru"> <code>
<b>static</b></code></span>:</p>
<blockquote>
<p><code><b>type</b> <br>

View file

@ -7,10 +7,10 @@
</head>
<body>
<H1>Предварительное объявление классов</H1>
<p>Два или более класса могут содержать в качестве полей объекты
других классов, циклически ссылающиеся друг на друга. </p>
<p>Например:</p>
<H1>Предварительное объявление классов</H1>
<p>Два или более класса могут содержать в качестве полей объекты
других классов, циклически ссылающиеся друг на друга. </p>
<p>Например:</p>
<blockquote>
<p><code><b>type</b><br>
&nbsp; AAA =<b> class<br>
@ -20,15 +20,15 @@
&nbsp; &nbsp; a: AAA;<br>
&nbsp; <b>end</b>;</code></p>
</blockquote>
<p>Данный код вызовет ошибку компиляции, поскольку тип
<code>BBB</code> в момент описания поля b
еще не определен. В такой ситуации следует воспользоваться предварительным
описанием класса в виде</p>
<p>Данный код вызовет ошибку компиляции, поскольку тип
<code>BBB</code> в момент описания поля b
еще не определен. В такой ситуации следует воспользоваться предварительным
описанием класса в виде</p>
<blockquote>
<p><i>ИмяКласса</i> <code>= <b>class</b></code>;</p>
<p><i>ИмяКласса</i> <code>= <b>class</b></code>;</p>
</blockquote>
<p>Предварительно описанный класс должен быть полностью описан в
той же секции <code><b>type</b></code>:</p>
<p>Предварительно описанный класс должен быть полностью описан в
той же секции <code><b>type</b></code>:</p>
<blockquote>
<p><code><b>type</b><br>
&nbsp; BBB =<b> class</b>;<br>

View file

@ -6,8 +6,8 @@
<param name="Keyword" value="destructor">
<param name="Keyword" value="Create">
<param name="Keyword" value="Destroy">
<param name="Keyword" value="Конструктор">
<param name="Keyword" value="Деструктор">
<param name="Keyword" value="Конструктор">
<param name="Keyword" value="Деструктор">
</object>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title></title>
@ -15,17 +15,17 @@
</head>
<body>
<H1>Конструктор<span lang="ru">ы</span> </H1>
<p>Объекты создаются с помощью специальных
методов, называемых <b><font color="#FF0000"> <i>конструкторами</i></font></b>. </p>
<p>Конструктор представляет собой функцию, создающую объект в
динамической памяти, инициализирующую его поля и возвращающую ссылку на
созданный объект. Эта ссылка обычно сразу присваивается переменной
типа класс. При описании конструктора вместо ключевого слова <code><b>
function</b></code> используется ключевое слово <code>
<b>constructor</b></code>. Кроме того, для конструктора не
указывается тип возвращаемого значения. </p>
<p>Например:</p>
<H1>Конструктор<span lang="ru">ы</span> </H1>
<p>Объекты создаются с помощью специальных
методов, называемых <b><font color="#FF0000"> <i>конструкторами</i></font></b>. </p>
<p>Конструктор представляет собой функцию, создающую объект в
динамической памяти, инициализирующую его поля и возвращающую ссылку на
созданный объект. Эта ссылка обычно сразу присваивается переменной
типа класс. При описании конструктора вместо ключевого слова <code><b>
function</b></code> используется ключевое слово <code>
<b>constructor</b></code>. Кроме того, для конструктора не
указывается тип возвращаемого значения. </p>
<p>Например:</p>
<blockquote>
<p><code><b>type</b> <br>
&nbsp; Person =<b> class<br>
@ -44,9 +44,9 @@ function</b></code>
&nbsp; ag := age;<br>
<b>end</b>;</code></p>
</blockquote>
<p>В <b>PascalABC.NET</b> конструктор
всегда должен иметь имя <code>Create</code>. При описании
конструктора внутри класса можно опускать его имя:</p>
<p>В <b>PascalABC.NET</b> конструктор
всегда должен иметь имя <code>Create</code>. При описании
конструктора внутри класса можно опускать его имя:</p>
<blockquote>
<p><code><b>type</b> <br>&nbsp; Person =<b> class<br></b>&nbsp;&nbsp;&nbsp;
<b>constructor</b> (name: <b>string</b>; age: integer);<br><b>
@ -56,38 +56,38 @@ function</b></code>
<b>&nbsp;&nbsp;&nbsp; end</b>;<br>
&nbsp; <b>end</b>;</code></p>
</blockquote>
<p><span lang="ru">В силу особенностей реализации вызовов конструкторов в </span>
.NET <span lang="ru">в </span><b>PascalABC.NET</b> <span lang="ru">всегда
создается конструктор без параметров (независимо от того, определен ли другой
конструктор). Этот конструктор инициализирует все поля нулевыми значениями
(строковые поля - пустыми строками, логические&nbsp; - значением </span>False)<span lang="ru">.</span></p>
<p>Для вызова конструктора можно использовать два способа.</p>
<p><b>1 способ.</b> В стиле Object Pascal.</p>
<p>Для вызова конструктора следует указать имя класса, за которым следует
точка-разделитель, имя конструктора и список параметров. Например:</p>
<p><span lang="ru">В силу особенностей реализации вызовов конструкторов в </span>
.NET <span lang="ru">в </span><b>PascalABC.NET</b> <span lang="ru">всегда
создается конструктор без параметров (независимо от того, определен ли другой
конструктор). Этот конструктор инициализирует все поля нулевыми значениями
(строковые поля - пустыми строками, логические&nbsp; - значением </span>False)<span lang="ru">.</span></p>
<p>Для вызова конструктора можно использовать два способа.</p>
<p><b>1 способ.</b> В стиле Object Pascal.</p>
<p>Для вызова конструктора следует указать имя класса, за которым следует
точка-разделитель, имя конструктора и список параметров. Например:</p>
<blockquote>
<p><code><b>var</b> p: Person;<br>
p := Person.Create('Иванов',20);</code></p>
p := Person.Create('Иванов',20);</code></p>
</blockquote>
<p><b>2</b><b> способ.</b> С помощью операции <code>new</code> - в
стиле C# (предпочтительный).</p>
<p><b>2</b><b> способ.</b> С помощью операции <code>new</code> - в
стиле C# (предпочтительный).</p>
<blockquote>
<p><code><b>var</b> p: Person;<br>
p := new Person('Иванов',20);</code></p>
p := new Person('Иванов',20);</code></p>
</blockquote>
<p>Деструктор в Object Pascal -
специальная процедура, уничтожающая объект и
освобождающая динамическую память, которую этот объект
занимал. При описании деструктора вместо служебного слова <b><code>procedure</code></b>
используется служебное слово <code><b>destructor</b></code>.</p>
<p>Например:</p>
<p>Деструктор в Object Pascal -
специальная процедура, уничтожающая объект и
освобождающая динамическую память, которую этот объект
занимал. При описании деструктора вместо служебного слова <b><code>procedure</code></b>
используется служебное слово <code><b>destructor</b></code>.</p>
<p>Например:</p>
<blockquote>
<p><code><b>destructor</b> Destroy;<br><b>begin</b><br>&nbsp; ...<br><b>end</b>;</code></p>
</blockquote>
<p>Поскольку в <b>PascalABC.NET</b>
память управляется сборщиком мусора, деструктор в <b>PascalABC.NET</b>
не играет никакой роли и представляет собой обычную
процедуру-метод.</p>
<p>Поскольку в <b>PascalABC.NET</b>
память управляется сборщиком мусора, деструктор в <b>PascalABC.NET</b>
не играет никакой роли и представляет собой обычную
процедуру-метод.</p>
</body>
</html>

View file

@ -9,39 +9,39 @@
</head>
<body>
<H1>Наследование конструкторов</H1>
<p>Правила наследования конструкторов - достаточно сложные. В разных языках
программирования приняты разные решения на этот счет. В частности, в
Delphi Object Pascal все конструкторы наследуются. В
.NET, напротив, конструкторы не наследуются. Причина
такого решения - каждый класс сам должен отвечать за инициализацию своих
экземпляров. Единственное исключение в .NET - если
класс вовсе не определяет конструкторов, то автоматически генерируется
конструктор без параметров, называемый конструктором по умолчанию.</p>
<p>В <b>PascalABC.NET</b> принято промежуточное решение. Если класс не
определяет конструкторов, то все конструкторы предка автоматически генерируются
в потомке, вызывая соответствующие конструкторы предка (можно также говорить,
что они наследуются). Если в классе определяются конструкторы, то конструкторы
предка не генерируются. Конструктор по умолчанию, если он явно не определен,
генерируется автоматически в любом случае <span lang="ru">и является </span>
<H1>Наследование конструкторов</H1>
<p>Правила наследования конструкторов - достаточно сложные. В разных языках
программирования приняты разные решения на этот счет. В частности, в
Delphi Object Pascal все конструкторы наследуются. В
.NET, напротив, конструкторы не наследуются. Причина
такого решения - каждый класс сам должен отвечать за инициализацию своих
экземпляров. Единственное исключение в .NET - если
класс вовсе не определяет конструкторов, то автоматически генерируется
конструктор без параметров, называемый конструктором по умолчанию.</p>
<p>В <b>PascalABC.NET</b> принято промежуточное решение. Если класс не
определяет конструкторов, то все конструкторы предка автоматически генерируются
в потомке, вызывая соответствующие конструкторы предка (можно также говорить,
что они наследуются). Если в классе определяются конструкторы, то конструкторы
предка не генерируются. Конструктор по умолчанию, если он явно не определен,
генерируется автоматически в любом случае <span lang="ru">и является </span>
<code>protected</code><span lang="ru">.</span></p>
<p>Кроме того, в .NET обязательно в конструкторе
потомка первым оператором должен быть вызван конструктор предка; в
Object Pascal это необязательно. Если в <b>
PascalABC.NET</b> конструктор предка вызывается из конструктора потомка, то этот
вызов должен быть первым оператором. Если конструктор предка явно не
вызывается из конструктора потомка, то неявно первым оператором в конструкторе
потомка вызывается конструктор предка по умолчанию (т.е. без параметров). Если
такого конструктора у предка нет (это может быть класс, откомпилированный другим
.NET-компилятором или входящий в стандартную библиотеку
классов - все классы, откомпилированные <b>PascalABC.NET</b>,
имеют конструктор по умолчанию), то возникает ошибка компиляции.</p>
<p>Например:</p>
<p>Кроме того, в .NET обязательно в конструкторе
потомка первым оператором должен быть вызван конструктор предка; в
Object Pascal это необязательно. Если в <b>
PascalABC.NET</b> конструктор предка вызывается из конструктора потомка, то этот
вызов должен быть первым оператором. Если конструктор предка явно не
вызывается из конструктора потомка, то неявно первым оператором в конструкторе
потомка вызывается конструктор предка по умолчанию (т.е. без параметров). Если
такого конструктора у предка нет (это может быть класс, откомпилированный другим
.NET-компилятором или входящий в стандартную библиотеку
классов - все классы, откомпилированные <b>PascalABC.NET</b>,
имеют конструктор по умолчанию), то возникает ошибка компиляции.</p>
<p>Например:</p>
<p><code><b>type</b> <br>
&nbsp; A = <b>class<br>
</b>&nbsp;&nbsp;&nbsp; i: integer;<br>
&nbsp;&nbsp;&nbsp; // конструктор по
умолчанию не определен явно, поэтому генерируется автоматически<br>
&nbsp;&nbsp;&nbsp; // конструктор по
умолчанию не определен явно, поэтому генерируется автоматически<br>
<b>&nbsp;&nbsp;&nbsp; constructor </b>Create(i: integer);<br>
<b>&nbsp;&nbsp;&nbsp; begin<br>
</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Self.i := i;<br>
@ -51,10 +51,10 @@ PascalABC.NET</b>
&nbsp;&nbsp;&nbsp; j: integer;<br>
<b>&nbsp;&nbsp;&nbsp; constructor </b>Create;<br>
<b>&nbsp;&nbsp;&nbsp; begin<br>
</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // конструктор по умолчанию
базового класса вызывается автоматически<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // конструктор по
умолчанию определен явно, поэтому не генерируется автоматически<br>
</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // конструктор по умолчанию
базового класса вызывается автоматически<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // конструктор по
умолчанию определен явно, поэтому не генерируется автоматически<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; j := 1;<br>
&nbsp;&nbsp;&nbsp; <b>end</b>;<br>
<b>&nbsp;&nbsp;&nbsp; constructor </b>Create(i,j: integer);<br>
@ -64,11 +64,11 @@ PascalABC.NET</b>
&nbsp;&nbsp;&nbsp; <b>end</b>;<br>
<b>&nbsp; end</b>;<br>
&nbsp; C =<b> class</b>(B)<br>
&nbsp; // класс не определяет конструкторов, поэтому<br>
&nbsp; // конструктор по умолчанию и <b>
&nbsp; // класс не определяет конструкторов, поэтому<br>
&nbsp; // конструктор по умолчанию и <b>
constructor </b>Create(i,j: integer)&nbsp; &nbsp;<br>
&nbsp; // генерируются автоматически, вызывая в своем
теле соответствующие конструкторы предка<br>
&nbsp; // генерируются автоматически, вызывая в своем
теле соответствующие конструкторы предка<br>
<b>&nbsp; end</b>;<br>
&nbsp;</code></p>
</body>

View file

@ -2,7 +2,7 @@
<head>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="Keyword" value="Методы расширения">
<param name="Keyword" value="Методы расширения">
<param name="Keyword" value="extensionmethod">
</object>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
@ -11,13 +11,13 @@
</head>
<body>
<H1>Методы расширения</H1>
<p>Любой существующий тип, хранящийся во внешней dll, и все типы стандартной
библитеки .NET можно расширить новыми методами. Метод расширения определяется
как процедура или функция с модификатором <code> <strong>
extensionmethod</strong></code>. Первый параметр метода расширения
обязательно должен иметь имя Self и принадлежит к расширяемому типу. Сравним две
процедуры, описанные ниже:</p>
<H1>Методы расширения</H1>
<p>Любой существующий тип, хранящийся во внешней dll, и все типы стандартной
библитеки .NET можно расширить новыми методами. Метод расширения определяется
как процедура или функция с модификатором <code> <strong>
extensionmethod</strong></code>. Первый параметр метода расширения
обязательно должен иметь имя Self и принадлежит к расширяемому типу. Сравним две
процедуры, описанные ниже:</p>
<blockquote><code><strong>procedure</strong> MyPrint(Self: integer);<br><strong>begin</strong><br>&nbsp; writeln(Self)<br>
<strong>end</strong>;<br>
<strong><br>procedure</strong> MyPrintEx(Self: integer); <strong>
@ -25,29 +25,29 @@
<strong>end</strong>;<br>
<br><strong>begin<br></strong>&nbsp; MyPrint(1);<br>&nbsp; 1.MyPrintEx;<br>
<strong>end</strong>.</code></blockquote>
<p>Здесь MyPrint - это обычная процедура с параметром типа integer, MyPrintEx -
метод расширения типа integer. При этом при вызове первый параметр MyPrintEx
становится объектом, вызывающим MyPrintEx как метод.</p>
<p>Можно расширить тип последовательности, тогда все классы, являющиеся
последовательностями (динамические одномерные массивы, списки List&lt;T&gt;, множества
HashSet&lt;T&gt; и SortedSet&lt;T&gt;),
получат этот метод. Например, в системном модуле PABCSystem так введен метод
расширения ForEach для последовательностей:</p>
<p>Здесь MyPrint - это обычная процедура с параметром типа integer, MyPrintEx -
метод расширения типа integer. При этом при вызове первый параметр MyPrintEx
становится объектом, вызывающим MyPrintEx как метод.</p>
<p>Можно расширить тип последовательности, тогда все классы, являющиеся
последовательностями (динамические одномерные массивы, списки List&lt;T&gt;, множества
HashSet&lt;T&gt; и SortedSet&lt;T&gt;),
получат этот метод. Например, в системном модуле PABCSystem так введен метод
расширения ForEach для последовательностей:</p>
<blockquote><code><strong>procedure</strong> &amp;ForEach&lt;T&gt;(Self: <strong>sequence
of</strong> T; action: T -&gt; ()); <strong>extensionmethod</strong>;<br>
<strong>begin</strong><br>&nbsp; <strong>foreach</strong> x: T <strong>in</strong>
Self <strong>do</strong><br>&nbsp;&nbsp;&nbsp; action(x);<br><strong>end</strong>;</code></blockquote>
<p>С помощью методов расширения можно <a href="operoverloading.html">перегружать
операции</a>:</p>
<p>С помощью методов расширения можно <a href="operoverloading.html">перегружать
операции</a>:</p>
<blockquote><code><strong>procedure operator</strong>+=&lt;T&gt;(a: List&lt;T&gt;; x: T):
List&lt;T&gt;; <strong>extensionmethod</strong>;<br><strong>begin</strong><br>&nbsp;
a.Add(x);<br><strong>end</strong>;</code></blockquote>
<p>В этом случае первый параметр не обязан иметь имя Self.</p>
<p>Для методов расширения имеется ряд ограничений:</p>
<p>В этом случае первый параметр не обязан иметь имя Self.</p>
<p>Для методов расширения имеется ряд ограничений:</p>
<ul>
<li>Методы расширения не могут быть виртуальными.</li>
<li>Если метод расширения имеет то же имя, что и обычный метод, то
предпочтение отдаётся обычному методу. </li>
<li>Методы расширения не могут быть виртуальными.</li>
<li>Если метод расширения имеет то же имя, что и обычный метод, то
предпочтение отдаётся обычному методу. </li>
</ul>
<p>&nbsp;</p>
</body>

View file

@ -6,7 +6,7 @@
<param name="Keyword" value="sealed">
</object>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title>Классы и объекты: обзор</title>
<title>Классы и объекты: обзор</title>
<link rel="StyleSheet" href="../../default.css">
<style type="text/css">
.auto-style1 {
@ -18,31 +18,31 @@
</head>
<body>
<H1>Обзор классов и объектов</H1>
<h2>Описание классов</h2>
<p>Класс представляет собой составной тип, состоящий из полей
(переменных), <A href="methods.html">методов</A> (процедур и функций)
и <A href="properties.html">свойств</A>. Описание класса имеет вид:</p>
<H1>Обзор классов и объектов</H1>
<h2>Описание классов</h2>
<p>Класс представляет собой составной тип, состоящий из полей
(переменных), <A href="methods.html">методов</A> (процедур и функций)
и <A href="properties.html">свойств</A>. Описание класса имеет вид:</p>
<blockquote>
<p><code><b>type</b> <br>
&nbsp; <code class="codeit">имя класса</code><b> </b>=<b> class</b><br>
&nbsp; <code class="codeit">&nbsp; секция1</code>&nbsp; <br>&nbsp;
<code class="codeit">&nbsp; секция2</code>&nbsp; <br><code class="codeit">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp; <code class="codeit">имя класса</code><b> </b>=<b> class</b><br>
&nbsp; <code class="codeit">&nbsp; секция1</code>&nbsp; <br>&nbsp;
<code class="codeit">&nbsp; секция2</code>&nbsp; <br><code class="codeit">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
...</code><br>
&nbsp; <b>end</b>;</code></p>
</blockquote>
<p>Каждая секция имеет вид:</p>
<p>Каждая секция имеет вид:</p>
<blockquote>
<p><code><code class="codeit"><A href="visibility.html">модификатор доступа</A></code>&nbsp;
<br><code class="codeit">&nbsp;&nbsp; описания полей</code><br>
<p><code><code class="codeit"><A href="visibility.html">модификатор доступа</A></code>&nbsp;
<br><code class="codeit">&nbsp;&nbsp; описания полей</code><br>
<code class="codeit">&nbsp;&nbsp;
объявления или описания методов и описания свойств</code></code></p>
объявления или описания методов и описания свойств</code></code></p>
</blockquote>
<p>Модификатор доступа в первой секции может отсутствовать, при этом
подразумевается модификатор <strong><span class="auto-style1">internal</span></strong>
(видимость всюду внутри сборки).</p>
<p>Методы могут описываться как внутри, так и вне класса. При описании метода
внутри класса его имя предваряется именем класса с последующей точкой. Например:</p>
<p>Модификатор доступа в первой секции может отсутствовать, при этом
подразумевается модификатор <strong><span class="auto-style1">internal</span></strong>
(видимость всюду внутри сборки).</p>
<p>Методы могут описываться как внутри, так и вне класса. При описании метода
внутри класса его имя предваряется именем класса с последующей точкой. Например:</p>
<blockquote>
<p><code><b>type</b><br>
&nbsp; Person = <strong>class</strong><b><br>
@ -58,49 +58,49 @@
Print;<br><b>&nbsp;&nbsp;&nbsp; property</b> Name: string read fName;<br><b>&nbsp;&nbsp;&nbsp;
property</b> Age: integer read fAge;<b><br>&nbsp; end</b>;<br><strong><br>
procedure</strong> Person.Print;<br><strong>begin</strong><br>&nbsp;
Writeln($'Имя: {Name} Возраст: {Age}');<br><strong>end</strong>;</code></p>
Writeln($'Имя: {Name} Возраст: {Age}');<br><strong>end</strong>;</code></p>
</blockquote>
<p>После слова <code><b>class</b></code>
в скобках может быть указано имя класса-предка (см. <A href="inheritance.html">
Наследование</A>), а также через запятую список поддерживаемых
<A href="../Interfaces/indexinterf.html">интерфейсов</A>. </p>
<p>Перед словом <code><b>class</b></code>
может быть указано ключевое слово <code><b>sealed</b></code> в
этом случае от класса запрещено <A href="inheritance.html">наследовать</A>.</p>
<p>Все описания и объявления внутри класса образуют <b>
<font color="#ff0000"><i>тело класса</i></font></b>. Поля и
методы образуют <b><font color="#ff0000"> <i>интерфейс</i></font></b> класса. Инициализаторы полей описаны <A href="initfields.html">здесь</A>. </p>
<p>Классы могут описываться только на глобальном уровне. Локальные определения классов (т.е. определения в
разделе описания подпрограмм) запрещены.</p>
<h2>Переменные типа класс</h2>
<p>В языке <strong>PascalABC.NET</strong> классы являются
<A href="../Types/value_ref_types.html">ссылочными типами</A>.
Это значит, что переменная типа класс хранит в действительности ссылку на
объект. </p>
<p>Переменные типа класс называются <b><font color="#ff0000"><i>объектами</i></font></b>
или <b><font color="#ff0000"><i>экземплярами класса</i></font></b>. Они
инициализируются вызовом <A href="constrdestr.html">конструктора</A> класса -
специального метода, выделяющего память под объект класса и инициализирующего
его поля:</p>
<p>После слова <code><b>class</b></code>
в скобках может быть указано имя класса-предка (см. <A href="inheritance.html">
Наследование</A>), а также через запятую список поддерживаемых
<A href="../Interfaces/indexinterf.html">интерфейсов</A>. </p>
<p>Перед словом <code><b>class</b></code>
может быть указано ключевое слово <code><b>sealed</b></code> в
этом случае от класса запрещено <A href="inheritance.html">наследовать</A>.</p>
<p>Все описания и объявления внутри класса образуют <b>
<font color="#ff0000"><i>тело класса</i></font></b>. Поля и
методы образуют <b><font color="#ff0000"> <i>интерфейс</i></font></b> класса. Инициализаторы полей описаны <A href="initfields.html">здесь</A>. </p>
<p>Классы могут описываться только на глобальном уровне. Локальные определения классов (т.е. определения в
разделе описания подпрограмм) запрещены.</p>
<h2>Переменные типа класс</h2>
<p>В языке <strong>PascalABC.NET</strong> классы являются
<A href="../Types/value_ref_types.html">ссылочными типами</A>.
Это значит, что переменная типа класс хранит в действительности ссылку на
объект. </p>
<p>Переменные типа класс называются <b><font color="#ff0000"><i>объектами</i></font></b>
или <b><font color="#ff0000"><i>экземплярами класса</i></font></b>. Они
инициализируются вызовом <A href="constrdestr.html">конструктора</A> класса -
специального метода, выделяющего память под объект класса и инициализирующего
его поля:</p>
<blockquote>
<p><code><strong>var</strong> p: Person := new Person('Иванов',20);</code></p>
<p><code><strong>var</strong> p: Person := new Person('Иванов',20);</code></p>
</blockquote>
<p>После инициализации через переменную типа класс можно обращаться к публичным
членам класса (полям, методам, свойствам), используя точечную нотацию:</p>
<p>После инициализации через переменную типа класс можно обращаться к публичным
членам класса (полям, методам, свойствам), используя точечную нотацию:</p>
<blockquote>
<p><code>Print(p.Name,p.Age);<br>p.Print;</code></p>
</blockquote>
<h2>Вывод переменной типа класс</h2>
<p>По умолчанию процедура <code>Write</code> для переменной типа класс выводит
содержимое её публичных полей и свойств в круглых скобках через запятую:</p>
<h2>Вывод переменной типа класс</h2>
<p>По умолчанию процедура <code>Write</code> для переменной типа класс выводит
содержимое её публичных полей и свойств в круглых скобках через запятую:</p>
<blockquote>
<p><code>Write(p); // Иванов 20</code></p>
<p><code>Write(p); // Иванов 20</code></p>
</blockquote>
<p>Чтобы изменить это поведение, в классе следует
<A href="../Classes/virtual.html">переопределить</A> виртуальный метод
<code>ToString</code> класса <code>Object</code> - в этом случае именно он будет
вызываться при выводе объекта. </p>
<p>Например:</p>
<p>Чтобы изменить это поведение, в классе следует
<A href="../Classes/virtual.html">переопределить</A> виртуальный метод
<code>ToString</code> класса <code>Object</code> - в этом случае именно он будет
вызываться при выводе объекта. </p>
<p>Например:</p>
<blockquote>
<p><code><b>type</b><br>
&nbsp; Person = <b>class<br>
@ -110,45 +110,45 @@
string; <b>override</b>;<br>
<b>&nbsp;&nbsp;&nbsp; begin</b><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Result :=
$'Имя: {Name} Возраст: {Age}'; <br>
$'Имя: {Name} Возраст: {Age}'; <br>
<b>&nbsp;&nbsp;&nbsp; end</b>;<br>
<b>&nbsp; end</b>;<br>
&nbsp; ...<br>
<b>var</b> p: Person := new Person('Иванов',20);<br>
Writeln(p); // Имя: Иванов&nbsp; Возраст: 20</code></p>
<b>var</b> p: Person := new Person('Иванов',20);<br>
Writeln(p); // Имя: Иванов&nbsp; Возраст: 20</code></p>
</blockquote>
<h2>Присваивание и передача в качестве параметров подпрограмм</h2>
<p>Переменная типа класс является ссылкой и хранит ссылку на объект, создаваемый
вызовом конструктора.</p>
<p>Как ссылка переменная типа класс может хранить значение <code>
<h2>Присваивание и передача в качестве параметров подпрограмм</h2>
<p>Переменная типа класс является ссылкой и хранит ссылку на объект, создаваемый
вызовом конструктора.</p>
<p>Как ссылка переменная типа класс может хранить значение <code>
<b>nil</b></code>:</p>
<blockquote>
<p><code>p :=<b> nil</b>;<br>
...<br>
if p =<b> nil</b> then ...</code></p>
</blockquote>
<p>При присваивании переменных типа класс копируется только ссылка. После
присваивания обе переменные типа класс будут ссылаться на один объект
и совместно модифицировать его:</p>
<p>При присваивании переменных типа класс копируется только ссылка. После
присваивания обе переменные типа класс будут ссылаться на один объект
и совместно модифицировать его:</p>
<blockquote>
<p><code><b>var</b> p1,p2: Person;<br>
...<br>
p1 := new Person('Петров',20);<br>
p1 := new Person('Петров',20);<br>
p2 := p1;<br>
p1.IncAge;<br>
p2.Print; // Имя: Петров&nbsp;
Возраст: 21</code></p>
p2.Print; // Имя: Петров&nbsp;
Возраст: 21</code></p>
</blockquote>
<h2>Сравнение на равенство</h2>
<p>При сравнении переменных типа класс на равенство сравниваются ссылки, а не
значения. </p>
<h2>Сравнение на равенство</h2>
<p>При сравнении переменных типа класс на равенство сравниваются ссылки, а не
значения. </p>
<blockquote>
<p><code><b>var</b> p1 := new Person('Петров',20);<br><b>var</b> p2 := new
Person('Петров',20);<br>writeln(p1=p2); // False<br>
<p><code><b>var</b> p1 := new Person('Петров',20);<br><b>var</b> p2 := new
Person('Петров',20);<br>writeln(p1=p2); // False<br>
p2 := p1; <br>
writeln(p1=p2); // True</code></p>
</blockquote>
<p>Это поведение можно изменить, <A href="operoverloading.html">перегрузив</A>
операцию = для класса.</p>
<p>Это поведение можно изменить, <A href="operoverloading.html">перегрузив</A>
операцию = для класса.</p>
</body>

View file

@ -2,8 +2,8 @@
<head>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="Keyword" value="Индексные свойства">
<param name="Keyword" value="Расширенные индексные свойства">
<param name="Keyword" value="Индексные свойства">
<param name="Keyword" value="Расширенные индексные свойства">
</object>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title></title>
@ -11,64 +11,64 @@
</head>
<body>
<H1>Индексные свойства</H1>
<p>Индексные свойства ведут себя аналогично полям-массивам и
используются, как правило, для доступа к элементам контейнеров.
Как и при использовании обычных свойств, при использовании индексных свойств
могут попутно выполняться некоторые действия.
<H1>Индексные свойства</H1>
<p>Индексные свойства ведут себя аналогично полям-массивам и
используются, как правило, для доступа к элементам контейнеров.
Как и при использовании обычных свойств, при использовании индексных свойств
могут попутно выполняться некоторые действия.
</p>
<p>Индексное свойство описывается в классе следующим
образом:</p>
<p>Индексное свойство описывается в классе следующим
образом:</p>
<blockquote>
<p><code><b>property</b> Prop[<code class="codeit">описание индексов</code>]: <code class="codeit">тип</code> <b>read</b>
<p><code><b>property</b> Prop[<code class="codeit">описание индексов</code>]: <code class="codeit">тип</code> <b>read</b>
<code class="codeit">IndexedPropertyReader</code> <b>
write</b>
<code class="codeit">IndexedPropertyWriter</code>;</code></p>
</blockquote>
<p>В качестве <code><code class="codeit">IndexedPropertyReader</code></code> может
выступать: </p>
<p>В качестве <code><code class="codeit">IndexedPropertyReader</code></code> может
выступать: </p>
<ul>
<li><em>имя функции чтения индексного свойства</em>;</li>
<li><em>выражение</em> соответствующего типа (в этом случае индексное свойство
называется <em>расширенным</em>). </li>
<li><em>имя функции чтения индексного свойства</em>;</li>
<li><em>выражение</em> соответствующего типа (в этом случае индексное свойство
называется <em>расширенным</em>). </li>
</ul>
<p>В качестве <code><code class="codeit">IndexedPropertyWriter</code></code> может
выступать: </p>
<p>В качестве <code><code class="codeit">IndexedPropertyWriter</code></code> может
выступать: </p>
<ul>
<li><em>имя процедуры записи индексного свойства</em>;</li>
<li><em>оператор</em> (в этом случае индексное свойство называется <em>расширенным</em>).
В операторе доступна предопределённая переменная value, в которую помещается
значение для изменения свойства.</li>
<li><em>имя процедуры записи индексного свойства</em>;</li>
<li><em>оператор</em> (в этом случае индексное свойство называется <em>расширенным</em>).
В операторе доступна предопределённая переменная value, в которую помещается
значение для изменения свойства.</li>
</ul>
<p>Функция чтения и процедура записи должны быть методами этого класса и иметь
следующий вид:</p>
<p>Функция чтения и процедура записи должны быть методами этого класса и иметь
следующий вид:</p>
<blockquote>
<p><code><b>function</b> GetProp(<code class="codeit">описание индексов</code>): <code class="codeit">
тип</code>;<b><br>
procedure</b> SetProp(<code class="codeit">описание индексов</code>; value: <code class="codeit">тип</code>);</code></p>
<p><code><b>function</b> GetProp(<code class="codeit">описание индексов</code>): <code class="codeit">
тип</code>;<b><br>
procedure</b> SetProp(<code class="codeit">описание индексов</code>; value: <code class="codeit">тип</code>);</code></p>
</blockquote>
<p>В простейшем случае одного индекса описание индексного свойства выглядит так:</p>
<p>В простейшем случае одного индекса описание индексного свойства выглядит так:</p>
<blockquote>
<p><code><b>property</b> Prop[ind: <code class="codeit">
тип индекса</code>]: <code class="codeit">тип</code> <b>read</b>
тип индекса</code>]: <code class="codeit">тип</code> <b>read</b>
GetProp <b>
write</b> SetProp;</code></p>
</blockquote>
<p>Всякий раз, когда мы для объекта <code>a</code>, содержащего свойство <code>
Prop</code>, выполняем присваивание <code>a.Prop[ind] := value</code>,
вызывается процедура <code>a.SetProp(ind,value)</code>, а
когда считываем значение
<code>a.Prop[ind]</code>, вызывается функция
<p>Всякий раз, когда мы для объекта <code>a</code>, содержащего свойство <code>
Prop</code>, выполняем присваивание <code>a.Prop[ind] := value</code>,
вызывается процедура <code>a.SetProp(ind,value)</code>, а
когда считываем значение
<code>a.Prop[ind]</code>, вызывается функция
<code>a.GetProp(ind)</code>.</p>
<p>Индексное свойство, после которого добавлено ключевое слово <b><code>default</code></b> с последующей <code>;</code>, называется <i><b><font color="#FF0000">ин</font></b><font color="#FF0000"><b>дексным
свойством по умолчанию</b></font></i> и позволяет пользоваться объектами класса как массивами, т.е.
использовать запись <code>a[ind]</code> <i>вместо </i> <code>a.Prop[ind]</code>. </p>
<p>Принципиальное отличие индексных свойств от полей-массивов
состоит в том, что тип индекса может быть произвольным (в частности, строковым).&nbsp;Это
позволяет легко реализовать так называемые ассоциативные массивы, элементы
которых индексируются строками. </p>
<p>В следующем примере индексное свойство используется для закрашивания клеток шахматной доски
белым или в графическом режиме.</p>
<p>Индексное свойство, после которого добавлено ключевое слово <b><code>default</code></b> с последующей <code>;</code>, называется <i><b><font color="#FF0000">ин</font></b><font color="#FF0000"><b>дексным
свойством по умолчанию</b></font></i> и позволяет пользоваться объектами класса как массивами, т.е.
использовать запись <code>a[ind]</code> <i>вместо </i> <code>a.Prop[ind]</code>. </p>
<p>Принципиальное отличие индексных свойств от полей-массивов
состоит в том, что тип индекса может быть произвольным (в частности, строковым).&nbsp;Это
позволяет легко реализовать так называемые ассоциативные массивы, элементы
которых индексируются строками. </p>
<p>В следующем примере индексное свойство используется для закрашивания клеток шахматной доски
белым или в графическом режиме.</p>
<blockquote>
<p><code><strong>uses</strong> GraphWPF;<br><strong>const</strong> <br>&nbsp;
n = 8;<br>&nbsp; sz = 50;<br><strong>type</strong> <br>&nbsp; ChessBoard =
@ -91,9 +91,9 @@ Prop</code>,
to</strong> n <strong>do</strong><br>&nbsp;&nbsp;&nbsp; c[x,y] := Odd(x+y);
<br><strong>end</strong>.</code></p>
</blockquote>
<p>Можно не писать отдельные методы <code>getCell</code> и <code>setCell</code>
для доступа к свойству на чтение и запись, а воспользоваться <em>расширенными
индексными свойствами</em>:</p>
<p>Можно не писать отдельные методы <code>getCell</code> и <code>setCell</code>
для доступа к свойству на чтение и запись, а воспользоваться <em>расширенными
индексными свойствами</em>:</p>
<blockquote>
<p><code><strong>type</strong> <br>&nbsp; ChessBoard = class<br>&nbsp;
<strong>private</strong><br>&nbsp;&nbsp;&nbsp; a: <strong>array</strong> [,]

View file

@ -2,31 +2,31 @@
<head>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="Keyword" value="Наследование">
<param name="Keyword" value="Наследование">
<param name="Keyword" value="final">
</object>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title>Наследование</title>
<title>Наследование</title>
<link rel="StyleSheet" href="../../default.css">
</head>
<body>
<H1>Наследование</H1>
<p>Класс может быть унаследован от другого класса. Класс, от которого наследуют,
называют <font color="#ff0000"><i><b>базовым классом</b></i></font>
(<font color="#ff0000"><i><b>надклассом</b></i></font>,
<font color="#ff0000"><i><b>предком</b></i></font>), а класс, который
наследуется, называется <font color="#ff0000"><i><b>производным классом</b></i></font>
(<font color="#ff0000"><i><b>подклассом</b></i></font>,
<font color="#ff0000"><i><b>потомком</b></i></font>). При наследовании все поля,
методы и свойства базового класса переходят в производный класс, кроме этого,
могут быть добавлены новые поля, методы и свойства и переопределены (замещены)
старые методы. Конструкторы наследуются по особым правилам, которые
рассматриваются
<A href="constrinheritance.html">здесь</a>.</p>
<p>При описании класса его базовый класс указывается в скобках после слова <code><b>
<H1>Наследование</H1>
<p>Класс может быть унаследован от другого класса. Класс, от которого наследуют,
называют <font color="#ff0000"><i><b>базовым классом</b></i></font>
(<font color="#ff0000"><i><b>надклассом</b></i></font>,
<font color="#ff0000"><i><b>предком</b></i></font>), а класс, который
наследуется, называется <font color="#ff0000"><i><b>производным классом</b></i></font>
(<font color="#ff0000"><i><b>подклассом</b></i></font>,
<font color="#ff0000"><i><b>потомком</b></i></font>). При наследовании все поля,
методы и свойства базового класса переходят в производный класс, кроме этого,
могут быть добавлены новые поля, методы и свойства и переопределены (замещены)
старые методы. Конструкторы наследуются по особым правилам, которые
рассматриваются
<A href="constrinheritance.html">здесь</a>.</p>
<p>При описании класса его базовый класс указывается в скобках после слова <code><b>
class</b></code>.</p>
<p>Например:</p>
<p>Например:</p>
<blockquote>
<p><code><b>type</b> <br>
&nbsp; BaseClass = <b>class<br>
@ -38,17 +38,17 @@ class</b></code>.</p>
&nbsp;&nbsp;&nbsp; <b>procedure</b> r(i: integer); <br>
<b>&nbsp; end</b>;</code></p>
</blockquote>
<p>В данном примере процедура <code>p</code>
переопределяется, а процедура <code>r</code>
добавляется в класс <code>MyClass</code>.</p>
<p>Если не указать имя базового класса, то считается, что класс наследуется от
класса <code>Object</code> - предка всех классов. Например, <code>BaseClass</code>
наследуется от
<p>В данном примере процедура <code>p</code>
переопределяется, а процедура <code>r</code>
добавляется в класс <code>MyClass</code>.</p>
<p>Если не указать имя базового класса, то считается, что класс наследуется от
класса <code>Object</code> - предка всех классов. Например, <code>BaseClass</code>
наследуется от
<code>Object</code>.</p>
<p>Переопределение методов при наследовании рассматривается
<A href="inherited.html">здесь</a>.</p>
<p>Перед словом <code><b>class</b></code>
может быть указано ключевое слово <code><b>sealed</b></code> в этом случае от
класса запрещено наследовать.</p>
<p>Переопределение методов при наследовании рассматривается
<A href="inherited.html">здесь</a>.</p>
<p>Перед словом <code><b>class</b></code>
может быть указано ключевое слово <code><b>sealed</b></code> в этом случае от
класса запрещено наследовать.</p>
</body>

View file

@ -10,11 +10,11 @@
</head>
<body>
<H1>Переопределение методов</H1>
<p>Метод базового класса может быть переопределен (замещен) в подклассах. Если
при этом требуется вызвать метод базового класса, то используется служебное
слово <code><b>inherited</b></code> (англ.-
унаследованный). Например:</p>
<H1>Переопределение методов</H1>
<p>Метод базового класса может быть переопределен (замещен) в подклассах. Если
при этом требуется вызвать метод базового класса, то используется служебное
слово <code><b>inherited</b></code> (англ.-
унаследованный). Например:</p>
<p><code><b>type</b><br>
&nbsp; Person =<b> class<br>
&nbsp; private</b><br>
@ -28,7 +28,7 @@
&nbsp;&nbsp;&nbsp; <b>end</b>;<br>
&nbsp;&nbsp;&nbsp; <b>procedure</b> Print;<br>
&nbsp;&nbsp;&nbsp; <b>begin</b><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Writeln('Имя: ',name,'&nbsp; Возраст: ',age);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Writeln('Имя: ',name,'&nbsp; Возраст: ',age);<br>
&nbsp;&nbsp;&nbsp; <b>end</b>;<br>
&nbsp; <b>end</b>;<br>
&nbsp; <br>&nbsp; Student =<b> class</b>(Person)<br>
@ -45,28 +45,28 @@ integer);<br>
&nbsp;&nbsp;&nbsp; <b>procedure</b> Print;<br>
&nbsp;&nbsp;&nbsp; <b>begin</b><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>inherited</b> Print;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Writeln('Курс: ',course,'&nbsp; Группа: ',group);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Writeln('Курс: ',course,'&nbsp; Группа: ',group);<br>
&nbsp;&nbsp;&nbsp; <b>end</b>;<br>
&nbsp; <b>end</b>;</code></p>
<p>Здесь метод <code>Print</code> производного класса <code>Student</code>
вызывает вначале метод <code>Print</code>, унаследованный от базового класса
<code>Person</code>, с помощью конструкции <code><b>inherited</b> Print</code>.
Аналогично конструктор <code>Create</code> класса <code>Student</code> вызывает
вначале конструктор <code>Create</code> базового класса <code>Person</code>,
также используя служебное слово <code><b>inherited</b></code>. </p>
<p>Правила наследования конструкторов рассматриваются
<a href="constrinheritance.html">здесь</a>.</p>
<p>Следует обратить
внимание, что конструктор базового класса вызывается в этом случае как процедура, а не как
функция, при этом создания нового объекта не происходит.</p>
<p>Если в методе вызывается метод базового класса с теми же параметрами, то
можно использовать запись <span lang="en-us">inherited</span>, не указывая имя
метода и параметры. Например, метод <code>Student.Print</code> можно записать
таким образом:</p>
<p>Здесь метод <code>Print</code> производного класса <code>Student</code>
вызывает вначале метод <code>Print</code>, унаследованный от базового класса
<code>Person</code>, с помощью конструкции <code><b>inherited</b> Print</code>.
Аналогично конструктор <code>Create</code> класса <code>Student</code> вызывает
вначале конструктор <code>Create</code> базового класса <code>Person</code>,
также используя служебное слово <code><b>inherited</b></code>. </p>
<p>Правила наследования конструкторов рассматриваются
<a href="constrinheritance.html">здесь</a>.</p>
<p>Следует обратить
внимание, что конструктор базового класса вызывается в этом случае как процедура, а не как
функция, при этом создания нового объекта не происходит.</p>
<p>Если в методе вызывается метод базового класса с теми же параметрами, то
можно использовать запись <span lang="en-us">inherited</span>, не указывая имя
метода и параметры. Например, метод <code>Student.Print</code> можно записать
таким образом:</p>
<p><code>&nbsp;&nbsp;&nbsp; <b>procedure</b> Print;<br>
&nbsp;&nbsp;&nbsp; <b>begin</b><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>inherited</b>;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; writeln('Курс: ',course,'&nbsp; Группа: ',group);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; writeln('Курс: ',course,'&nbsp; Группа: ',group);<br>
&nbsp;&nbsp;&nbsp; <b>end</b>;<br>
&nbsp;</code></p>
</body>

View file

@ -9,14 +9,14 @@
</head>
<body>
<H1>Инициализаторы полей</H1>
<p>При создании объекта <i><b> его поля инициализируются
автоматически
нулевыми значениями</b></i> если они не инициализированы явно. Их
инициализация может проводиться как в конструкторе, так и непосредственно при
описании. Инициализация поля при описании приводит к тому, что код инициализации
вставляется в начало ВСЕХ конструкторов.</p>
<p>Например:</p>
<H1>Инициализаторы полей</H1>
<p>При создании объекта <i><b> его поля инициализируются
автоматически
нулевыми значениями</b></i> если они не инициализированы явно. Их
инициализация может проводиться как в конструкторе, так и непосредственно при
описании. Инициализация поля при описании приводит к тому, что код инициализации
вставляется в начало ВСЕХ конструкторов.</p>
<p>Например:</p>
<blockquote>
<p><code><b>type</b> <br>
&nbsp; A =<b> class<br>
@ -40,8 +40,8 @@
<b>&nbsp;&nbsp;&nbsp; end</b>;<br>
&nbsp; <b>end</b>;</code></p>
</blockquote>
<p>В данном примере код <code>x:=1; l := new List&lt;integer&gt;</code>&nbsp; вставляется
в начало каждого конструктора.</p>
<p>В данном примере код <code>x:=1; l := new List&lt;integer&gt;</code>&nbsp; вставляется
в начало каждого конструктора.</p>
</body>
</html>

View file

@ -11,18 +11,18 @@
</head>
<body>
<H1>Операции is и as</H1>
<p><b>// Старый текст</b></p>
<p>Операция <code><b>is</b></code> предназначена для проверки того, имеет ли
классовая переменная указанный <a href="virtual.html">динамический тип</a>.
Операция <code><b>as</b></code> позволяет безопасно преобразовать переменную
одного классового типа к другому классовому типу (в отличие от
<a href="classcast.html#ClassCast">явного приведения классового типа</a>). </p>
<p>Если <code>a1</code> - переменная
классового типа, а <code>B</code> - тип класса, то выражение <code>a1 <b>is</b>
<H1>Операции is и as</H1>
<p><b>// Старый текст</b></p>
<p>Операция <code><b>is</b></code> предназначена для проверки того, имеет ли
классовая переменная указанный <a href="virtual.html">динамический тип</a>.
Операция <code><b>as</b></code> позволяет безопасно преобразовать переменную
одного классового типа к другому классовому типу (в отличие от
<a href="classcast.html#ClassCast">явного приведения классового типа</a>). </p>
<p>Если <code>a1</code> - переменная
классового типа, а <code>B</code> - тип класса, то выражение <code>a1 <b>is</b>
B</code>
возвращает <code>True</code> если переменная <code>a1</code> имеет динамический
тип, совпадающий с B или являющийся одним из его потомков, и <code>False</code> в противном случае. Например:</p>
возвращает <code>True</code> если переменная <code>a1</code> имеет динамический
тип, совпадающий с B или являющийся одним из его потомков, и <code>False</code> в противном случае. Например:</p>
<blockquote>
<p><code><b>type</b> <br>
&nbsp; A =<b> class<br>
@ -34,18 +34,18 @@ B</code>
a1 := B.Create;<br>
writeln(a1 <b>is</b> B); // True</code></p>
</blockquote>
<p>Если <code>a1</code> - переменная
классового типа, а <code>B</code> - тип класса, то выражение <code>a1 <b>as</b>
<p>Если <code>a1</code> - переменная
классового типа, а <code>B</code> - тип класса, то выражение <code>a1 <b>as</b>
B</code>
возвращает объект класса <code>B</code>, <code>a1</code> имеет динамический тип
<code>B</code> или производный от него и <b><code>nil</code></b> в противном
случае. Например:</p>
возвращает объект класса <code>B</code>, <code>a1</code> имеет динамический тип
<code>B</code> или производный от него и <b><code>nil</code></b> в противном
случае. Например:</p>
<blockquote>
<p><code><b>var</b> b1: B;<br>
...<br>
b1 := a1 <b>as</b> B;</code><br>
</blockquote>
Фактически последняя строка делает то же, что и следующий фрагмент кода:</p>
Фактически последняя строка делает то же, что и следующий фрагмент кода:</p>
<blockquote>
<p><code><b>if</b> a1 <b>is</b> B <b>then</b><br>&nbsp; b1 := B(a1)<br><b>else</b> b1 :=<b> nil</b>;</code></p>
</blockquote>

View file

@ -9,14 +9,14 @@
</head>
<body>
<H1>Методы</H1>
<p>Методы представляют собой процедуры и функции, объявленные внутри класса или
записи. Особыми разновидностями методов являются конструкторы, деструкторы и
перегруженные операции.</p>
<p>Определение методов можно давать как внутри класса (стиль
Java, C#, C++), так и вне класса (стиль
Delphi, C++). При определении метода вне интерфейса
класса его имя предваряется именем класса с последующей точкой. Например:</p>
<H1>Методы</H1>
<p>Методы представляют собой процедуры и функции, объявленные внутри класса или
записи. Особыми разновидностями методов являются конструкторы, деструкторы и
перегруженные операции.</p>
<p>Определение методов можно давать как внутри класса (стиль
Java, C#, C++), так и вне класса (стиль
Delphi, C++). При определении метода вне интерфейса
класса его имя предваряется именем класса с последующей точкой. Например:</p>
<blockquote>
<p><code><b>type</b> <br>
&nbsp; Rectangle =<b> class</b><br>
@ -35,24 +35,24 @@ Delphi, C++).
&nbsp; Result := abs(x2-x1) * abs(y2-y1);<br>
<b>end</b>;</code></p>
</blockquote>
<p>Обычно когда класс определяется в интерфейсной части модуля, то в интерфейсе
класса производят лишь объявление методов, реализацию же методов класса дают в
секции реализации модуля.</p>
<p>Методы делятся на <i> <span lang="ru">классовые</span></i> и <i>экземплярные</i>.
<span lang="ru">Классовые методы в </span>.NET <span lang="ru">называются
<i>статическими</i>. О</span>бъявлени<span lang="ru">е</span> <span lang="ru">классов</span>ого метода
<span lang="ru">начинается с ключевого слова </span><code><b>class</b></code>. Экземплярные методы
можно вызывать только через переменную-объект класса. <span lang="ru">Классовые</span> же методы не
связаны с конкретным экземпляром класса; их следует
вызывать в виде: </p>
<p>Обычно когда класс определяется в интерфейсной части модуля, то в интерфейсе
класса производят лишь объявление методов, реализацию же методов класса дают в
секции реализации модуля.</p>
<p>Методы делятся на <i> <span lang="ru">классовые</span></i> и <i>экземплярные</i>.
<span lang="ru">Классовые методы в </span>.NET <span lang="ru">называются
<i>статическими</i>. О</span>бъявлени<span lang="ru">е</span> <span lang="ru">классов</span>ого метода
<span lang="ru">начинается с ключевого слова </span><code><b>class</b></code>. Экземплярные методы
можно вызывать только через переменную-объект класса. <span lang="ru">Классовые</span> же методы не
связаны с конкретным экземпляром класса; их следует
вызывать в виде: </p>
<blockquote>
<p><i>имя класса</i><code>.</code><i>имя метода</i><code>(</code><i>параметры</i><code>)</code>
<p><i>имя класса</i><code>.</code><i>имя метода</i><code>(</code><i>параметры</i><code>)</code>
</p>
</blockquote>
<p>Внутри <span lang="ru">классов</span>ого метода не может быть обращения к полям класса, а может
быть только обращение к другим <span lang="ru">классовы</span>м методам. Напротив, экземплярный метод
может вызывать <span lang="ru">классовый</span>.</p>
<p>Например:</p>
<p>Внутри <span lang="ru">классов</span>ого метода не может быть обращения к полям класса, а может
быть только обращение к другим <span lang="ru">классовы</span>м методам. Напротив, экземплярный метод
может вызывать <span lang="ru">классовый</span>.</p>
<p>Например:</p>
<blockquote>
<p><code><b>type</b> <br>&nbsp; Rectangle =<b> class<br>
&nbsp; &nbsp; </b>...<br>
@ -67,13 +67,13 @@ Delphi, C++).
<b>var</b> r := <b>new</b> Rectangle(10,10,100,100);<br>
Rectangle.Move(r,5,5);</code></p>
</blockquote>
<p>По существу, <span lang="ru">классовые</span> методы являются разновидностью
глобальных<span lang="ru"> подпрограмм</span>, но находятся внутри класса, что подчеркивает, что они осуществляют
действия, связанные именно с этим классом. Класс в этом случае выступает только
в роли пространства имен.</p>
<p>Нередко создаются классы, целиком состоящие из <span lang="ru">классовых
</span>методов. Таков, например, класс <code>System.Math</code>,
содержащий определения математических подпрограмм.</p>
<p>По существу, <span lang="ru">классовые</span> методы являются разновидностью
глобальных<span lang="ru"> подпрограмм</span>, но находятся внутри класса, что подчеркивает, что они осуществляют
действия, связанные именно с этим классом. Класс в этом случае выступает только
в роли пространства имен.</p>
<p>Нередко создаются классы, целиком состоящие из <span lang="ru">классовых
</span>методов. Таков, например, класс <code>System.Math</code>,
содержащий определения математических подпрограмм.</p>
</body>
</html>

View file

@ -5,7 +5,7 @@
<param name="Keyword" value="operator">
<param name="Keyword" value="implicit">
<param name="Keyword" value="explicit">
<param name="Keyword" value="Перегрузка операций">
<param name="Keyword" value="Перегрузка операций">
</object>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title></title>
@ -18,18 +18,18 @@
</head>
<body>
<H1>Перегрузка операций</H1>
<p>Перегрузка операций - это средство языка, позволяющее вводить
операции над типами, определяемыми пользователем. В <b>PascalABC.NET</b>
можно использовать только предопределенные значки операций.
Перегрузка операций для типа <code>T</code>, являющегося
классом или записью, осуществляется при помощи статической (классовой) функции-метода со
специальным именем <b><code>operator</code></b> <i>
ЗнакОперации</i>. Перегрузка специальных операций <code>+=</code>, <code>
<H1>Перегрузка операций</H1>
<p>Перегрузка операций - это средство языка, позволяющее вводить
операции над типами, определяемыми пользователем. В <b>PascalABC.NET</b>
можно использовать только предопределенные значки операций.
Перегрузка операций для типа <code>T</code>, являющегося
классом или записью, осуществляется при помощи статической (классовой) функции-метода со
специальным именем <b><code>operator</code></b> <i>
ЗнакОперации</i>. Перегрузка специальных операций <code>+=</code>, <code>
-=</code>, <code>*=</code>, <code>/=</code>
осуществляется с помощью статической процедуры-метода, первый параметр
которой передается по ссылке.</p>
<p>Например:</p>
осуществляется с помощью статической процедуры-метода, первый параметр
которой передается по ссылке.</p>
<p>Например:</p>
<blockquote>
<p><code><b>type</b> <br>&nbsp; Complex = <b>record</b><br>&nbsp;&nbsp;&nbsp; re,im: real;<br>&nbsp;&nbsp;&nbsp;
<strong>static</strong><b><span lang="en-us"> </span>function</b> <b>operator</b>+(a,b: Complex): Complex; <br>&nbsp;&nbsp;&nbsp;
@ -38,36 +38,36 @@
<strong>static</strong><b><span lang="en-us"> </span>function</b> <b>operator</b>=(a,b: Complex): boolean; <br>&nbsp;&nbsp;&nbsp; <b>begin</b><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Result := (a.re = b.re)
<b>and</b> (a.im = b.im);<br>&nbsp;&nbsp;&nbsp; <b>end</b>; <br>&nbsp; <b>end</b>;</code></p>
</blockquote>
<p>Для перегрузки операций действуют следующие правила:</p>
<p>Для перегрузки операций действуют следующие правила:</p>
<ol>
<li>Перегружать можно все операции за исключением
<code>@</code> (взятие адреса), <b><code>as</code></b>,
<code><b>is</b></code>, <code>new</code>. Кроме того,
можно перегружать специальные бинарные операции <code>+=</code>,
<li>Перегружать можно все операции за исключением
<code>@</code> (взятие адреса), <b><code>as</code></b>,
<code><b>is</b></code>, <code>new</code>. Кроме того,
можно перегружать специальные бинарные операции <code>+=</code>,
<code>-=</code>, <code>*=</code>, <code>/=</code>,
не возвращающие значений.</li>
<li>Перегружать можно только еще не перегруженные операции.</li>
<li>Тип по крайней мере одного операнда должен совпадать с
типом класса или записи, внутри которого определена операция.</li>
<li>Перегрузка осуществляется с помощью статической функции-метода,
количество параметров которой совпадает с количеством параметров
соответствующей операции (2 - для бинарной, 1 - для унарной).</li>
<li>Перегрузка операций <code>+=</code>, <code>-=</code>,
не возвращающие значений.</li>
<li>Перегружать можно только еще не перегруженные операции.</li>
<li>Тип по крайней мере одного операнда должен совпадать с
типом класса или записи, внутри которого определена операция.</li>
<li>Перегрузка осуществляется с помощью статической функции-метода,
количество параметров которой совпадает с количеством параметров
соответствующей операции (2 - для бинарной, 1 - для унарной).</li>
<li>Перегрузка операций <code>+=</code>, <code>-=</code>,
<code>*=</code>, <code>/=</code>
для соответствующих операторов
осуществляется с помощью статической процедуры-метода, первый параметр которой передается по
ссылке и имеет тип записи или класса, в котором определяется данная
операция, второй - передается по значению и совместим по присваиванию с
первым. Перегрузка остальных операций осуществляется с помощью статических
функций-методов. </li>
<li>Операции приведения типа <span lang="ru">задаются статическими
функциями, у которых </span>вместо имени <span lang="ru">используется </span>
для соответствующих операторов
осуществляется с помощью статической процедуры-метода, первый параметр которой передается по
ссылке и имеет тип записи или класса, в котором определяется данная
операция, второй - передается по значению и совместим по присваиванию с
первым. Перегрузка остальных операций осуществляется с помощью статических
функций-методов. </li>
<li>Операции приведения типа <span lang="ru">задаются статическими
функциями, у которых </span>вместо имени <span lang="ru">используется </span>
<code><b>operator</b></code> <code><b>implicit</b></code> <span lang="ru">
(для неявного приведения типа) </span>и<span lang="ru">ли </span><code><b>
operator</b></code> <code><b>explicit</b></code> <span lang="ru">(для явного
приведения типа)</span>. </li>
(для неявного приведения типа) </span>и<span lang="ru">ли </span><code><b>
operator</b></code> <code><b>explicit</b></code> <span lang="ru">(для явного
приведения типа)</span>. </li>
</ol>
<p>Например:</p>
<p>Например:</p>
<blockquote>
<p><code><b>type</b> <br>&nbsp; Complex = <b>record</b><br>&nbsp;&nbsp;&nbsp;
...<br>&nbsp;&nbsp;&nbsp;
@ -90,15 +90,15 @@ value: Complex);<br>&nbsp;&nbsp;&nbsp; <b>begin</b><br>&nbsp;&nbsp;&nbsp;&nbsp;&
<br>&nbsp;&nbsp;&nbsp;
<b>end</b>;<br>&nbsp; <b>end</b>;</code></p>
</blockquote>
<p>Можно перегружать операции с помощью <a href="extensionmethods.html">методов расширения</a> - в этом случае при
описании подпрограммы не следует писать слово class. Например, так в системном модуле
реализовано добавление числа к строке:</p>
<p>Можно перегружать операции с помощью <a href="extensionmethods.html">методов расширения</a> - в этом случае при
описании подпрограммы не следует писать слово class. Например, так в системном модуле
реализовано добавление числа к строке:</p>
<blockquote>
<p><code><strong>function</strong> operator+(str: string; n:
integer): string; <strong>extensionmethod</strong>;<br><strong>begin</strong><br>&nbsp; result := str +
n.ToString;<br><strong>end</strong>;</code></p>
</blockquote>
<p>Можно перегружать расширенные операции присваивания +=, -= и т.д.: </p>
<p>Можно перегружать расширенные операции присваивания +=, -= и т.д.: </p>
<blockquote>
<pre><code><strong>type</strong>
t0 = <strong>class
@ -113,10 +113,10 @@ value: Complex);<br>&nbsp;&nbsp;&nbsp; <b>begin</b><br>&nbsp;&nbsp;&nbsp;&nbsp;&
t += 2;
</code><span class="auto-style1"><font size="2"><strong>end</strong>.</font></span></pre>
</blockquote>
<p>Важно отметить, что если слева от расширенного присваивания находится
свойство, то перегруженная форма расширенного присваивания игнорируется и само
расширенное присваивание разворачивается в присваивание и соответствующую
операцию: </p>
<p>Важно отметить, что если слева от расширенного присваивания находится
свойство, то перегруженная форма расширенного присваивания игнорируется и само
расширенное присваивание разворачивается в присваивание и соответствующую
операцию: </p>
<blockquote>
<pre><code><strong>type</strong>
t0 = <strong>class
@ -134,12 +134,12 @@ value: Complex);<br>&nbsp;&nbsp;&nbsp; <b>begin</b><br>&nbsp;&nbsp;&nbsp;&nbsp;&
t.p1 += 2;
</code><span class="auto-style1"><font size="2"><strong>end</strong>.</font></span></pre>
</blockquote>
<p>В данном коде последний оператор расширенного присваивания принудительно
развернется в </p>
<p>В данном коде последний оператор расширенного присваивания принудительно
развернется в </p>
<blockquote>
<pre><code>t.p1 := t.p1 + 2; </code></pre>
</blockquote>
<p>и поскольку для t0 не перегружена операция +, то компилятор выдаст ошибку.</p>
<p>и поскольку для t0 не перегружена операция +, то компилятор выдаст ошибку.</p>
</body>
</html>

View file

@ -5,8 +5,8 @@
<param name="Keyword" value="property">
<param name="Keyword" value="read">
<param name="Keyword" value="write">
<param name="Keyword" value="Свойства">
<param name="Keyword" value="Расширенные свойства">
<param name="Keyword" value="Свойства">
<param name="Keyword" value="Расширенные свойства">
<param name="Keyword" value="value">
<param name="Keyword" value="auto">
</object>
@ -16,58 +16,58 @@
</head>
<body>
<H1>Свойства</H1>
<p>Свойство внешне выглядит как поле
класса, однако, при доступе к нему на чтение или запись позволяет выполнять некоторые действия. Свойство описывается в классе
или записи следующим образом:</p>
<H1>Свойства</H1>
<p>Свойство внешне выглядит как поле
класса, однако, при доступе к нему на чтение или запись позволяет выполнять некоторые действия. Свойство описывается в классе
или записи следующим образом:</p>
<blockquote>
<p><code><b>property</b> Prop: <code class="codeit">тип</code> <b>read</b>
<p><code><b>property</b> Prop: <code class="codeit">тип</code> <b>read</b>
<code class="codeit">PropertyReader</code> <b>
write</b> <code class="codeit">PropertyWriter</code>;</code></p>
</blockquote>
<p>В качестве <code><code class="codeit">PropertyReader</code></code> может
выступать: </p>
<p>В качестве <code><code class="codeit">PropertyReader</code></code> может
выступать: </p>
<ul>
<li><em>имя функции чтения свойства</em>;</li>
<li><em>поле</em> соответствующего типа;</li>
<li><em>выражение</em> соответствующего типа (в этом случае свойство
называется <em>расширенным</em>). </li>
<li><em>имя функции чтения свойства</em>;</li>
<li><em>поле</em> соответствующего типа;</li>
<li><em>выражение</em> соответствующего типа (в этом случае свойство
называется <em>расширенным</em>). </li>
</ul>
<p>В качестве <code><code class="codeit">PropertyWriter</code></code> может
выступать: </p>
<p>В качестве <code><code class="codeit">PropertyWriter</code></code> может
выступать: </p>
<ul>
<li><em>имя процедуры записи свойства</em>;</li>
<li><em>поле</em> соответствующего типа;</li>
<li><em>оператор</em> (в этом случае свойство называется <em>расширенным</em>).
В операторе доступна предопределённая переменная value, в которую помещается
значение для изменения свойства.</li>
<li><em>имя процедуры записи свойства</em>;</li>
<li><em>поле</em> соответствующего типа;</li>
<li><em>оператор</em> (в этом случае свойство называется <em>расширенным</em>).
В операторе доступна предопределённая переменная value, в которую помещается
значение для изменения свойства.</li>
</ul>
<p>Одна из секций - read или write - может быть опущена, в этом случае мы имеем
свойство с доступом только на запись или только на чтение соответственно.</p>
<p>При доступе к свойству на чтение вызывается <code><code class="codeit">
PropertyReader</code></code>, при доступе на запись - <code>
<p>Одна из секций - read или write - может быть опущена, в этом случае мы имеем
свойство с доступом только на запись или только на чтение соответственно.</p>
<p>При доступе к свойству на чтение вызывается <code><code class="codeit">
PropertyReader</code></code>, при доступе на запись - <code>
<code class="codeit">PropertyWriter</code></code>.</p>
<p>Как правило, каждое свойство связано с некоторым полем класса
и возвращает значение этого поля с помощью <i>функции чтения</i>, а меняет - с
помощью <i>процедуры записи</i>. Функция чтения и процедура записи должны быть
методами этого класса и иметь следующий вид:</p>
<p>Как правило, каждое свойство связано с некоторым полем класса
и возвращает значение этого поля с помощью <i>функции чтения</i>, а меняет - с
помощью <i>процедуры записи</i>. Функция чтения и процедура записи должны быть
методами этого класса и иметь следующий вид:</p>
<blockquote>
<p><code><b>function</b> getProp: <code class="codeit">
тип</code>;<b><br>
procedure</b> setProp(value: <code class="codeit">тип</code>);</code>&nbsp;</p>
тип</code>;<b><br>
procedure</b> setProp(value: <code class="codeit">тип</code>);</code>&nbsp;</p>
</blockquote>
<p>Если функция чтения свойства просто возвращает значение некоторого поля, то
вместо её имени можно указать имя этого поля. Аналогично если процедура записи
просто присваивает значение некоторому полю, то вместо её имени можно указать
имя этого поля.</p>
<p>Любая из секций <code><b>read</b></code>
или <code><b>write</b></code> может быть опущена, в этом
случае мы получаем свойство с доступом только на запись или с доступом только на чтение. </p>
<p>Обычно функция чтения и процедура записи описываются в
приватной секции класса. Они могут быть виртуальными, в этом случае их уместно
описывать в защищенной секции класса.</p>
<p>Для начала рассмотрим пример, в котором используются функция чтения и
процедура записи свойства:</p>
<p>Если функция чтения свойства просто возвращает значение некоторого поля, то
вместо её имени можно указать имя этого поля. Аналогично если процедура записи
просто присваивает значение некоторому полю, то вместо её имени можно указать
имя этого поля.</p>
<p>Любая из секций <code><b>read</b></code>
или <code><b>write</b></code> может быть опущена, в этом
случае мы получаем свойство с доступом только на запись или с доступом только на чтение. </p>
<p>Обычно функция чтения и процедура записи описываются в
приватной секции класса. Они могут быть виртуальными, в этом случае их уместно
описывать в защищенной секции класса.</p>
<p>Для начала рассмотрим пример, в котором используются функция чтения и
процедура записи свойства:</p>
<blockquote>
<p><code><b>type</b> <br>
&nbsp; Person =<b> class<br>
@ -102,20 +102,20 @@ PropertyReader</code></code>,
getId;<br><b>&nbsp; end</b>;</code></p>
<p><code><b>begin<br>&nbsp; var</b> p: Person;<br>
&nbsp;
p := new Person('Иванов',20);<br>&nbsp; p.Age := -3; // p.Age = 0 !<br>
&nbsp; p.Age := p.Age + 1; // компилятор заменяет этот код на p.setAge(p.getAge
p := new Person('Иванов',20);<br>&nbsp; p.Age := -3; // p.Age = 0 !<br>
&nbsp; p.Age := p.Age + 1; // компилятор заменяет этот код на p.setAge(p.getAge
+ 1);<br>
&nbsp;
writeln(p.Id); <br><strong>end</strong>.</code></p>
</blockquote>
<p>Всякий раз, когда мы присваиваем свойству <code>Age</code>
новое значение,
вызывается процедура <code>setAge</code> с
соответствующим параметром. Всякий раз, когда мы считываем значение свойства
<code>Age</code>, вызывается функция <code>getAge</code>. </p>
<p>Как уже отмечалось, в тривиальных случаях имя процедуры в секции <code> <b>write</b></code>
свойства и имя функции в секции <code> <b>read</b></code> свойства можно
заменить на имена соответствующих полей. Приведём код с учётом этого замечания:</p>
<p>Всякий раз, когда мы присваиваем свойству <code>Age</code>
новое значение,
вызывается процедура <code>setAge</code> с
соответствующим параметром. Всякий раз, когда мы считываем значение свойства
<code>Age</code>, вызывается функция <code>getAge</code>. </p>
<p>Как уже отмечалось, в тривиальных случаях имя процедуры в секции <code> <b>write</b></code>
свойства и имя функции в секции <code> <b>read</b></code> свойства можно
заменить на имена соответствующих полей. Приведём код с учётом этого замечания:</p>
<blockquote>
<p><code><b>type</b> <br>
&nbsp; Person =<b> class<br>
@ -138,9 +138,9 @@ PropertyReader</code></code>,
fName;<b><br>&nbsp;&nbsp;&nbsp; property</b> Id: string <strong>read
</strong>getId;<b><br>&nbsp; end</b>;</code></p>
</blockquote>
<p>Наконец, воспользуемся <em>расширенными свойствами</em>, заменив <code>getId</code>
на выражение <code>fName + fAge.ToString</code>, а <code>setAge</code> - на
оператор, реализующий тело этой процедуры:</p>
<p>Наконец, воспользуемся <em>расширенными свойствами</em>, заменив <code>getId</code>
на выражение <code>fName + fAge.ToString</code>, а <code>setAge</code> - на
оператор, реализующий тело этой процедуры:</p>
<blockquote>
<p><code><b>type</b> <br>
&nbsp; Person =<b> class<br>
@ -156,12 +156,12 @@ PropertyReader</code></code>,
property</strong> Id: string <strong>read</strong> fName + fAge.ToString;<br>
<b>&nbsp; end</b>;</code></p>
</blockquote>
<p>Заметим, что расширенные свойства имеются только в PascalABC.NET, введены в
язык чтобы не писать отдельно функцию чтения или процедуру записи и отсутстуют в
других версиях Паскаля.</p>
<p>Расширенные свойства удобно использовать во многих ситуациях. Например, когда
обычные свойства рализованы обращением к аналогичным свойствам поля этого
класса:</p>
<p>Заметим, что расширенные свойства имеются только в PascalABC.NET, введены в
язык чтобы не писать отдельно функцию чтения или процедуру записи и отсутстуют в
других версиях Паскаля.</p>
<p>Расширенные свойства удобно использовать во многих ситуациях. Например, когда
обычные свойства рализованы обращением к аналогичным свойствам поля этого
класса:</p>
<blockquote>
<p><code><strong>type</strong><br>&nbsp; MyList&lt;T&gt; = <strong>class</strong><br>&nbsp;
<strong>private</strong> <br>&nbsp;&nbsp;&nbsp; l := new List&lt;T&gt;;<br>&nbsp;
@ -170,56 +170,56 @@ PropertyReader</code></code>,
l.Capacity := <em>value</em>;<br>&nbsp; <strong>end</strong>;</code></p>
<p><code><strong>begin</strong><br><b>&nbsp; var</b> ml := new
MyList&lt;integer&gt;;<br>
&nbsp; ml.Capacity := 5; // доступ на запись: значение 5 копируется в
переменную <em>value</em><br>
&nbsp; Println(ml.Capacity); // доступ на чтение<br><strong>end</strong>.</code></p>
&nbsp; ml.Capacity := 5; // доступ на запись: значение 5 копируется в
переменную <em>value</em><br>
&nbsp; Println(ml.Capacity); // доступ на чтение<br><strong>end</strong>.</code></p>
</blockquote>
<p>Свойства не могут передаваться по ссылке в процедуры и функции. Например,
следующий код ошибочен:</p>
<p>Свойства не могут передаваться по ссылке в процедуры и функции. Например,
следующий код ошибочен:</p>
<blockquote>
<p><code>Inc(p.Age); // ошибка!</code></p>
<p><code>Inc(p.Age); // ошибка!</code></p>
</blockquote>
<p>Если требуется обработать значение свойства, передав его по
ссылке, то надо воспользоваться вспомогательной переменной:</p>
<p>Если требуется обработать значение свойства, передав его по
ссылке, то надо воспользоваться вспомогательной переменной:</p>
<blockquote>
<p><code>a := p.Age;<br>
Inc(a);<br>
p.Age := a;</code></p>
</blockquote>
<p>Однако, свойства соответствующих типов можно использовать в левой части
операций присваивания <code>+= -= *= /=</code>:</p>
<p>Однако, свойства соответствующих типов можно использовать в левой части
операций присваивания <code>+= -= *= /=</code>:</p>
<blockquote>
<p><code>p.Age += 1<span lang="en-us">;</span></code></p>
</blockquote>
<p>Свойства очень удобны при работе с визуальными объектами,
поскольку позволяют автоматически перерисовывать объект, если изменить
какие-либо его визуальные характеристики. Например, если создана
кнопка <code>b1</code> типа <code>
<p>Свойства очень удобны при работе с визуальными объектами,
поскольку позволяют автоматически перерисовывать объект, если изменить
какие-либо его визуальные характеристики. Например, если создана
кнопка <code>b1</code> типа <code>
Button</code>,
то для визуального изменения ее ширины достаточно присвоить значение ее свойству
то для визуального изменения ее ширины достаточно присвоить значение ее свойству
<code>Width</code>:</p>
<blockquote>
<p><code>b1.Width := 100;</code></p>
</blockquote>
<p>Процедура для записи этого свойства в приватное поле <code>fWidth</code> будет выглядеть примерно так:</p>
<p>Процедура для записи этого свойства в приватное поле <code>fWidth</code> будет выглядеть примерно так:</p>
<blockquote>
<p><code><b>procedure</b> SetWidth(w: integer);<br>
<b>begin</b><br>
&nbsp; <b>if</b> (w&gt;0) <b>and</b> (w&lt;&gt;fWidth) <b>then</b> <br>
&nbsp; <b>begin</b><br>
&nbsp;&nbsp;&nbsp; fWidth := w;<br>
</code>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<i>код перерисовки кнопки</i><br>
</code>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<i>код перерисовки кнопки</i><br>
<code>&nbsp; <b>end</b><br>
<b>end</b>;</code></p>
</blockquote>
<p>Следует обратить внимание на вторую часть условия в операторе
<p>Следует обратить внимание на вторую часть условия в операторе
<code><b>if</b></code>: <code>w&lt;&gt;fWidth</code>.
Добавление этой проверки позволяет избежать лишней перерисовки кнопки в случае,
если ее ширина не меняется.</p>
<H1>Автоматически определяемые свойства</H1>
<p>В классе можно определить автосвойство, для которого автоматически
генерируется поле соответствующего типа. Автосвойство в PascalABC.NET доступны и
на чтение и на запись, а также могут иметь значение по умолчанию. Например:</p>
Добавление этой проверки позволяет избежать лишней перерисовки кнопки в случае,
если ее ширина не меняется.</p>
<H1>Автоматически определяемые свойства</H1>
<p>В классе можно определить автосвойство, для которого автоматически
генерируется поле соответствующего типа. Автосвойство в PascalABC.NET доступны и
на чтение и на запись, а также могут иметь значение по умолчанию. Например:</p>
<blockquote>
<p><code><b>type</b> <br>
&nbsp; Position =<b> class<br>
@ -227,7 +227,7 @@ Button</code>,
&nbsp;&nbsp;&nbsp; auto property </b>Row: integer;<br><b>&nbsp;&nbsp;&nbsp;
auto property</b> Col: integer;<br>&nbsp; <strong>end</strong>;</code></p>
</blockquote>
<p>или</p>
<p>или</p>
<blockquote>
<p><code><b>type</b> <br>
&nbsp; Grid =<b> class</b>(CommonElement)<b><br>

View file

@ -10,11 +10,11 @@
</head>
<body>
<H1>Переменная Self</H1>
<p>Внутри каждого нестатического метода неявно определяется переменная
<code>Self</code>, ссылающаяся на объект, вызвавший этот метод.
<H1>Переменная Self</H1>
<p>Внутри каждого нестатического метода неявно определяется переменная
<code>Self</code>, ссылающаяся на объект, вызвавший этот метод.
</p>
<p>Например:</p>
<p>Например:</p>
<blockquote>
<p><code><b>type</b> <br>
&nbsp; A =<b> class</b><br>
@ -25,12 +25,12 @@
&nbsp;&nbsp;&nbsp; <b>end</b>;<br>
&nbsp; <b>end</b>;</code></p>
</blockquote>
<p>В момент вызова конструктора <code>Create</code>
объект будет уже создан. Конструкция <code>Self.i</code>
ссылается на поле <code>i</code> этого объекта, а не на
параметр <code>i</code> функции <code>Create</code>. Фактически в любом
нестатическом методе перед именем любого поля и методу этого класса неявно
присутствует <code>Self.</code></p>
<p>В момент вызова конструктора <code>Create</code>
объект будет уже создан. Конструкция <code>Self.i</code>
ссылается на поле <code>i</code> этого объекта, а не на
параметр <code>i</code> функции <code>Create</code>. Фактически в любом
нестатическом методе перед именем любого поля и методу этого класса неявно
присутствует <code>Self.</code></p>
</body>
</html>

View file

@ -5,11 +5,11 @@
<param name="Keyword" value="virtual">
<param name="Keyword" value="override">
<param name="Keyword" value="reintroduce">
<param name="Keyword" value="Полиморфизм">
<param name="Keyword" value="Виртуальный метод">
<param name="Keyword" value="Динамический тип">
<param name="Keyword" value="Раннее связывание">
<param name="Keyword" value="Позднее связывание">
<param name="Keyword" value="Полиморфизм">
<param name="Keyword" value="Виртуальный метод">
<param name="Keyword" value="Динамический тип">
<param name="Keyword" value="Раннее связывание">
<param name="Keyword" value="Позднее связывание">
</object>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title></title>
@ -17,19 +17,19 @@
</head>
<body>
<H1>Виртуальные методы и полиморфизм</H1>
<p><font color="#FF0000"><i><b>Полиморфизм</b></i></font> (от <i>греч</i>.
&quot;много форм&quot;) - это свойство классов, связанных наследованием, иметь различную
реализацию входящих в них методов, и способность
переменной базового класса вызывать методы того класса, объект которого
содержится в этой переменной в момент вызова метода.</p>
<p>Полиморфизм используется в ситуации, когда для
группы взаимосвязанных объектов требуется выполнить единое действие, но каждый
из этих объектов должен выполнить указанное действие по-своему (т.е. у действия
возникает много форм). Для этого определяется базовый для всех объектов класс с
виртуальными методами, предусмотренными для меняющегося поведения, после чего эти методы
переопределяется в потомках. </p>
<p>Для пояснения рассмотрим переопределение метода в подклассе:</p>
<H1>Виртуальные методы и полиморфизм</H1>
<p><font color="#FF0000"><i><b>Полиморфизм</b></i></font> (от <i>греч</i>.
&quot;много форм&quot;) - это свойство классов, связанных наследованием, иметь различную
реализацию входящих в них методов, и способность
переменной базового класса вызывать методы того класса, объект которого
содержится в этой переменной в момент вызова метода.</p>
<p>Полиморфизм используется в ситуации, когда для
группы взаимосвязанных объектов требуется выполнить единое действие, но каждый
из этих объектов должен выполнить указанное действие по-своему (т.е. у действия
возникает много форм). Для этого определяется базовый для всех объектов класс с
виртуальными методами, предусмотренными для меняющегося поведения, после чего эти методы
переопределяется в потомках. </p>
<p>Для пояснения рассмотрим переопределение метода в подклассе:</p>
<blockquote>
<p><code><b>type</b><br>
&nbsp; Base =<b> class<br>
@ -47,32 +47,32 @@
&nbsp;&nbsp;&nbsp; <b>end</b>;<br>
&nbsp; <b>end</b>;</code> </p>
</blockquote>
<p>Присвоим переменной базового класса <code>Base</code> объект производного
класса <code>Derived</code> и вызовем метод <code>Print</code>.</p>
<p>Присвоим переменной базового класса <code>Base</code> объект производного
класса <code>Derived</code> и вызовем метод <code>Print</code>.</p>
<blockquote>
<p><code><b>var</b> b: Base := new Derived;<br>
b.Print;</code></p>
</blockquote>
<p>Какая версия метода <code>Print</code> вызывается - класса <code>Base</code> или класса <code>Derived</code>?
В данном случае решение будет принято еще на этапе компиляции: вызовется метод
<code>Print</code> класса <code>Base</code>,
заявленного при описании переменной <code>b</code>. Говорят, что имеет место
<font color="#FF0000"><b> <i>раннее связывание</i></b></font> имени метода с его
телом. Если же решение о том,
какой метод вызывать, принимается на этапе выполнения программы в зависимости от
реального типа объекта, на который ссылается переменная <code>b</code>, то
в данном случае вызывается метод <code>Derived.Print</code> (говорят
также, что имеет место <i><font color="#FF0000"><b>позднее связывание</b></font></i>). Методы, для которых
реализуется позднее связывание, называются <i><font color="#FF0000"><b>виртуальными</b></font></i>,
а переменная базового класса, через которую осуществляется вызов виртуального
метода, - <i><font color="#FF0000"><b>полиморфной переменной</b></font></i>.
Таким образом, полиморфизм реализуется вызовом виртуальных функций через
переменную базового класса. Тип класса, который хранится в данной переменной на
этапе выполнения, называется <i><font color="#FF0000"><b>динамическим типом</b></font></i>
этой переменной. </p>
<p>Для того чтобы сделать метод виртуальным, следует в объявлении этого метода
после заголовка указать ключевое слово <code><b>virtual</b></code> с последующей <code>;</code>. Для переопределения виртуального метода
следует использовать ключевое слово <code><b>override</b></code>:</p>
<p>Какая версия метода <code>Print</code> вызывается - класса <code>Base</code> или класса <code>Derived</code>?
В данном случае решение будет принято еще на этапе компиляции: вызовется метод
<code>Print</code> класса <code>Base</code>,
заявленного при описании переменной <code>b</code>. Говорят, что имеет место
<font color="#FF0000"><b> <i>раннее связывание</i></b></font> имени метода с его
телом. Если же решение о том,
какой метод вызывать, принимается на этапе выполнения программы в зависимости от
реального типа объекта, на который ссылается переменная <code>b</code>, то
в данном случае вызывается метод <code>Derived.Print</code> (говорят
также, что имеет место <i><font color="#FF0000"><b>позднее связывание</b></font></i>). Методы, для которых
реализуется позднее связывание, называются <i><font color="#FF0000"><b>виртуальными</b></font></i>,
а переменная базового класса, через которую осуществляется вызов виртуального
метода, - <i><font color="#FF0000"><b>полиморфной переменной</b></font></i>.
Таким образом, полиморфизм реализуется вызовом виртуальных функций через
переменную базового класса. Тип класса, который хранится в данной переменной на
этапе выполнения, называется <i><font color="#FF0000"><b>динамическим типом</b></font></i>
этой переменной. </p>
<p>Для того чтобы сделать метод виртуальным, следует в объявлении этого метода
после заголовка указать ключевое слово <code><b>virtual</b></code> с последующей <code>;</code>. Для переопределения виртуального метода
следует использовать ключевое слово <code><b>override</b></code>:</p>
<blockquote>
<p><code><b>type</b><br>
&nbsp; Base =<b> class<br>
@ -90,26 +90,26 @@
&nbsp;&nbsp;&nbsp; <b>end</b>;<br>
&nbsp; <b>end</b>;</code> </p>
</blockquote>
<p>Теперь в аналогичном участке кода.</p>
<p>Теперь в аналогичном участке кода.</p>
<blockquote>
<p><code><b>var</b> b: Base := new Derived;<br>
b.Print;</code></p>
</blockquote>
<p>вызывается метод <code>Print</code> класса <code>
Derived</code> за счет того что решение о вызове метода откладывается на этап
выполнения программы.</p>
<p>Говорят, что методы <code>Print</code> завязаны в
<font color="#FF0000"><i><b>цепочку виртуальности</b></i></font>. Чтобы
разорвать ее (не вызывать методы в подклассах виртуально) используется ключевое
слово <code><b>reintroduce</b></code>:</p>
<p>вызывается метод <code>Print</code> класса <code>
Derived</code> за счет того что решение о вызове метода откладывается на этап
выполнения программы.</p>
<p>Говорят, что методы <code>Print</code> завязаны в
<font color="#FF0000"><i><b>цепочку виртуальности</b></i></font>. Чтобы
разорвать ее (не вызывать методы в подклассах виртуально) используется ключевое
слово <code><b>reintroduce</b></code>:</p>
<blockquote>
<p><code><b>type</b><br>&nbsp; DerivedTwice1 =<b> class</b>(Derived)<br>
<b>&nbsp; public </b><br>&nbsp;&nbsp;&nbsp; <b>procedure</b> Print; </code><code><b>reintroduce</b></code><code>;<br>&nbsp;&nbsp;&nbsp;
<b>begin</b><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; writeln('DerivedTwice1');<br>&nbsp;&nbsp;&nbsp;
<b>end</b>;<br>&nbsp; <b>end</b>;</code> </p>
</blockquote>
<p>Если мы хотим начать новую цепочку виртуальности, то следует использовать и
<code><b>virtual</b></code> и <code><b>reintroduce</b></code>: </p>
<p>Если мы хотим начать новую цепочку виртуальности, то следует использовать и
<code><b>virtual</b></code> и <code><b>reintroduce</b></code>: </p>
<blockquote>
<p><code><b>type</b><br>&nbsp; DerivedTwice2 =<b> class</b>(Derived)<br>
<b>&nbsp; public </b><br>&nbsp;&nbsp;&nbsp; <b>procedure</b> Print; </code><code><b>virtual</b>; </code><code>
@ -117,14 +117,14 @@ Derived</code>
<b>begin</b><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; writeln('DerivedTwice2');<br>&nbsp;&nbsp;&nbsp;
<b>end</b>;<br>&nbsp; <b>end</b>;</code> </p>
</blockquote>
<p>Если переопределить виртуальную функцию невиртуальной без ключевого слова
<code><b>reintroduce</b></code>, то ошибки не произойдет - будет выведено лишь
предупреждение о том, что цепочка виртуальности нарушена. Таким образом,
ключевое слово <code><b>reintroduce</b></code> в этой
ситуации лишь подавляет вывод предупреждения.</p>
<p>При переопределении виртуального метода в подклассе его уровень доступа
должен быть не ниже, чем в базовом классе. Например, <code><b>public</b></code>
виртуальный метод не может быть переопределен в подклассе <code><b>private</b></code>-методом.</p>
<p>Если переопределить виртуальную функцию невиртуальной без ключевого слова
<code><b>reintroduce</b></code>, то ошибки не произойдет - будет выведено лишь
предупреждение о том, что цепочка виртуальности нарушена. Таким образом,
ключевое слово <code><b>reintroduce</b></code> в этой
ситуации лишь подавляет вывод предупреждения.</p>
<p>При переопределении виртуального метода в подклассе его уровень доступа
должен быть не ниже, чем в базовом классе. Например, <code><b>public</b></code>
виртуальный метод не может быть переопределен в подклассе <code><b>private</b></code>-методом.</p>
</body>
</html>

View file

@ -13,28 +13,28 @@
</head>
<body>
<H1>Видимость членов класса и модификаторы доступа</H1>
<p>Каждое поле, метод или свойство класса имеет модификатор (атрибут) доступа,
задающий правила его видимости. В <b>PascalABC.NET</b> существуют
четыре вида модификаторов доступа: <code><b>public</b></code> (открытый), <code><b>private</b></code> (закрытый), <code><b>protected</b></code> (защищенный)
и <code><b>internal</b></code> (внутренний).
К члену класса, имеющему атрибут <code><b>public</b></code>,
можно обратиться из любого места программы, члены класса с атрибутом
<code><b>private</b></code> доступны только внутри методов этого
класса, члены класса с атрибутом <code><b>protected</b></code>
доступны внутри методов этого класса
и всех его подклассов, члены класса с атрибутом <code><b>internal</b></code> доступны внутри сборки (термин .NET, сборка в
нашем понимании - это множество файлов, необходимых для генерации
.exe или .dll-файла). Кроме
того,
<code><b>private</b></code> и <code><b>protected</b></code>
члены видны отовсюду в пределах модуля, в котором определен класс.</p>
<p>Тело класса делится на секции. В начале каждой секции располагается
модификатор доступа, после которого идут поля, а затем методы и свойства с
доступом, определяемым этим модификатором. В первой секции модификатор доступа может отсутствовать, в этом случае
подразумевается модификатор <code><b>internal</b></code>. В классе может быть произвольное
количество секций, располагающихся в произвольном порядке.</p>
<p>Например, пусть данный код располагается в одном модуле:</p>
<H1>Видимость членов класса и модификаторы доступа</H1>
<p>Каждое поле, метод или свойство класса имеет модификатор (атрибут) доступа,
задающий правила его видимости. В <b>PascalABC.NET</b> существуют
четыре вида модификаторов доступа: <code><b>public</b></code> (открытый), <code><b>private</b></code> (закрытый), <code><b>protected</b></code> (защищенный)
и <code><b>internal</b></code> (внутренний).
К члену класса, имеющему атрибут <code><b>public</b></code>,
можно обратиться из любого места программы, члены класса с атрибутом
<code><b>private</b></code> доступны только внутри методов этого
класса, члены класса с атрибутом <code><b>protected</b></code>
доступны внутри методов этого класса
и всех его подклассов, члены класса с атрибутом <code><b>internal</b></code> доступны внутри сборки (термин .NET, сборка в
нашем понимании - это множество файлов, необходимых для генерации
.exe или .dll-файла). Кроме
того,
<code><b>private</b></code> и <code><b>protected</b></code>
члены видны отовсюду в пределах модуля, в котором определен класс.</p>
<p>Тело класса делится на секции. В начале каждой секции располагается
модификатор доступа, после которого идут поля, а затем методы и свойства с
доступом, определяемым этим модификатором. В первой секции модификатор доступа может отсутствовать, в этом случае
подразумевается модификатор <code><b>internal</b></code>. В классе может быть произвольное
количество секций, располагающихся в произвольном порядке.</p>
<p>Например, пусть данный код располагается в одном модуле:</p>
<blockquote>
<p><code><b>type</b> <br>
&nbsp; A =<b> class<br>
@ -44,13 +44,13 @@
&nbsp;&nbsp;&nbsp; a: integer;<br><b>&nbsp; public<br>
&nbsp;&nbsp;&nbsp; constructor </b>Create(xx: integer)<b>;<br>
&nbsp;&nbsp;&nbsp; begin<br>
</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x := xx;<b> </b>// верно,
т.к. внутри метода класса можно обращаться к его закрытому полю x<br>
</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x := xx;<b> </b>// верно,
т.к. внутри метода класса можно обращаться к его закрытому полю x<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a := 0;&nbsp; //
верно<br>
верно<br>
<b>&nbsp;&nbsp;&nbsp; end;<br>
&nbsp; end</b>;</code></blockquote>
Следующий же код пусть располагается в другом модуле:
Следующий же код пусть располагается в другом модуле:
<blockquote>
<code>
<b>type</b> <br>
@ -59,22 +59,22 @@
</b>&nbsp;
<b>&nbsp; procedure</b> print;<br>
&nbsp;&nbsp;&nbsp; <b>begin</b><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; writeln(a); // верно, т.к.
a - защищенное поле<b><br>
</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; writeln(x); // неверно,
т.к. х - закрытое поле<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; writeln(a); // верно, т.к.
a - защищенное поле<b><br>
</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; writeln(x); // неверно,
т.к. х - закрытое поле<br>
&nbsp;&nbsp;&nbsp; <b>end</b>;<br>
&nbsp; <b>end</b>;<br>
...<br>
<b>var</b> b1: B := new B(5); <br>
...<br>
writeln(b1.x); // неверно, т.к. х - закрытое
поле<br>writeln(b1.a); // неверно, т.к. a -
защищенное поле<br>
b1.print; // верно, т.к. print -
открытый метод</code></blockquote>
<p>Комментарии по тексту программы описывают верное и неверное в смысле доступа
обращение к полям и методам.</p>
writeln(b1.x); // неверно, т.к. х - закрытое
поле<br>writeln(b1.a); // неверно, т.к. a -
защищенное поле<br>
b1.print; // верно, т.к. print -
открытый метод</code></blockquote>
<p>Комментарии по тексту программы описывают верное и неверное в смысле доступа
обращение к полям и методам.</p>
</body>
</html>

View file

@ -1,102 +1,102 @@
<html>
<head>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="Keyword" value="Директивы компилятора">
<param name="Keyword" value="apptype">
<param name="Keyword" value="reference">
<param name="Keyword" value="gendoc">
<param name="Keyword" value="mainresource">
<param name="Keyword" value="resource">
<param name="Keyword" value="title">
<param name="Keyword" value="description">
<param name="Keyword" value="product">
<param name="Keyword" value="version">
<param name="Keyword" value="company">
<param name="Keyword" value="copyright">
<param name="Keyword" value="trademark">
<param name="Keyword" value="include">
<param name="Keyword" value="define">
<param name="Keyword" value="undef">
<param name="Keyword" value="ifdef">
<param name="Keyword" value="ifndef">
<param name="Keyword" value="else">
<param name="Keyword" value="endif">
<param name="Keyword" value="faststrings">
<param name="Keyword" value="region">
<param name="Keyword" value="endregion">
<param name="Keyword" value="string_nullbased">
<param name="Keyword" value="platformtarget">
<param name="Keyword" value="targetframework">
</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>Общий вид директивы компилятора:</p>
<blockquote><code>{$ИмяДирективы параметры}</code></blockquote>
<h2>Список директив компилятора</h2>
<p><b>{$apptype &lt;тип приложения&gt;}</b> - задание типа приложения
(windows/console). </p>
<p><b>{$reference &lt;имя файла&gt;}</b> - подключение библиотеки. </p>
<p><b>{$include &lt;имя файла&gt;}</b> - включение в текст программы содержимого
указанного файла. </p>
<p><b>{$define &lt;идентификатор&gt;}</b> - определение имени, используемого в
директивах <b>$ifdef</b>, <b>$ifndef</b>. </p>
<p><b>{$undef &lt;идентификатор&gt;}</b> - исключение имени, используется для отмены
действия директивы <b>$define</b>. </p>
<p><b>{$ifdef &lt;идентификатор&gt;}</b> - начало блока условной компиляции
(проверяется условие: &quot;идентификатор определен&quot;). </p>
<p><b>{$ifndef &lt;идентификатор&gt;}</b> - начало блока условной компиляции
(проверяется условие: &quot;идентификатор не определен&quot;). </p>
<p><b>{$else}</b> - директива &quot;иначе&quot; в блоке условной компиляции. </p>
<p><b>{$endif}</b> - завершение блока условной компиляции. </p>
<p><b>{$faststrings}</b> - строки с быстрым доступом к символам на запись, но со
ссылочной семантикой. </p>
<p><b>{$zerobasedstrings}</b> - включение строк, индексируемых с 0.</p>
<p><b>{$zerobasedstrings on}</b> - включение строк, индексируемых с 0.</p>
<p><b>{$zerobasedstrings off}</b> - выключение строк, индексируемых с 0.</p>
<p><strong>{$</strong><span class="highlight-strong"><strong>platformtarget</strong></span><strong>
x86}</strong> - компиляция для 32-битной платформы (требуется для подключения
32-битных dll)</p>
<p><strong>{$</strong><span class="highlight-strong"><strong>platformtarget</strong></span><strong>
x64}</strong> - компиляция для 64-битной платформы</p>
<p><b>{$gendoc &lt;параметр&gt;}</b> -генерация документации в XML формате. Параметры:
<b>true</b>, <b>false</b>. </p>
<p><b>{$mainresource &lt;имя файла&gt;}</b> - подключение .res файла в качестве
неуправляемого ресурса </p>
<p><b>{$resource &lt;имя файла&gt;}</b> - подключение файла в качестве управляемого
ресурса </p>
<p><b>{$region &lt;имя региона&gt;}</b> - начало региона (используется в
редакторе в режиме сворачивания кода</p>
<p><b>{$endregion}</b> - конец региона</p>
<p><b>{$title &lt;описание&gt;}</b> - название сборки как информационного
продукта</p>
<p><b>{$description &lt;описание&gt;}</b> - краткое описание сборки</p>
<p><b>{$product &lt;название продукта&gt;}</b> - информация о продукте </p>
<p><b>{$version &lt;версия продукта&gt;}</b> - версия продукта </p>
<p><b>{$company &lt;компания&gt;}</b> - компания </p>
<p><b>{$copyright &lt;копирайт&gt;}</b> - копирайт </p>
<p><b>{$trademark &lt;торговая марка&gt;}</b> - торговая марка </p>
<p><b>{$targetframework &lt;версия&gt;}</b> - минимальная версия .NET Framework, требуемая для запуска </p>
<p>Директивы <b>$ifdef</b>, <b>$ifndef</b> совместно с директивами <b>$else</b>
и <b>$endif</b> управлют условной компиляцией частей исходного файла. Каждой
директиве <b>$ifdef</b>, <b>$ifndef</b> должна соответствовать завершающая ее
директива <b>$endif</b>. Между директивами <b>$ifdef</b>, <b>$ifndef</b> и <b>
$endif</b> допускается произвольное количество блоков условной компиляции (в том
числе вложенных) и не более одной директивы <b>$else</b>. </p>
<p><strong>Пример.</strong> Использование директив условной компиляции.</p>
<blockquote><code>{$define DEBUG} <br><strong>begin</strong><br>&nbsp; {$ifndef
DEBUG}<br>&nbsp;&nbsp;&nbsp; writeln('Имя DEBUG не определено');<br>&nbsp;
{$else} <br>&nbsp;&nbsp;&nbsp; writeln('Имя DEBUG определено');<br>&nbsp;
{$endif}<br><strong>end</strong>.</code></blockquote>
</body>
</html>
<html>
<head>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="Keyword" value="Директивы компилятора">
<param name="Keyword" value="apptype">
<param name="Keyword" value="reference">
<param name="Keyword" value="gendoc">
<param name="Keyword" value="mainresource">
<param name="Keyword" value="resource">
<param name="Keyword" value="title">
<param name="Keyword" value="description">
<param name="Keyword" value="product">
<param name="Keyword" value="version">
<param name="Keyword" value="company">
<param name="Keyword" value="copyright">
<param name="Keyword" value="trademark">
<param name="Keyword" value="include">
<param name="Keyword" value="define">
<param name="Keyword" value="undef">
<param name="Keyword" value="ifdef">
<param name="Keyword" value="ifndef">
<param name="Keyword" value="else">
<param name="Keyword" value="endif">
<param name="Keyword" value="faststrings">
<param name="Keyword" value="region">
<param name="Keyword" value="endregion">
<param name="Keyword" value="string_nullbased">
<param name="Keyword" value="platformtarget">
<param name="Keyword" value="targetframework">
</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>Общий вид директивы компилятора:</p>
<blockquote><code>{$ИмяДирективы параметры}</code></blockquote>
<h2>Список директив компилятора</h2>
<p><b>{$apptype &lt;тип приложения&gt;}</b> - задание типа приложения
(windows/console). </p>
<p><b>{$reference &lt;имя файла&gt;}</b> - подключение библиотеки. </p>
<p><b>{$include &lt;имя файла&gt;}</b> - включение в текст программы содержимого
указанного файла. </p>
<p><b>{$define &lt;идентификатор&gt;}</b> - определение имени, используемого в
директивах <b>$ifdef</b>, <b>$ifndef</b>. </p>
<p><b>{$undef &lt;идентификатор&gt;}</b> - исключение имени, используется для отмены
действия директивы <b>$define</b>. </p>
<p><b>{$ifdef &lt;идентификатор&gt;}</b> - начало блока условной компиляции
(проверяется условие: &quot;идентификатор определен&quot;). </p>
<p><b>{$ifndef &lt;идентификатор&gt;}</b> - начало блока условной компиляции
(проверяется условие: &quot;идентификатор не определен&quot;). </p>
<p><b>{$else}</b> - директива &quot;иначе&quot; в блоке условной компиляции. </p>
<p><b>{$endif}</b> - завершение блока условной компиляции. </p>
<p><b>{$faststrings}</b> - строки с быстрым доступом к символам на запись, но со
ссылочной семантикой. </p>
<p><b>{$zerobasedstrings}</b> - включение строк, индексируемых с 0.</p>
<p><b>{$zerobasedstrings on}</b> - включение строк, индексируемых с 0.</p>
<p><b>{$zerobasedstrings off}</b> - выключение строк, индексируемых с 0.</p>
<p><strong>{$</strong><span class="highlight-strong"><strong>platformtarget</strong></span><strong>
x86}</strong> - компиляция для 32-битной платформы (требуется для подключения
32-битных dll)</p>
<p><strong>{$</strong><span class="highlight-strong"><strong>platformtarget</strong></span><strong>
x64}</strong> - компиляция для 64-битной платформы</p>
<p><b>{$gendoc &lt;параметр&gt;}</b> -генерация документации в XML формате. Параметры:
<b>true</b>, <b>false</b>. </p>
<p><b>{$mainresource &lt;имя файла&gt;}</b> - подключение .res файла в качестве
неуправляемого ресурса </p>
<p><b>{$resource &lt;имя файла&gt;}</b> - подключение файла в качестве управляемого
ресурса </p>
<p><b>{$region &lt;имя региона&gt;}</b> - начало региона (используется в
редакторе в режиме сворачивания кода</p>
<p><b>{$endregion}</b> - конец региона</p>
<p><b>{$title &lt;описание&gt;}</b> - название сборки как информационного
продукта</p>
<p><b>{$description &lt;описание&gt;}</b> - краткое описание сборки</p>
<p><b>{$product &lt;название продукта&gt;}</b> - информация о продукте </p>
<p><b>{$version &lt;версия продукта&gt;}</b> - версия продукта </p>
<p><b>{$company &lt;компания&gt;}</b> - компания </p>
<p><b>{$copyright &lt;копирайт&gt;}</b> - копирайт </p>
<p><b>{$trademark &lt;торговая марка&gt;}</b> - торговая марка </p>
<p><b>{$targetframework &lt;версия&gt;}</b> - минимальная версия .NET Framework, требуемая для запуска </p>
<p>Директивы <b>$ifdef</b>, <b>$ifndef</b> совместно с директивами <b>$else</b>
и <b>$endif</b> управлют условной компиляцией частей исходного файла. Каждой
директиве <b>$ifdef</b>, <b>$ifndef</b> должна соответствовать завершающая ее
директива <b>$endif</b>. Между директивами <b>$ifdef</b>, <b>$ifndef</b> и <b>
$endif</b> допускается произвольное количество блоков условной компиляции (в том
числе вложенных) и не более одной директивы <b>$else</b>. </p>
<p><strong>Пример.</strong> Использование директив условной компиляции.</p>
<blockquote><code>{$define DEBUG} <br><strong>begin</strong><br>&nbsp; {$ifndef
DEBUG}<br>&nbsp;&nbsp;&nbsp; writeln('Имя DEBUG не определено');<br>&nbsp;
{$else} <br>&nbsp;&nbsp;&nbsp; writeln('Имя DEBUG определено');<br>&nbsp;
{$endif}<br><strong>end</strong>.</code></blockquote>
</body>
</html>

View file

@ -7,21 +7,21 @@
</head>
<body>
<H1>Примеры обработки исключений</H1>
<p><b>Пример 1.</b> Обработка неверного ввода данных.</p>
<p>Рассмотрим программу. </p>
<H1>Примеры обработки исключений</H1>
<p><b>Пример 1.</b> Обработка неверного ввода данных.</p>
<p>Рассмотрим программу. </p>
<blockquote>
<p><code><b>var</b> i: integer;<br>
<b>begin</b><br>
&nbsp; readln(i);<br>
&nbsp; writeln(i);<br>
&nbsp; writeln('Выполнение программы продолжается');<br>
&nbsp; writeln('Выполнение программы продолжается');<br>
<b>end</b>.</code></p>
</blockquote>
<p>Если при вводе данных произойдет ошибка (например, мы введем
не число), то программа завершится с ошибкой (ошибка ввода), и последующие
операторы <code>writeln</code> не будут выполнены.</p>
<p>Перехватим исключение в блоке <code><b>try</b></code>:</p>
<p>Если при вводе данных произойдет ошибка (например, мы введем
не число), то программа завершится с ошибкой (ошибка ввода), и последующие
операторы <code>writeln</code> не будут выполнены.</p>
<p>Перехватим исключение в блоке <code><b>try</b></code>:</p>
<blockquote>
<p><code><b>var</b> i: integer;<br>
<b>begin</b><br>
@ -29,20 +29,20 @@
&nbsp;&nbsp;&nbsp; readln(i);<br>
&nbsp;&nbsp;&nbsp; writeln(i);<br>
&nbsp; <b>except</b><br>
&nbsp;&nbsp;&nbsp; writeln('Ошибка ввода');<br>
&nbsp;&nbsp;&nbsp; writeln('Ошибка ввода');<br>
&nbsp; <b>end</b>;<br>
&nbsp; writeln('Выполнение программы продолжается');<br>
&nbsp; writeln('Выполнение программы продолжается');<br>
<b>end</b>.</code></p>
</blockquote>
<p>На этот раз при возникновении ошибки ввода программа не будет
завершена, а выполнение будет передано в блок <code><b>except</b></code>,
после чего выполнение программы продолжится дальше. Таким образом, в последней
программе не выполнится лишь оператор <code>writeln(i)</code>.</p>
<p>Если в блоке <code><b>try</b></code> могут
возникнуть различные исключения, то обычно используется вторая форма блока <code>
<b>except</b></code> с несколькими обработчиками
исключений. </p>
<p><b>Пример 2.</b> Обработка различных исключений.</p>
<p>На этот раз при возникновении ошибки ввода программа не будет
завершена, а выполнение будет передано в блок <code><b>except</b></code>,
после чего выполнение программы продолжится дальше. Таким образом, в последней
программе не выполнится лишь оператор <code>writeln(i)</code>.</p>
<p>Если в блоке <code><b>try</b></code> могут
возникнуть различные исключения, то обычно используется вторая форма блока <code>
<b>except</b></code> с несколькими обработчиками
исключений. </p>
<p><b>Пример 2.</b> Обработка различных исключений.</p>
<blockquote>
<p><code><b>var</b> a,b: integer;<br>
assign(f,'a.txt');<br>
@ -52,18 +52,18 @@
&nbsp; c:=a <b>div</b> b;<br>
<b>except</b><br>
&nbsp; <b>on</b> System.DivideByZeroException <b>do</b><br>
&nbsp;&nbsp;&nbsp; writeln('Целочисленное деление на 0');&nbsp; <br>
&nbsp;&nbsp;&nbsp; writeln('Целочисленное деление на 0');&nbsp; <br>
&nbsp; <b>on</b> System.IO.IOException <b>do</b><br>
&nbsp;&nbsp;&nbsp; writeln('Файл отсутствует');&nbsp;<br>
&nbsp;&nbsp;&nbsp; writeln('Файл отсутствует');&nbsp;<br>
<b>end</b>;</code></p>
</blockquote>
<p>Часто необходимо совмещать обработку исключений и
освобождение ресурсов независимо от того, произошло исключение или нет. В этом
случае используются вложенные операторы <code><b>try</b></code> ... <code>
<b>except</b></code> и <code><b>try</b></code> ... <code>
<p>Часто необходимо совмещать обработку исключений и
освобождение ресурсов независимо от того, произошло исключение или нет. В этом
случае используются вложенные операторы <code><b>try</b></code> ... <code>
<b>except</b></code> и <code><b>try</b></code> ... <code>
<b>finally</b></code>. </p>
<p><b>Пример 3.</b> Вложенные операторы <code><b>try</b></code>
... <code><b>except</b></code> и <code><b>try</b></code>
<p><b>Пример 3.</b> Вложенные операторы <code><b>try</b></code>
... <code><b>except</b></code> и <code><b>try</b></code>
... <code><b>finally</b></code>. </p>
<blockquote>
<p><code>assign(f,'a.txt');<br>
@ -74,21 +74,21 @@
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c:=a <b>div</b> b;<br>
<b>&nbsp;&nbsp;&nbsp; except</b><br>
&nbsp; <b>&nbsp;&nbsp;&nbsp; on</b> System.DivideByZeroException <b>do</b><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
writeln('Целочисленное деление на 0');&nbsp; <br><b>&nbsp;&nbsp;&nbsp;
writeln('Целочисленное деление на 0');&nbsp; <br><b>&nbsp;&nbsp;&nbsp;
end</b>;<br>
<b>&nbsp; finally</b><br>
&nbsp;&nbsp;&nbsp; close(f);<br>
<b>&nbsp; end</b>;<br>
<b>except</b><br>
&nbsp; <b>on</b> System.IO.IOException <b>do</b><br>
&nbsp;&nbsp;&nbsp; writeln('Файл отсутствует');&nbsp;<br>
&nbsp;&nbsp;&nbsp; writeln('Файл отсутствует');&nbsp;<br>
<b>end</b>;</code></p>
</blockquote>
<p>Обратим внимание, что в данном примере исключение, связанное
c целочисленным делением на 0, обрабатывается в самом внутреннем
блоке <code><b>try</b></code>, а исключение, связанное с
отсутствующим файлом - в самом внешнем. При этом, если файл был открыт, то
независимо от возникновения исключения деления на 0 он будет закрыт.</p>
<p>Обратим внимание, что в данном примере исключение, связанное
c целочисленным делением на 0, обрабатывается в самом внутреннем
блоке <code><b>try</b></code>, а исключение, связанное с
отсутствующим файлом - в самом внешнем. При этом, если файл был открыт, то
независимо от возникновения исключения деления на 0 он будет закрыт.</p>
</body>
</html>

View file

@ -7,49 +7,49 @@
</head>
<body>
<H1>Обработка исключений: обзор</H1>
<p>Когда во время выполнения программы происходит ошибка,
генерируется так называемое <i>исключение</i>, которое можно <i>перехватить</i>
и <i>обработать</i>. Исключение представляет собой объект класса, производного от
класса <code>Exception</code>, создающийся при
возникновении исключительной ситуации.</p>
<p>Имеется
ряд <a href="StandardExceptions.html">стандартных типов исключений</a>. Можно также
определять <a href="userExceptions.html">пользовательские типы исключений</a>.</p>
<p>Если исключение не обработать, то программа завершится с
ошибкой. Для обработки исключений используется оператор
<H1>Обработка исключений: обзор</H1>
<p>Когда во время выполнения программы происходит ошибка,
генерируется так называемое <i>исключение</i>, которое можно <i>перехватить</i>
и <i>обработать</i>. Исключение представляет собой объект класса, производного от
класса <code>Exception</code>, создающийся при
возникновении исключительной ситуации.</p>
<p>Имеется
ряд <a href="StandardExceptions.html">стандартных типов исключений</a>. Можно также
определять <a href="userExceptions.html">пользовательские типы исключений</a>.</p>
<p>Если исключение не обработать, то программа завершится с
ошибкой. Для обработки исключений используется оператор
<a href="../Operators/try_except.html"><code><b>try</b></code>
... <code><b>except</b></code></a>. </p>
<p>Обычно исключения возбуждаются в подпрограммах, поскольку
разработчик подпрограммы, как правило, не знает, как обработать ошибочную
ситуацию. В месте вызова подпрограммы уже, как правило, известно, каким образом
следует обрабатывать исключение. Например, пусть разработана
следующая функция:</p>
<p>Обычно исключения возбуждаются в подпрограммах, поскольку
разработчик подпрограммы, как правило, не знает, как обработать ошибочную
ситуацию. В месте вызова подпрограммы уже, как правило, известно, каким образом
следует обрабатывать исключение. Например, пусть разработана
следующая функция:</p>
<blockquote>
<p><code><b>function</b> mymod(a,b: integer): integer;<br>
<b>begin</b><br>
&nbsp; Result := a - (a <b>div</b> b) * b;<br>
<b>end</b>;</code></p>
</blockquote>
<p>Если вызвать <code>mymod(1,0)</code>, то
будет возбуждено исключение <code>System.DivideByZeroException</code>
целочисленного деления на 0. </p>
<p>Рассмотрим наивную попытку обработать ошибочную ситуацию
внутри функции <code>mymod</code>:</p>
<p>Если вызвать <code>mymod(1,0)</code>, то
будет возбуждено исключение <code>System.DivideByZeroException</code>
целочисленного деления на 0. </p>
<p>Рассмотрим наивную попытку обработать ошибочную ситуацию
внутри функции <code>mymod</code>:</p>
<blockquote>
<p><code><b>function</b> mymod(a,b: integer): integer;<br>
<b>begin<br>
</b>&nbsp; <b>if</b> b = 0 <b>then</b> <br>
&nbsp;&nbsp;&nbsp; writeln('Функция mymod: деление на 0');<br>
&nbsp;&nbsp;&nbsp; writeln('Функция mymod: деление на 0');<br>
&nbsp; Result := a - (a <b>div</b> b) * b;<br>
<b>end</b>;</code></p>
</blockquote>
<p>Подобное решение является плохим, поскольку программист,
разрабатывающий функцию <code>mymod</code>, не знает, как
она будет использоваться. Например, при вызове функции <code>mymod</code>
в цикле мы увидим на экране многократное сообщение об ошибке.</p>
<p>Простейший способ - оставить исходный вариант функции и
обрабатывать исключение <code>System.DivideByZeroException</code>:</p>
<p>Подобное решение является плохим, поскольку программист,
разрабатывающий функцию <code>mymod</code>, не знает, как
она будет использоваться. Например, при вызове функции <code>mymod</code>
в цикле мы увидим на экране многократное сообщение об ошибке.</p>
<p>Простейший способ - оставить исходный вариант функции и
обрабатывать исключение <code>System.DivideByZeroException</code>:</p>
<blockquote>
<p><code><b>try</b> <br>
&nbsp; readln(a,b);<br>
@ -57,30 +57,30 @@
&nbsp; ...<br>
<b>except</b><br>
&nbsp; <b>on</b> System.DivideByZeroException <b>do</b><br>
&nbsp;&nbsp;&nbsp; writeln('Деление на 0');&nbsp; <br>
&nbsp;&nbsp;&nbsp; writeln('Деление на 0');&nbsp; <br>
<b>end</b>;</code></p>
</blockquote>
<p>Отличие от вывода внутри функции состоит в том, что при
разработке программы мы сами определяем действие, которое необходимо выполнять
при обработке исключения. Это может быть специфическое сообщение об ошибке,
вывод в файл ошибок или пустой оператор (в случае, когда требуется &quot;беззвучно&quot;
погасить исключение). </p>
<p>Однако, данное решение обладает существенным недостатком:
исключение <code>System.DivideByZeroException</code> будет возбуждено и
при a=1 и не будет связано с функцией <code>mymod</code>.
Для устранения подобного недостатка определим собственный класс исключения и
возбудим его в функции <code>mymod</code>: </p>
<p>Отличие от вывода внутри функции состоит в том, что при
разработке программы мы сами определяем действие, которое необходимо выполнять
при обработке исключения. Это может быть специфическое сообщение об ошибке,
вывод в файл ошибок или пустой оператор (в случае, когда требуется &quot;беззвучно&quot;
погасить исключение). </p>
<p>Однако, данное решение обладает существенным недостатком:
исключение <code>System.DivideByZeroException</code> будет возбуждено и
при a=1 и не будет связано с функцией <code>mymod</code>.
Для устранения подобного недостатка определим собственный класс исключения и
возбудим его в функции <code>mymod</code>: </p>
<blockquote>
<p><code><b>type</b> MyModErrorException =<b> class</b>(System.Exception) <b>end</b>;&nbsp;&nbsp;
</code></p>
<p><code><b>function</b> mymod(a,b: integer): integer;<br>
<b>begin</b><br>
&nbsp; <b>if</b> b = 0 <b>then</b> <br>
&nbsp;&nbsp;&nbsp; <b>raise</b> new MyModErrorException('Функция mymod: деление на 0');<br>
&nbsp;&nbsp;&nbsp; <b>raise</b> new MyModErrorException('Функция mymod: деление на 0');<br>
&nbsp; Result := a - (a <b>div</b> b) * b;<br>
<b>end</b>;</code></p>
</blockquote>
<p>Тогда обработка ошибок будет выглядеть так:</p>
<p>Тогда обработка ошибок будет выглядеть так:</p>
<blockquote>
<p><code><b>try</b> <br>
&nbsp; readln(a,b);<br>
@ -88,15 +88,15 @@
&nbsp; ...<br>
<b>except</b><br>
&nbsp; <b>on</b> System.DivideByZeroException <b>do</b><br>
&nbsp;&nbsp;&nbsp; writeln('Деление на 0');&nbsp; <br>
&nbsp;&nbsp;&nbsp; writeln('Деление на 0');&nbsp; <br>
&nbsp; <b>on</b> e: MyModErrorException <b>do</b><br>
&nbsp;&nbsp;&nbsp; writeln(e.Message);<br>
&nbsp; <b>else</b> writeln('какое-то другое исключение')&nbsp; <br>
&nbsp; <b>else</b> writeln('какое-то другое исключение')&nbsp; <br>
<b>end</b>;</code></p>
</blockquote>
<p>Если сделать <code>MyModErrorException</code>
наследником класса&nbsp;<code>System.ArithmeticException</code>, как и <code>
System.DivideByZeroException</code>, то последний код можно упростить:<code>&nbsp;&nbsp;
<p>Если сделать <code>MyModErrorException</code>
наследником класса&nbsp;<code>System.ArithmeticException</code>, как и <code>
System.DivideByZeroException</code>, то последний код можно упростить:<code>&nbsp;&nbsp;
</code></p>
<blockquote>
<p><code><b>type</b> MyModErrorException =<b> class</b>(System.ArithmeticException) <b>end</b>;</code></p>
@ -108,13 +108,13 @@ System.DivideByZeroException</code>,
<b>except</b><br>
&nbsp; <b>on</b> e: System.ArithmeticException <b>do</b><br>
&nbsp;&nbsp;&nbsp; writeln(e.Message);&nbsp; <br>
&nbsp; <b>else</b> writeln('Какое-то другое исключение')&nbsp; <br>
&nbsp; <b>else</b> writeln('Какое-то другое исключение')&nbsp; <br>
<b>end</b>;</code></p>
</blockquote>
<p>Наконец, можно поступить следующим образом.
Перехватим в функции <code>mymod</code>
исключение <code>System.DivideByZeroException</code> и в
ответ сгенерируем новое - <code>MyModErrorException</code>:</p>
<p>Наконец, можно поступить следующим образом.
Перехватим в функции <code>mymod</code>
исключение <code>System.DivideByZeroException</code> и в
ответ сгенерируем новое - <code>MyModErrorException</code>:</p>
<blockquote>
<p><code><b>function</b> mymod(a,b: integer): integer;<br>
<b>begin</b><br>
@ -125,7 +125,7 @@ System.DivideByZeroException</code>,
&nbsp;&nbsp;&nbsp; <b>on</b> e: System.DivideByZeroException <b>do</b><br>
&nbsp; &nbsp; &nbsp; <b>raise</b>
<b>new</b>
MyModErrorException('Функция mymod: деление на 0');<br>
MyModErrorException('Функция mymod: деление на 0');<br>
&nbsp; <b>end</b>;<br>
<b>end</b>;</code></p>
</blockquote>

View file

@ -29,9 +29,9 @@
<body>
<H1>Стандартные классы исключений</H1>
<p>Все классы исключений являются потомками класса <code>System.Exception</code>,
включающего следующий интерфейс:</p>
<H1>Стандартные классы исключений</H1>
<p>Все классы исключений являются потомками класса <code>System.Exception</code>,
включающего следующий интерфейс:</p>
<blockquote>
<p><code><b>type</b> <br>
&nbsp; Exception =<b> class<br>
@ -39,47 +39,47 @@
&nbsp;&nbsp;&nbsp; <b>constructor</b> Create;<br>
&nbsp;&nbsp;&nbsp; <b>constructor</b> Create(message: <b>string</b>);<br>
&nbsp;&nbsp;&nbsp; <b>property</b> Message: <b>string</b>; //
только на чтение<br>
только на чтение<br>
&nbsp;&nbsp;&nbsp; <b>property</b> </code><code>StackTrace</code><code>: <b>string</b>;
// только на чтение<br>
// только на чтение<br>
<b>&nbsp; end</b>;</code></p>
</blockquote>
<p>Свойство <code>Message</code>
возвращает сообщение, связанное с объектом исключения.</p>
<p>Свойство <code>StackTrace</code>
возвращает стек вызовов подпрограмм на момент генерации исключения.</p>
<p>Ниже приводятся некоторые классы исключений, определенные в пространстве имен <code>System</code> и
являющиеся производными от класса <code>System.SystemException</code>:</p>
<p>Свойство <code>Message</code>
возвращает сообщение, связанное с объектом исключения.</p>
<p>Свойство <code>StackTrace</code>
возвращает стек вызовов подпрограмм на момент генерации исключения.</p>
<p>Ниже приводятся некоторые классы исключений, определенные в пространстве имен <code>System</code> и
являющиеся производными от класса <code>System.SystemException</code>:</p>
<blockquote>
<p><code>System.OutOfMemoryException</code> - недостаточно
памяти для выполнения программы;<br><code>System.StackOverflowException</code> - переполнение стека (как
правило, при многократных вложенных вызовах подпрограмм);<br>
<code>System.AccessViolationException</code> - попытка доступа к защищенной
памяти;<br><code>System.ArgumentException</code> -
неверное значение параметра подпрограммы; <br>
<code>System.ArithmeticException</code> - базовый класс всех арифметических
исключений. Наследники:</p>
<p><code>System.OutOfMemoryException</code> - недостаточно
памяти для выполнения программы;<br><code>System.StackOverflowException</code> - переполнение стека (как
правило, при многократных вложенных вызовах подпрограмм);<br>
<code>System.AccessViolationException</code> - попытка доступа к защищенной
памяти;<br><code>System.ArgumentException</code> -
неверное значение параметра подпрограммы; <br>
<code>System.ArithmeticException</code> - базовый класс всех арифметических
исключений. Наследники:</p>
<blockquote>
<p><code>System.DivideByZeroException</code> - целочисленное деление на
<p><code>System.DivideByZeroException</code> - целочисленное деление на
0;<br>
<code>System.OverflowException</code> - переполнение при выполнении
арифметической операции или преобразования типов;</p>
<code>System.OverflowException</code> - переполнение при выполнении
арифметической операции или преобразования типов;</p>
</blockquote>
<p><code>System.FormatException</code> - неверный формат параметра
(например, при преобразовании строки в число); <br>
<code>System.IndexOutOfRangeException</code> - выход за границы диапазона
изменения индекса массива; <br><code>System.InvalidCastException</code> -
неверное приведение типов; <br><code>System.NullReferenceException</code> -
попытка вызвать метод для нулевого объекта или разыменовать нулевой
указатель;<br><code>System.IO.IOException</code> -
ошибка ввода-вывода. Наследники: </p>
<p><code>System.FormatException</code> - неверный формат параметра
(например, при преобразовании строки в число); <br>
<code>System.IndexOutOfRangeException</code> - выход за границы диапазона
изменения индекса массива; <br><code>System.InvalidCastException</code> -
неверное приведение типов; <br><code>System.NullReferenceException</code> -
попытка вызвать метод для нулевого объекта или разыменовать нулевой
указатель;<br><code>System.IO.IOException</code> -
ошибка ввода-вывода. Наследники: </p>
<blockquote>
<p><code>System.IO.IOException.DirectoryNotFoundException</code> -
каталог не найден;<br>
каталог не найден;<br>
<code>System.IO.IOException.</code><code>EndOfStreamException</code> -
попытка чтения за концом потока; <br>
попытка чтения за концом потока; <br>
<code>System.IO.IOException.</code><code>FileNotFoundException</code> -
файл не найден.<br>
файл не найден.<br>
<br>&nbsp;</code></p>
</blockquote>
</blockquote>

View file

@ -9,22 +9,22 @@
</head>
<body>
<H1>Повторная генерация исключения</H1>
<p>Для повторной генерации исключения в блоке <code><b>
except</b></code> служит <a href="../Operators/raise.html">о</a><a href="../Operators/raise.html">ператор <code> <b>raise</b></code></a>
без параметров:</p>
<H1>Повторная генерация исключения</H1>
<p>Для повторной генерации исключения в блоке <code><b>
except</b></code> служит <a href="../Operators/raise.html">о</a><a href="../Operators/raise.html">ператор <code> <b>raise</b></code></a>
без параметров:</p>
<blockquote>
<p><code><b>raise</b>;</code></p>
</blockquote>
<p>Например:</p>
<p>Например:</p>
<blockquote>
<p><code><b>try</b><br>
&nbsp; ...<br>
<b>except</b><br>
&nbsp; <b>on</b> FileNotFoundException <b>do</b><br>
&nbsp; <b>begin</b><br>
&nbsp;&nbsp;&nbsp; log.WriteLine('Файл не найден'); //
запись в файл ошибок<br>
&nbsp;&nbsp;&nbsp; log.WriteLine('Файл не найден'); //
запись в файл ошибок<br>
&nbsp;&nbsp;&nbsp; <b>raise</b>;<br>
&nbsp; <b>end</b>;<br>
<b>end</b>;</code></p>

View file

@ -7,25 +7,25 @@
</head>
<body>
<H1>Исключения, определяемые пользователем</H1>
<p>Для определения своего типа исключения достаточно породить класс - наследник
класса <code>Exception</code>:</p>
<H1>Исключения, определяемые пользователем</H1>
<p>Для определения своего типа исключения достаточно породить класс - наследник
класса <code>Exception</code>:</p>
<blockquote>
<p><code><b>type</b> MyException =<b> class</b>(Exception) <b>end</b>;</code></p>
</blockquote>
<p>Тело класса-исключения может быть пустым, но, тем не менее, новое имя для
типа исключения позволит его разграничить с остальными исключениями:</p>
<p>Тело класса-исключения может быть пустым, но, тем не менее, новое имя для
типа исключения позволит его разграничить с остальными исключениями:</p>
<blockquote>
<p><code><b>try</b><br>
&nbsp; ...<br>
<b>except</b><br>
&nbsp; <b>on</b> MyException <b>do</b><br>&nbsp;&nbsp;&nbsp; writeln('Целочисленное
деление на 0');&nbsp; <br>&nbsp; <b>on</b> Exception <b>do</b><br><b>&nbsp;&nbsp;&nbsp;
</b>writeln('Файл отсутствует');&nbsp;<br>
&nbsp; <b>on</b> MyException <b>do</b><br>&nbsp;&nbsp;&nbsp; writeln('Целочисленное
деление на 0');&nbsp; <br>&nbsp; <b>on</b> Exception <b>do</b><br><b>&nbsp;&nbsp;&nbsp;
</b>writeln('Файл отсутствует');&nbsp;<br>
<b>end</b>;</code></p>
</blockquote>
<p>Исключение может содержать дополнительную информацию, связанную с точкой, в
которой произошло исключение:</p>
<p>Исключение может содержать дополнительную информацию, связанную с точкой, в
которой произошло исключение:</p>
<blockquote>
<p><code><b>type</b> <br>
&nbsp; FileNotFoundException = <b>class</b>(Exception)<b><br>
@ -41,16 +41,16 @@
<b>begin</b><br>
&nbsp; <b>if</b> <b>not</b>
FileExists(fname) <b>then</b><br>
&nbsp;&nbsp;&nbsp; <b>raise</b> <b>new</b> FileNotFoundException('Файл
не найден',fname);<br>
&nbsp;&nbsp;&nbsp; <b>raise</b> <b>new</b> FileNotFoundException('Файл
не найден',fname);<br>
<b>end</b>;</code></p>
<p><code>...</code></p>
<p><code><b>try</b><br>
&nbsp; ...<br>
<b>except</b><br>
&nbsp; <b>on</b> e: FileNotFoundException <b>do</b><br><b>&nbsp;&nbsp;&nbsp;
</b>writeln('Файл '+e.fname+'
не найден');&nbsp;<br>
</b>writeln('Файл '+e.fname+'
не найден');&nbsp;<br>
<b>end</b>;</code></p>
</blockquote>
</body>

View file

@ -2,21 +2,21 @@
<param name="Keyword" value="Aggregate">
</object><meta http-equiv="Content-Type" content="text/html; charset=windows-1251"><title></title><link rel="StyleSheet" href="../../../default.css"></head>
<body>
<H1>Метод Aggregate</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<H1>Метод Aggregate</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<tr><td>
<code><b>function </b>Aggregate(func: (T,T)-&gt;T): T;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Применяет к последовательности агрегатную функцию. Возвращает конечное агрегатное значение.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Применяет к последовательности агрегатную функцию. Возвращает конечное агрегатное значение.
</td></tr>
<tr><td>
<code><b>function </b>Aggregate&lt;Accum&gt;(seed: T; func: (Accum,T)-&gt;Accum): T;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Применяет к последовательности агрегатную функцию. Указанное начальное значение используется в качестве исходного значения агрегатной операции. Возвращает конечное агрегатное значение.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Применяет к последовательности агрегатную функцию. Указанное начальное значение используется в качестве исходного значения агрегатной операции. Возвращает конечное агрегатное значение.
</td></tr>
<tr><td>
<code><b>function </b>Aggregate&lt;Accum,Res&gt;(seed: T; func: (Accum,T)-&gt;Accum; resultSelector: Accum-&gt;Res): T;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Применяет к последовательности агрегатную функцию.Указанное начальное значение служит исходным значением для агрегатной операции, а указанная функция используется для выбора результирующего значения. Возвращает конечное агрегатное значение.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Применяет к последовательности агрегатную функцию.Указанное начальное значение служит исходным значением для агрегатной операции, а указанная функция используется для выбора результирующего значения. Возвращает конечное агрегатное значение.
</td></tr>
</table>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
a := Seq(2,3,5,6);<br>&nbsp; Println(a.Aggregate(1,(p,x) -&gt; p*x)); <br>
<strong>end</strong>.</code></blockquote>
</body>

View file

@ -3,21 +3,21 @@
<param name="Keyword" value="All">
</object><meta http-equiv="Content-Type" content="text/html; charset=windows-1251"><title></title><link rel="StyleSheet" href="../../../default.css"></head>
<body>
<H1>Методы Any, All</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<H1>Методы Any, All</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<tr><td>
<code><b>function </b>Any(): boolean;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Проверяет, содержит ли последовательность какие-либо элементы.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Проверяет, содержит ли последовательность какие-либо элементы.
</td></tr>
<tr><td>
<code><b>function </b>Any(predicate: T-&gt;boolean): boolean;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Проверяет, удовлетворяет ли какой-либо элемент последовательности заданному условию.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Проверяет, удовлетворяет ли какой-либо элемент последовательности заданному условию.
</td></tr>
<tr><td>
<code><b>function </b>All(predicate: T-&gt;boolean): boolean;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Проверяет, все ли элементы последовательности удовлетворяют условию.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Проверяет, все ли элементы последовательности удовлетворяют условию.
</td></tr>
</table>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
a := Lst(1,3,5);<br>&nbsp; Println(a.All(x -&gt; x mod 2 &lt;&gt; 0)); // True<br>&nbsp;
Println(a.Any(x -&gt; x mod 2 = 0));&nbsp; // False<br><strong>end</strong>.</code></blockquote>
</body>

View file

@ -2,13 +2,13 @@
<param name="Keyword" value="AsEnumerable">
</object><meta http-equiv="Content-Type" content="text/html; charset=windows-1251"><title></title><link rel="StyleSheet" href="../../../default.css"></head>
<body>
<H1>Ìåòîä AsEnumerable</H1><h2>Îïèñàíèå ìåòîäîâ</h2><p>Ìåòîäû ïðèâåäåíû äëÿ ïîñëåäîâàòåëüíîñòè <code><b>sequence of</b> T</code>.</p><table>
<H1>Метод AsEnumerable</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<tr><td>
<code><b>function </b>AsEnumerable(): <b>sequence of</b> T;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Âîçâðàùàåò âõîäíûå äàííûå, ïðèâåäåííûå ê òèïó IEnumerable<T>.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает входные данные, приведенные к типу IEnumerable<T>.
</td></tr>
</table>
<h2>Ïðèìåð </h2><blockquote><code><strong>function</strong> Print&lt;T&gt;(Self:
<h2>Пример </h2><blockquote><code><strong>function</strong> Print&lt;T&gt;(Self:
<strong>array of</strong> T): <strong>array of</strong> T; extensionmethod;<br>
<strong>begin</strong><br>&nbsp; Self.AsEnumerable.Print; <br>&nbsp; Result
:= Self;<br><strong>end</strong>;<br><br><strong>begin</strong><br>&nbsp;

View file

@ -2,13 +2,13 @@
<param name="Keyword" value="Cast">
</object><meta http-equiv="Content-Type" content="text/html; charset=windows-1251"><title></title><link rel="StyleSheet" href="../../../default.css"></head>
<body>
<H1>Ìåòîä Cast</H1><h2>Îïèñàíèå ìåòîäîâ</h2><p>Ìåòîäû ïðèâåäåíû äëÿ ïîñëåäîâàòåëüíîñòè <code><b>sequence of</b> T</code>.</p><table>
<H1>Метод Cast</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<tr><td>
<code><b>function </b>Cast&lt;Res&gt;(): <b>sequence of</b> Res;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Ïðåîáðàçîâûâàåò ýëåìåíòû îáúåêòà System.Collections.IEnumerable â çàäàííûé òèï.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Преобразовывает элементы объекта System.Collections.IEnumerable в заданный тип.
</td></tr>
</table>
<h2>Ïðèìåð </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
a: <strong>sequence of</strong> integer; <br>&nbsp; <strong>var</strong> b:
<strong>sequence of</strong> real;<br>&nbsp; a := Seq(1,3,5);<br>&nbsp; b :=
a.Cast&amp;&lt;real&gt;();<br><strong>end</strong>.</code></blockquote>

View file

@ -2,13 +2,13 @@
<param name="Keyword" value="Concat">
</object><meta http-equiv="Content-Type" content="text/html; charset=windows-1251"><title></title><link rel="StyleSheet" href="../../../default.css"></head>
<body>
<H1>Метод Concat</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<H1>Метод Concat</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<tr><td>
<code><b>function </b>Concat(second: <b>sequence of</b> T): <b>sequence of</b> T;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Соединяет две последовательности, дописывая вторую в конец первой и возвращая результирующую последовательность.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Соединяет две последовательности, дописывая вторую в конец первой и возвращая результирующую последовательность.
</td></tr>
</table>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
a1 := Lst(2,3,5);<br>&nbsp; <strong>var</strong> a2 := Seq(4,7,8);<br>&nbsp;
a1.Concat(a2).Println; // 2 3 5 4 7 8<br><strong>end</strong>.</code></blockquote>
</body>

View file

@ -2,17 +2,17 @@
<param name="Keyword" value="Contains">
</object><meta http-equiv="Content-Type" content="text/html; charset=windows-1251"><title></title><link rel="StyleSheet" href="../../../default.css"></head>
<body>
<H1>Метод Contains</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<H1>Метод Contains</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<tr><td>
<code><b>function </b>Contains(value: T): boolean;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Определяет, содержится ли указанный элемент в последовательности, используя компаратор проверки на равенство по умолчанию.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Определяет, содержится ли указанный элемент в последовательности, используя компаратор проверки на равенство по умолчанию.
</td></tr>
<tr><td>
<code><b>function </b>Contains(value: T; comparer: IEqualityComparer&lt;T&gt;): boolean;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Определяет, содержит ли последовательность заданный элемент, используя указанный компаратор.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Определяет, содержит ли последовательность заданный элемент, используя указанный компаратор.
</td></tr>
</table>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
a := Lst(1,3,5,6);<br>&nbsp; Println(a.Contains(666)); // False<br>&nbsp;
Println(666 <strong>in</strong> a); // False<br><strong>end</strong>.</code></blockquote>
</body>

View file

@ -2,25 +2,25 @@
<param name="Keyword" value="Count">
</object><meta http-equiv="Content-Type" content="text/html; charset=windows-1251"><title></title><link rel="StyleSheet" href="../../../default.css"></head>
<body>
<H1>Методы Count</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<H1>Методы Count</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<tr><td>
<code><b>function </b>Count(): integer;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает количество элементов в последовательности.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает количество элементов в последовательности.
</td></tr>
<tr><td>
<code><b>function </b>Count(predicate: T-&gt;boolean): integer;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает число, представляющее количество элементов последовательности, удовлетворяющих заданному условию.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает число, представляющее количество элементов последовательности, удовлетворяющих заданному условию.
</td></tr>
<tr><td>
<code><b>function </b>LongCount(): int64;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает значение типа Int64, представляющее общее число элементов в последовательности.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает значение типа Int64, представляющее общее число элементов в последовательности.
</td></tr>
<tr><td>
<code><b>function </b>LongCount(predicate: T-&gt;boolean): int64;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает значение типа Int64, представляющее число элементов последовательности, удовлетворяющих заданному условию.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает значение типа Int64, представляющее число элементов последовательности, удовлетворяющих заданному условию.
</td></tr>
</table>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
a := Lst(1,3,5,6);<br>&nbsp; Println(a.Count(x -&gt; x mod 2 &lt;&gt; 0)); // 3<br>
<strong>end</strong>.</code></blockquote>
</body>

View file

@ -2,17 +2,17 @@
<param name="Keyword" value="DefaultIfEmpty">
</object><meta http-equiv="Content-Type" content="text/html; charset=windows-1251"><title></title><link rel="StyleSheet" href="../../../default.css"></head>
<body>
<H1>Метод DefaultIfEmpty</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<H1>Метод DefaultIfEmpty</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<tr><td>
<code><b>function </b>DefaultIfEmpty(): <b>sequence of</b> T;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает элементы указанной последовательности или одноэлементную коллекцию, содержащую значение параметра типа по умолчанию, если последовательность пуста.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает элементы указанной последовательности или одноэлементную коллекцию, содержащую значение параметра типа по умолчанию, если последовательность пуста.
</td></tr>
<tr><td>
<code><b>function </b>DefaultIfEmpty(defaultValue: T): <b>sequence of</b> T;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает элементы указанной последовательности или одноэлементную коллекцию, содержащую указанное значение, если последовательность пуста.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает элементы указанной последовательности или одноэлементную коллекцию, содержащую указанное значение, если последовательность пуста.
</td></tr>
</table>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
a := Arr(1,2,3,4);<br>&nbsp; a.Skip(4).DefaultIfEmpty.Println; // 0<br>
<strong>end</strong>.</code></blockquote>
</body>

View file

@ -2,17 +2,17 @@
<param name="Keyword" value="Distinct">
</object><meta http-equiv="Content-Type" content="text/html; charset=windows-1251"><title></title><link rel="StyleSheet" href="../../../default.css"></head>
<body>
<H1>Метод Distinct</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<H1>Метод Distinct</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<tr><td>
<code><b>function </b>Distinct(): <b>sequence of</b> T;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает различающиеся элементы последовательности.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает различающиеся элементы последовательности.
</td></tr>
<tr><td>
<code><b>function </b>Distinct(comparer: IEqualityComparer&lt;T&gt;): <b>sequence of</b> T;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает различающиеся элементы последовательности, используя для сравнения значений компаратор comparer.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает различающиеся элементы последовательности, используя для сравнения значений компаратор comparer.
</td></tr>
</table>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
a := Arr('aaa','bbb','ccc','aaa','ccc');<br>&nbsp; a.Distinct.Println; //
aaa bbb ccc<br><strong>end</strong>.</code></blockquote>
</body>

View file

@ -3,17 +3,17 @@
<param name="Keyword" value="ElementAtOrDefault">
</object><meta http-equiv="Content-Type" content="text/html; charset=windows-1251"><title></title><link rel="StyleSheet" href="../../../default.css"></head>
<body>
<H1>Методы ElementAt, ElementAtOrDefault</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<H1>Методы ElementAt, ElementAtOrDefault</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<tr><td>
<code><b>function </b>ElementAt(index: integer): T;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает элемент по указанному индексу в последовательности.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает элемент по указанному индексу в последовательности.
</td></tr>
<tr><td>
<code><b>function </b>ElementAtOrDefault(index: integer): T;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает элемент по указанному индексу в последовательности или значение по умолчанию, если индекс вне допустимого диапазона.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает элемент по указанному индексу в последовательности или значение по умолчанию, если индекс вне допустимого диапазона.
</td></tr>
</table>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
a := Arr(1,2,3,4);<br>&nbsp; Println(a.ElementAt(2)); // 3<br>&nbsp;
Println(a.ElementAtOrDefault(10)); // 0<br><strong>end</strong>.</code></blockquote>
</body>

View file

@ -3,25 +3,25 @@
<param name="Keyword" value="FirstOrDefault">
</object><meta http-equiv="Content-Type" content="text/html; charset=windows-1251"><title></title><link rel="StyleSheet" href="../../../default.css"></head>
<body>
<H1>Методы First, FirstOrDefault</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<H1>Методы First, FirstOrDefault</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<tr><td>
<code><b>function </b>First(): T;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает первый элемент последовательности.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает первый элемент последовательности.
</td></tr>
<tr><td>
<code><b>function </b>First(predicate: T-&gt;boolean): T;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает первый элемент последовательности, удовлетворяющий указанному условию.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает первый элемент последовательности, удовлетворяющий указанному условию.
</td></tr>
<tr><td>
<code><b>function </b>FirstOrDefault(): T;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает первый элемент последовательности или значение по умолчанию, если последовательность не содержит элементов.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает первый элемент последовательности или значение по умолчанию, если последовательность не содержит элементов.
</td></tr>
<tr><td>
<code><b>function </b>FirstOrDefault(predicate: T-&gt;boolean): T;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает первый удовлетворяющий условию элемент последовательности или значение по умолчанию, если ни одного такого элемента не найдено.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает первый удовлетворяющий условию элемент последовательности или значение по умолчанию, если ни одного такого элемента не найдено.
</td></tr>
</table>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
a := Arr(1,2,3,4);<br>&nbsp; Println(a.Skip(2).First); // 3<br>&nbsp;
Println(a.First(x -&gt; x <strong>mod</strong> 2 = 0); // 2<br>&nbsp;
Println(a.FirstOrDefault(x -&gt; x&gt;5); // 0&nbsp; <br><strong>end</strong>.</code></blockquote>

View file

@ -2,13 +2,13 @@
<param name="Keyword" value="ForEach">
</object><meta http-equiv="Content-Type" content="text/html; charset=windows-1251"><title></title><link rel="StyleSheet" href="../../../default.css"></head>
<body>
<H1>Метод ForEach</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<H1>Метод ForEach</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<tr><td>
<code><b>procedure</b> ForEach(action: T-&gt;());</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Применяет действие к каждому элементу последовательности.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Применяет действие к каждому элементу последовательности.
</td></tr>
</table>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
a := Lst(2,3,5);<br>&nbsp; <strong>var</strong> p := 1;<br>&nbsp; a.ForEach(<strong>procedure</strong>(x)
-&gt; p *= x);<br>&nbsp; Println(p);<br><strong>end</strong>.</code></blockquote>
</body>

View file

@ -2,46 +2,46 @@
<param name="Keyword" value="GroupBy">
</object><meta http-equiv="Content-Type" content="text/html; charset=windows-1251"><title></title><link rel="StyleSheet" href="../../../default.css"></head>
<body>
<H1>Метод GroupBy</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<H1>Метод GroupBy</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<tr><td>
<code><b>function </b>GroupBy&lt;Key&gt;(keySelector: T-&gt;Key): IEnumerable&lt;IGrouping&lt;Key,T&gt;&gt;;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Группирует элементы последовательности в соответствии с заданной функцией селектора ключа и возвращает последовательность групп; каждая группа соответствует одному значению ключа.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Группирует элементы последовательности в соответствии с заданной функцией селектора ключа и возвращает последовательность групп; каждая группа соответствует одному значению ключа.
</td></tr>
<tr><td>
<code><b>function </b>GroupBy&lt;Key&gt;(keySelector: T-&gt;Key; comparer: System.Collections.Generic.IEqualityComparer&lt;Key&gt;): IEnumerable&lt;IGrouping&lt;Key,T&gt;&gt;;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Группирует элементы последовательности в соответствии с заданной функцией селектора ключа, сравнивает ключи с помощью указанного компаратора и возвращает последовательность групп; каждая группа соответствует одному значению ключа.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Группирует элементы последовательности в соответствии с заданной функцией селектора ключа, сравнивает ключи с помощью указанного компаратора и возвращает последовательность групп; каждая группа соответствует одному значению ключа.
</td></tr>
<tr><td>
<code><b>function </b>GroupBy&lt;Key,Element&gt;(keySelector: T-&gt;Key; elementSelector: T-&gt;Element): IEnumerable&lt;IGrouping&lt;Key,T&gt;&gt;;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Группирует элементы последовательности в соответствии с заданной функцией селектора ключа и проецирует элементы каждой группы с помощью указанной функции. Возвращает последовательность групп; каждая группа соответствует одному значению ключа.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Группирует элементы последовательности в соответствии с заданной функцией селектора ключа и проецирует элементы каждой группы с помощью указанной функции. Возвращает последовательность групп; каждая группа соответствует одному значению ключа.
</td></tr>
<tr><td>
<code><b>function </b>GroupBy&lt;Key,Element&gt;(keySelector: T-&gt;Key; elementSelector: T-&gt;Element; comparer: IEqualityComparer&lt;Key&gt;): IEnumerable&lt;IGrouping&lt;Key,Element&gt;&gt;;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Группирует элементы последовательности в соответствии с функцией селектора ключа.Ключи сравниваются с помощью компаратора, элементы каждой группы проецируются с помощью указанной функции.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Группирует элементы последовательности в соответствии с функцией селектора ключа.Ключи сравниваются с помощью компаратора, элементы каждой группы проецируются с помощью указанной функции.
</td></tr>
<tr><td>
<code><b>function </b>GroupBy&lt;Key,Res&gt;(keySelector: T-&gt;Key; resultSelector: (Key,<b>sequence of</b> T)-&gt;Res): <b>sequence of</b> Res;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Группирует элементы последовательности в соответствии с заданной функцией селектора ключа и создает результирующее значение для каждой группы и ее ключа.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Группирует элементы последовательности в соответствии с заданной функцией селектора ключа и создает результирующее значение для каждой группы и ее ключа.
</td></tr>
<tr><td>
<code><b>function </b>GroupBy&lt;Key,Element,Res&gt;(keySelector: T-&gt;Key; elementSelector: T-&gt;Element; resultSelector: (Key,<b>sequence of</b> Element)-&gt;Res): <b>sequence of</b> Res;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Группирует элементы последовательности в соответствии с заданной функцией селектора ключа и создает результирующее значение для каждой группы и ее ключа.Элементы каждой группы проецируются с помощью указанной функции.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Группирует элементы последовательности в соответствии с заданной функцией селектора ключа и создает результирующее значение для каждой группы и ее ключа.Элементы каждой группы проецируются с помощью указанной функции.
</td></tr>
<tr><td>
<code><b>function </b>GroupBy&lt;Key,Res&gt;(keySelector: T-&gt;Key; resultSelector: (Key,<b>sequence of</b> T)-&gt;Res; comparer: IEqualityComparer&lt;Key&gt;): <b>sequence of</b> Res;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Группирует элементы последовательности в соответствии с заданной функцией селектора ключа и создает результирующее значение для каждой группы и ее ключа.Ключи сравниваются с использованием заданного компаратора.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Группирует элементы последовательности в соответствии с заданной функцией селектора ключа и создает результирующее значение для каждой группы и ее ключа.Ключи сравниваются с использованием заданного компаратора.
</td></tr>
<tr><td>
<code><b>function </b>GroupBy&lt;Key,Element,Res&gt;(keySelector: T-&gt;Key; elementSelector: System.T-&gt;Element; resultSelector: (Key,<b>sequence of</b> Element)-&gt;Res; comparer: IEqualityComparer&lt;Key&gt;): <b>sequence of</b> Res;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Группирует элементы последовательности в соответствии с заданной функцией селектора ключа и создает результирующее значение для каждой группы и ее ключа.Значения ключей сравниваются с помощью указанного компаратора, элементы каждой группы проецируются с помощью указанной функции.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Группирует элементы последовательности в соответствии с заданной функцией селектора ключа и создает результирующее значение для каждой группы и ее ключа.Значения ключей сравниваются с помощью указанного компаратора, элементы каждой группы проецируются с помощью указанной функции.
</td></tr>
</table>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
a := Arr(('Иванов',3),('Попов',1),('Авилов',1),<br>&nbsp;&nbsp;&nbsp;
('Козлов',3),('Ослов',2),('Рогов',1));<br>&nbsp; <strong>var</strong> groups
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
a := Arr(('Иванов',3),('Попов',1),('Авилов',1),<br>&nbsp;&nbsp;&nbsp;
('Козлов',3),('Ослов',2),('Рогов',1));<br>&nbsp; <strong>var</strong> groups
:= a.GroupBy(s-&gt;s[1]);<br><br>&nbsp; <strong>foreach</strong> <strong>var</strong>
g <strong>in</strong> groups <strong>do</strong><br>&nbsp; <strong>begin</strong><br>&nbsp;&nbsp;&nbsp;
Print(g.Key+':');<br>&nbsp;&nbsp;&nbsp; g.Select(x-&gt;x[0]).Println;<br>&nbsp;
<strong>end</strong>; <br><strong>end</strong>.<br><br>Вывод:<br>3: Иванов
Козлов<br>1: Попов Авилов Рогов<br>2: Ослов</code></blockquote>
<strong>end</strong>; <br><strong>end</strong>.<br><br>Вывод:<br>3: Иванов
Козлов<br>1: Попов Авилов Рогов<br>2: Ослов</code></blockquote>
</body>

View file

@ -2,21 +2,21 @@
<param name="Keyword" value="GroupJoin">
</object><meta http-equiv="Content-Type" content="text/html; charset=windows-1251"><title></title><link rel="StyleSheet" href="../../../default.css"></head>
<body>
<H1>Метод GroupJoin</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<H1>Метод GroupJoin</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<tr><td>
<code><b>function </b>GroupJoin&lt;TInner,Key,Res&gt;(inner: <b>sequence of</b> TInner; outerKeySelector: T-&gt;Key; innerKeySelector: TInner-&gt;TKey; resultSelector: (T,<b>sequence of</b> TInner)-&gt;Res): <b>sequence of</b> Res;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Объединяет две последовательности на основе равенства ключей и группирует результаты. Затем функция resultSelector проектирует ключ и последовательность соответствующих ему значений на элемент результирующей последовательности.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Объединяет две последовательности на основе равенства ключей и группирует результаты. Затем функция resultSelector проектирует ключ и последовательность соответствующих ему значений на элемент результирующей последовательности.
</td></tr>
<tr><td>
<code><b>function </b>GroupJoin&lt;TInner,Key,Res&gt;(inner: <b>sequence of</b> TInner; outerKeySelector: T-&gt;Key; innerKeySelector: TInner-&gt;TKey; resultSelector: (T,<b>sequence of</b> TInner)-&gt;Res; comparer: IEqualityComparer&lt;Key&gt;): <b>sequence of</b> Res;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Объединяет две последовательности на основе равенства ключей и группирует результаты. Для сравнения ключей используется указанный компаратор. Затем функция resultSelector проектирует ключ и последовательность соответствующих ему значений на элемент результирующей последовательности.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Объединяет две последовательности на основе равенства ключей и группирует результаты. Для сравнения ключей используется указанный компаратор. Затем функция resultSelector проектирует ключ и последовательность соответствующих ему значений на элемент результирующей последовательности.
</td></tr>
</table>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
people := Arr((1,'Иванов'),(2,'Попов'),(3,'Сидоров'));<br>&nbsp; <strong>var</strong>
subjects := Arr((1,'История'),(1,'Математика'),(2,'История')<br>&nbsp;&nbsp;&nbsp;
,(3,'Математика'),(1,'Русский'),(2,'Физика'));<br><br>&nbsp;
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
people := Arr((1,'Иванов'),(2,'Попов'),(3,'Сидоров'));<br>&nbsp; <strong>var</strong>
subjects := Arr((1,'История'),(1,'Математика'),(2,'История')<br>&nbsp;&nbsp;&nbsp;
,(3,'Математика'),(1,'Русский'),(2,'Физика'));<br><br>&nbsp;
people.GroupJoin(subjects,p-&gt;p[0],s-&gt;s[0],(p,ss)-&gt;(p[1],ss.Select(x-&gt;x[1]))).Println(NewLine);<br>
<strong>end</strong>.<br><br>Вывод:<br>(Иванов,[История,Математика,Русский])<br>
(Попов,[История,Физика])<br>(Сидоров,[Математика])</code></blockquote>
<strong>end</strong>.<br><br>Вывод:<br>(Иванов,[История,Математика,Русский])<br>
(Попов,[История,Физика])<br>(Сидоров,[Математика])</code></blockquote>
</body>

View file

@ -2,22 +2,22 @@
<param name="Keyword" value="Join">
</object><meta http-equiv="Content-Type" content="text/html; charset=windows-1251"><title></title><link rel="StyleSheet" href="../../../default.css"></head>
<body>
<H1>Методы Join</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<H1>Методы Join</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<tr><td>
<code><b>function </b>Join&lt;TInner,Key,Res&gt;(inner: <b>sequence of</b> TInner; outerKeySelector: T-&gt;Key; innerKeySelector: TInner-&gt;TKey; resultSelector: (T,TInner)-&gt;Res): <b>sequence of</b> Res;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Объединяет две последовательности на основе сопоставления ключей в третью последовательность. Функция resultSelector задаёт проекцию элементов двух последовательностей с одинаковыми значениями ключа в элемент третьей последовательности.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Объединяет две последовательности на основе сопоставления ключей в третью последовательность. Функция resultSelector задаёт проекцию элементов двух последовательностей с одинаковыми значениями ключа в элемент третьей последовательности.
</td></tr>
<tr><td>
<code><b>function </b>Join&lt;TInner,Key,Res&gt;(inner: <b>sequence of</b> TInner; outerKeySelector: T-&gt;Key; innerKeySelector: TInner-&gt;TKey; resultSelector: (T,TInner)-&gt;Res; comparer: System.Collections.Generic.IEqualityComparer&lt;Key&gt;): <b>sequence of</b> Res;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Объединяет две последовательности на основе сопоставления ключей в третью последовательность. Функция resultSelector задаёт проекцию элементов двух последовательностей с одинаковыми значениями ключа в элемент третьей последовательности. Для сравнения ключей используется компаратор comparer.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Объединяет две последовательности на основе сопоставления ключей в третью последовательность. Функция resultSelector задаёт проекцию элементов двух последовательностей с одинаковыми значениями ключа в элемент третьей последовательности. Для сравнения ключей используется компаратор comparer.
</td></tr>
</table>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
people := Arr((1,'Иванов'),(2,'Попов'),(3,'Сидоров'));<br>&nbsp; <strong>var</strong>
subjects := Arr((1,'История'),(1,'Математика'),(2,'История')<br>&nbsp;&nbsp;&nbsp;
,(3,'Математика'),(1,'Русский'),(2,'Физика'));<br><br>&nbsp;
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
people := Arr((1,'Иванов'),(2,'Попов'),(3,'Сидоров'));<br>&nbsp; <strong>var</strong>
subjects := Arr((1,'История'),(1,'Математика'),(2,'История')<br>&nbsp;&nbsp;&nbsp;
,(3,'Математика'),(1,'Русский'),(2,'Физика'));<br><br>&nbsp;
people.Join(subjects,p-&gt;p[0],s-&gt;s[0],(p,s)-&gt;(p[1],s[1])).Println(NewLine);<br>
<strong>end</strong>.<br><br>Вывод:<br>(Иванов,История)<br>
(Иванов,Математика)<br>(Иванов,Русский)<br>(Попов,История)<br>(Попов,Физика)<br>
(Сидоров,Математика)</code></blockquote>
<strong>end</strong>.<br><br>Вывод:<br>(Иванов,История)<br>
(Иванов,Математика)<br>(Иванов,Русский)<br>(Попов,История)<br>(Попов,Физика)<br>
(Сидоров,Математика)</code></blockquote>
</body>

View file

@ -2,13 +2,13 @@
<param name="Keyword" value="JoinIntoString">
</object><meta http-equiv="Content-Type" content="text/html; charset=windows-1251"><title></title><link rel="StyleSheet" href="../../../default.css"></head>
<body>
<H1>Метод JoinIntoString</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<H1>Метод JoinIntoString</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<tr><td>
<code><b>function </b>JoinIntoString(delim: string := ' '): string;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Преобразует элементы последовательности в строковое представление, после чего объединяет их в строку, используя delim в качестве разделителя.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Преобразует элементы последовательности в строковое представление, после чего объединяет их в строку, используя delim в качестве разделителя.
</td></tr>
</table>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
a := Arr('aaa','bbb','ccc');<br>&nbsp; <strong>var</strong> s: string :=
a.JoinIntoString('');<br>&nbsp; Println(s); // aaabbbccc<br><strong>end</strong>.</code></blockquote>
</body>

View file

@ -3,25 +3,25 @@
<param name="Keyword" value="LastOrDefault">
</object><meta http-equiv="Content-Type" content="text/html; charset=windows-1251"><title></title><link rel="StyleSheet" href="../../../default.css"></head>
<body>
<H1>Методы Last, LastOrDefault</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<H1>Методы Last, LastOrDefault</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<tr><td>
<code><b>function </b>Last(): T;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает последний элемент последовательности.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает последний элемент последовательности.
</td></tr>
<tr><td>
<code><b>function </b>Last(predicate: T-&gt;boolean): T;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает последний элемент последовательности, удовлетворяющий указанному условию.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает последний элемент последовательности, удовлетворяющий указанному условию.
</td></tr>
<tr><td>
<code><b>function </b>LastOrDefault(): T;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает последний элемент последовательности или значение по умолчанию, если последовательность не содержит элементов.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает последний элемент последовательности или значение по умолчанию, если последовательность не содержит элементов.
</td></tr>
<tr><td>
<code><b>function </b>LastOrDefault(predicate: T-&gt;boolean): T;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает последний элемент последовательности, удовлетворяющий указанному условию, или значение по умолчанию, если ни одного такого элемента не найдено.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает последний элемент последовательности, удовлетворяющий указанному условию, или значение по умолчанию, если ни одного такого элемента не найдено.
</td></tr>
</table>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
a := Arr(1,2,3,4);<br>&nbsp; Println(a.Last); // 4<br>&nbsp;
Println(a.Last(x -&gt; x <strong>mod</strong> 2 = 0); // 4<br>&nbsp;
Println(a.LastOrDefault(x -&gt; x&gt;5); // 0<br><strong>end</strong>.</code></blockquote>

View file

@ -3,27 +3,27 @@
<param name="Keyword" value="Max">
</object><meta http-equiv="Content-Type" content="text/html; charset=windows-1251"><title></title><link rel="StyleSheet" href="../../../default.css"></head>
<body>
<H1>Методы Min, Max</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<H1>Методы Min, Max</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<tr><td>
<code><b>function </b>Min(): число;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Вычисляет минимальный элемент последовательности значений числового типа.
<code><b>function </b>Min(): число;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Вычисляет минимальный элемент последовательности значений числового типа.
</td></tr>
<tr><td>
<code><b>function </b>Min(selector: T-&gt;число): число;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Вызывает функцию преобразования для каждого элемента последовательности и возвращает минимальное значение числового типа.
<code><b>function </b>Min(selector: T-&gt;число): число;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Вызывает функцию преобразования для каждого элемента последовательности и возвращает минимальное значение числового типа.
</td></tr>
<tr><td>
<code><b>function </b>Max(): число;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Вычисляет максимальный элемент последовательности значений числового типа.
<code><b>function </b>Max(): число;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Вычисляет максимальный элемент последовательности значений числового типа.
</td></tr>
<tr><td>
<code><b>function </b>Max(selector: T-&gt;число): число;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Вызывает функцию преобразования для каждого элемента последовательности и возвращает максимальное значение числового типа.
<code><b>function </b>Max(selector: T-&gt;число): число;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Вызывает функцию преобразования для каждого элемента последовательности и возвращает максимальное значение числового типа.
</td></tr>
</table>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
a := Lst(1,3,5,6);<br>&nbsp; Println(a.Min, a.Max); <br>&nbsp; <strong>var</strong>
b :=
Arr(('Иванов',20),('Попов',21),('Авилов',28));<br>&nbsp; Println(b.Min(x -&gt;
Arr(('Иванов',20),('Попов',21),('Авилов',28));<br>&nbsp; Println(b.Min(x -&gt;
x[1]));&nbsp;&nbsp; <br><strong>end</strong>.</code></blockquote>
</body>

View file

@ -2,13 +2,13 @@
<param name="Keyword" value="OfType">
</object><meta http-equiv="Content-Type" content="text/html; charset=windows-1251"><title></title><link rel="StyleSheet" href="../../../default.css"></head>
<body>
<H1>Метод OfType</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<H1>Метод OfType</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<tr><td>
<code><b>function </b>OfType&lt;Res&gt;(): <b>sequence of</b> Res;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Выполняет фильтрацию элементов объекта System.Collections.IEnumerable по заданному типу. Возвращает подпоследовательность данной последовательности. в которой все элементы принадлежат заданному типу.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Выполняет фильтрацию элементов объекта System.Collections.IEnumerable по заданному типу. Возвращает подпоследовательность данной последовательности. в которой все элементы принадлежат заданному типу.
</td></tr>
</table>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
a := new object[](1,2.5,'d','ff',3.4);<br>&nbsp; a.OfType&amp;&lt;real&gt;().Println;<br>
<strong>end</strong>.</code></blockquote>
</body>

View file

@ -3,27 +3,27 @@
<param name="Keyword" value="OrderByDescending">
</object><meta http-equiv="Content-Type" content="text/html; charset=windows-1251"><title></title><link rel="StyleSheet" href="../../../default.css"></head>
<body>
<H1>Методы OrderBy, OrderByDescending</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<H1>Методы OrderBy, OrderByDescending</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<tr><td>
<code><b>function </b>OrderBy&lt;Key&gt;(keySelector: T-&gt;Key): System.Linq.IOrderedEnumerable&lt;T&gt;;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Сортирует элементы последовательности в порядке возрастания ключа и возвращает отсортированнную последовательность. keySelector - функция, проектирующая элемент на ключ.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Сортирует элементы последовательности в порядке возрастания ключа и возвращает отсортированнную последовательность. keySelector - функция, проектирующая элемент на ключ.
</td></tr>
<tr><td>
<code><b>function </b>OrderBy&lt;Key&gt;(keySelector: T-&gt;Key; comparer: IComparer&lt;Key&gt;): System.Linq.IOrderedEnumerable&lt;T&gt;;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Сортирует элементы последовательности в порядке возрастания с использованием компаратора comparer и возвращает отсортированнную последовательность. keySelector - функция, проектирующая элемент на ключ.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Сортирует элементы последовательности в порядке возрастания с использованием компаратора comparer и возвращает отсортированнную последовательность. keySelector - функция, проектирующая элемент на ключ.
</td></tr>
<tr><td>
<code><b>function </b>OrderByDescending&lt;Key&gt;(keySelector: T-&gt;Key): System.Linq.IOrderedEnumerable&lt;T&gt;;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Сортирует элементы последовательности в порядке убывания ключа и возвращает отсортированнную последовательность. keySelector - функция, проектирующая элемент на ключ.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Сортирует элементы последовательности в порядке убывания ключа и возвращает отсортированнную последовательность. keySelector - функция, проектирующая элемент на ключ.
</td></tr>
<tr><td>
<code><b>function </b>OrderByDescending&lt;Key&gt;(keySelector: T-&gt;Key; comparer: IComparer&lt;Key&gt;): System.Linq.IOrderedEnumerable&lt;T&gt;;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Сортирует элементы последовательности в порядке убывания с использованием компаратора comparer и возвращает отсортированнную последовательность. keySelector - функция, проектирующая элемент на ключ.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Сортирует элементы последовательности в порядке убывания с использованием компаратора comparer и возвращает отсортированнную последовательность. keySelector - функция, проектирующая элемент на ключ.
</td></tr>
</table>
<h2>Пример </h2><blockquote><code><strong>begin<br>&nbsp; var</strong> a :=
Arr(('Иванов',20),('Попов',21),('Авилов',28));<br>&nbsp; a.OrderBy(t -&gt;
<h2>Пример </h2><blockquote><code><strong>begin<br>&nbsp; var</strong> a :=
Arr(('Иванов',20),('Попов',21),('Авилов',28));<br>&nbsp; a.OrderBy(t -&gt;
t[0]).Println;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// (Авилов,28) (Иванов,20) (Попов,21)<br>&nbsp; a.OrderByDescending(t -&gt;
t[1]).Println; // (Авилов,28) (Попов,21) (Иванов,20)<br><strong>end</strong>.</code></blockquote>
// (Авилов,28) (Иванов,20) (Попов,21)<br>&nbsp; a.OrderByDescending(t -&gt;
t[1]).Println; // (Авилов,28) (Попов,21) (Иванов,20)<br><strong>end</strong>.</code></blockquote>
</body>

View file

@ -2,17 +2,17 @@
<param name="Keyword" value="Print">
</object><meta http-equiv="Content-Type" content="text/html; charset=windows-1251"><title></title><link rel="StyleSheet" href="../../../default.css"></head>
<body>
<H1>Методы Print</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<H1>Методы Print</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<tr><td>
<code><b>function </b>Print(delim: string := ' '): <b>sequence of</b> T;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Выводит последовательность на экран, используя delim в качестве разделителя.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Выводит последовательность на экран, используя delim в качестве разделителя.
</td></tr>
<tr><td>
<code><b>function </b>Println(delim: string := ' '): <b>sequence of</b> T;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Выводит последовательность на экран, используя delim в качестве разделителя, и переходит на новую строку.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Выводит последовательность на экран, используя delim в качестве разделителя, и переходит на новую строку.
</td></tr>
</table>
<h2>Пример </h2><blockquote><code><strong>begin<br>&nbsp; var</strong> a :=
<h2>Пример </h2><blockquote><code><strong>begin<br>&nbsp; var</strong> a :=
Arr(1,3,5);<br>&nbsp; a.Println;<br>&nbsp;
ReadLines('a.txt').Println(NewLine); <br><strong>end</strong>.</code></blockquote>
</body>

View file

@ -2,13 +2,13 @@
<param name="Keyword" value="Reverse">
</object><meta http-equiv="Content-Type" content="text/html; charset=windows-1251"><title></title><link rel="StyleSheet" href="../../../default.css"></head>
<body>
<H1>Метод Reverse</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<H1>Метод Reverse</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<tr><td>
<code><b>function </b>Reverse(): <b>sequence of</b> T;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает инвертированную последовательность.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает инвертированную последовательность.
</td></tr>
</table>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
a := Range(1,9);<br>&nbsp; a.Reverse.Println; // 9 8 7 6 5 4 3 2 1<br>
<strong>end</strong>.</code></blockquote>
</body>

View file

@ -2,17 +2,17 @@
<param name="Keyword" value="Select">
</object><meta http-equiv="Content-Type" content="text/html; charset=windows-1251"><title></title><link rel="StyleSheet" href="../../../default.css"></head>
<body>
<H1>Метод проецирования Select</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<H1>Метод проецирования Select</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<tr><td>
<code><b>function </b>Select&lt;Res&gt;(selector: T-&gt;Res): <b>sequence of</b> Res;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Проецирует каждый элемент последовательности на другой элемент с помощью функции selector. Возвращает последовательность элементов, полученных в результате проецирования.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Проецирует каждый элемент последовательности на другой элемент с помощью функции selector. Возвращает последовательность элементов, полученных в результате проецирования.
</td></tr>
<tr><td>
<code><b>function </b>Select&lt;Res&gt;(selector: (T,integer)-&gt;Res): <b>sequence of</b> Res;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Проецирует каждый элемент последовательности на другой элемент с помощью функции selector, учитывающую индекс элемента. Возвращает последовательность элементов, полученных в результате проецирования.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Проецирует каждый элемент последовательности на другой элемент с помощью функции selector, учитывающую индекс элемента. Возвращает последовательность элементов, полученных в результате проецирования.
</td></tr>
</table>
<h2>Пример </h2>
<h2>Пример </h2>
<blockquote>
<code>
<strong>begin</strong><br>&nbsp; <strong>var</strong> a :=

View file

@ -2,25 +2,25 @@
<param name="Keyword" value="SelectMany">
</object><meta http-equiv="Content-Type" content="text/html; charset=windows-1251"><title></title><link rel="StyleSheet" href="../../../default.css"></head>
<body>
<H1>Метод проецирования SelectMany</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<H1>Метод проецирования SelectMany</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<tr><td>
<code><b>function </b>SelectMany&lt;Res&gt;(selector: T-&gt;<b>sequence of</b> Res): <b>sequence of</b> Res;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Проецирует каждый элемент последовательности в новую последовательность и объединяет результирующие последовательности в одну последовательность. Возвращает объединённую последовательность.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Проецирует каждый элемент последовательности в новую последовательность и объединяет результирующие последовательности в одну последовательность. Возвращает объединённую последовательность.
</td></tr>
<tr><td>
<code><b>function </b>SelectMany&lt;Res&gt;(selector: (T,integer)-&gt;<b>sequence of</b> Res): <b>sequence of</b> Res;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Проецирует каждый элемент последовательности в новую последовательность с учетом индекса элемента и объединяет результирующие последовательности в одну последовательность. Возвращает объединённую последовательность.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Проецирует каждый элемент последовательности в новую последовательность с учетом индекса элемента и объединяет результирующие последовательности в одну последовательность. Возвращает объединённую последовательность.
</td></tr>
<tr><td>
<code><b>function </b>SelectMany&lt;Coll,Res&gt;(collSelector: (T,integer)-&gt;<b>sequence of</b> Coll; resultSelector: (T,Coll)-&gt;Res): <b>sequence of</b> Res;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Проецирует каждый элемент последовательности в новую последовательность, объединяет результирующие последовательности в одну и вызывает функцию селектора результата для каждого элемента этой последовательности. Индекс каждого элемента исходной последовательности используется в промежуточной проецированной форме этого элемента. Возвращает объединённую последовательность.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Проецирует каждый элемент последовательности в новую последовательность, объединяет результирующие последовательности в одну и вызывает функцию селектора результата для каждого элемента этой последовательности. Индекс каждого элемента исходной последовательности используется в промежуточной проецированной форме этого элемента. Возвращает объединённую последовательность.
</td></tr>
<tr><td>
<code><b>function </b>SelectMany&lt;Coll,Res&gt;(collSelector: T-&gt;<b>sequence of</b> Coll; resultSelector: (T,Coll)-&gt;Res): <b>sequence of</b> Res;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Проецирует каждый элемент последовательности в новую последовательность, объединяет результирующие последовательности в одну и вызывает функцию селектора результата для каждого элемента этой последовательности. Возвращает объединённую последовательность.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Проецирует каждый элемент последовательности в новую последовательность, объединяет результирующие последовательности в одну и вызывает функцию селектора результата для каждого элемента этой последовательности. Возвращает объединённую последовательность.
</td></tr>
</table>
<h2>Пример </h2><blockquote><code><strong>begin<br>&nbsp; var</strong> a :=
<h2>Пример </h2><blockquote><code><strong>begin<br>&nbsp; var</strong> a :=
Arr(Arr(1,2,3),Arr(4,5,6),Arr(7,8,9));<br>&nbsp; a.SelectMany(x -&gt;
x).Println; // 1 2 3 4 5 6 7 8 9<br><strong>end</strong>.</code></blockquote>
</body>

View file

@ -2,17 +2,17 @@
<param name="Keyword" value="SequenceEqual">
</object><meta http-equiv="Content-Type" content="text/html; charset=windows-1251"><title></title><link rel="StyleSheet" href="../../../default.css"></head>
<body>
<H1>Метод SequenceEqual</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<H1>Метод SequenceEqual</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<tr><td>
<code><b>function </b>SequenceEqual(second: <b>sequence of</b> T): boolean;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Определяет, совпадают ли две последовательности.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Определяет, совпадают ли две последовательности.
</td></tr>
<tr><td>
<code><b>function </b>SequenceEqual(second: <b>sequence of</b> T; comparer: IEqualityComparer&lt;T&gt;): boolean;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Определяет, совпадают ли две последовательности, используя для сравнения элементов указанный компаратор.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Определяет, совпадают ли две последовательности, используя для сравнения элементов указанный компаратор.
</td></tr>
</table>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
a := Arr(1,2,3);<br>&nbsp; <strong>var</strong> b := Lst(1,2,3);<br>&nbsp;
a.SequenceEqual(b);&nbsp; <br><strong>end</strong>.</code></blockquote>
</body>

View file

@ -3,26 +3,26 @@
<param name="Keyword" value="SingleOrDefault">
</object><meta http-equiv="Content-Type" content="text/html; charset=windows-1251"><title></title><link rel="StyleSheet" href="../../../default.css"></head>
<body>
<H1>Методы Single, SingleOrDefault</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<H1>Методы Single, SingleOrDefault</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<tr><td>
<code><b>function </b>Single(): T;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает единственный элемент последовательности и генерирует исключение, если число элементов последовательности отлично от 1.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает единственный элемент последовательности и генерирует исключение, если число элементов последовательности отлично от 1.
</td></tr>
<tr><td>
<code><b>function </b>Single(predicate: T-&gt;boolean): T;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает единственный элемент последовательности, удовлетворяющий заданному условию, и генерирует исключение, если таких элементов больше одного.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает единственный элемент последовательности, удовлетворяющий заданному условию, и генерирует исключение, если таких элементов больше одного.
</td></tr>
<tr><td>
<code><b>function </b>SingleOrDefault(): T;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает единственный элемент последовательности или значение по умолчанию, если последовательность пуста; если в последовательности более одного элемента, генерируется исключение.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает единственный элемент последовательности или значение по умолчанию, если последовательность пуста; если в последовательности более одного элемента, генерируется исключение.
</td></tr>
<tr><td>
<code><b>function </b>SingleOrDefault(predicate: T-&gt;boolean): T;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает единственный элемент последовательности, удовлетворяющий заданному условию, или значение по умолчанию, если такого элемента не существует; если условию удовлетворяет более одного элемента, генерируется исключение.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает единственный элемент последовательности, удовлетворяющий заданному условию, или значение по умолчанию, если такого элемента не существует; если условию удовлетворяет более одного элемента, генерируется исключение.
</td></tr>
</table>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
a := Arr(1,2,3,4);<br>&nbsp; Println(a.Single); // исключение<br>&nbsp;
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
a := Arr(1,2,3,4);<br>&nbsp; Println(a.Single); // исключение<br>&nbsp;
Println(a.Single(x -&gt; x&gt;3); // 4<br>&nbsp; Println(a.SingleOrDefault(x -&gt;
x&gt;5); // 0<br><strong>end</strong>.</code></blockquote>
</body>

View file

@ -3,19 +3,19 @@
<param name="Keyword" value="SortedDescending">
</object><meta http-equiv="Content-Type" content="text/html; charset=windows-1251"><title></title><link rel="StyleSheet" href="../../../default.css"></head>
<body>
<H1>Методы Sorted, SortedDescending</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<H1>Методы Sorted, SortedDescending</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<tr><td>
<code><b>function </b>Sorted(): <b>sequence of</b> T;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает отсортированную по возрастанию последовательность.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает отсортированную по возрастанию последовательность.
</td></tr>
</table>
<table>
<tr><td>
<code><b>function </b>SortedDescending(): <b>sequence of</b> T;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает отсортированную по убыванию последовательность.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает отсортированную по убыванию последовательность.
</td></tr>
</table>
<h2>Пример </h2><blockquote><code><strong>begin<br>&nbsp; var</strong> a :=
<h2>Пример </h2><blockquote><code><strong>begin<br>&nbsp; var</strong> a :=
Arr(6,2,7,4,8,1);<br>&nbsp; a.Sorted.Println; // 1 2 4 6 7 8 <br>&nbsp;
a.SortedDescending.Println; // 8 7 6 4 2 1<br><strong>end</strong>.</code></blockquote>
</body>

View file

@ -3,27 +3,27 @@
<param name="Keyword" value="Average">
</object><meta http-equiv="Content-Type" content="text/html; charset=windows-1251"><title></title><link rel="StyleSheet" href="../../../default.css"></head>
<body>
<H1>Методы Sum, Average</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<H1>Методы Sum, Average</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<tr><td>
<code><b>function </b>Sum(): число;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Вычисляет сумму последовательности значений числового типа.
<code><b>function </b>Sum(): число;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Вычисляет сумму последовательности значений числового типа.
</td></tr>
<tr><td>
<code><b>function </b>Sum(selector: T-&gt;число): число;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Вычисляет сумму последовательности значений числового типа, получаемой в результате применения функции преобразования к каждому элементу входной последовательности.
<code><b>function </b>Sum(selector: T-&gt;число): число;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Вычисляет сумму последовательности значений числового типа, получаемой в результате применения функции преобразования к каждому элементу входной последовательности.
</td></tr>
<tr><td>
<code><b>function </b>Average(): real;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Вычисляет среднее для последовательности значений числового типа.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Вычисляет среднее для последовательности значений числового типа.
</td></tr>
<tr><td>
<code><b>function </b>Average(selector: T-&gt;число): real;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Вычисляет среднее для последовательности значений числового типа, получаемой в результате применения функции преобразования к каждому элементу входной последовательности.
<code><b>function </b>Average(selector: T-&gt;число): real;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Вычисляет среднее для последовательности значений числового типа, получаемой в результате применения функции преобразования к каждому элементу входной последовательности.
</td></tr>
</table>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
<h2>Пример </h2><blockquote><code><strong>begin</strong><br>&nbsp; <strong>var</strong>
a := Lst(1,3,5,6);<br>&nbsp; Println(a.Sum); <br>&nbsp; <strong>var</strong>
b :=
Arr(('Иванов',20),('Попов',21),('Авилов',28));<br>&nbsp; Println(b.Average(x
Arr(('Иванов',20),('Попов',21),('Авилов',28));<br>&nbsp; Println(b.Average(x
-&gt; x[1]));&nbsp;&nbsp; <br><strong>end</strong>.</code></blockquote>
</body>

View file

@ -5,33 +5,33 @@
<param name="Keyword" value="SkipWhile">
</object><meta http-equiv="Content-Type" content="text/html; charset=windows-1251"><title></title><link rel="StyleSheet" href="../../../default.css"></head>
<body>
<H1>Методы Take, TakeWhile, Skip, SkipWhile</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<H1>Методы Take, TakeWhile, Skip, SkipWhile</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<tr><td>
<code><b>function </b>Take(count: integer): <b>sequence of</b> T;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает последовательность из count элементов с начала последовательности.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает последовательность из count элементов с начала последовательности.
</td></tr>
<tr><td>
<code><b>function </b>TakeWhile(predicate: T-&gt;boolean): <b>sequence of</b> T;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает цепочку элементов последовательности, удовлетворяющих указанному условию, до первого не удовлетворяющего.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает цепочку элементов последовательности, удовлетворяющих указанному условию, до первого не удовлетворяющего.
</td></tr>
<tr><td>
<code><b>function </b>TakeWhile(predicate: (T,integer)-&gt;boolean): <b>sequence of</b> T;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает цепочку элементов последовательности, удовлетворяющих указанному условию, до первого не удовлетворяющего (учитывается индекс элемента).
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Возвращает цепочку элементов последовательности, удовлетворяющих указанному условию, до первого не удовлетворяющего (учитывается индекс элемента).
</td></tr>
<tr><td>
<code><b>function </b>Skip(count: integer): <b>sequence of</b> T;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Пропускает count элементов в последовательности и возвращает остальные элементы.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Пропускает count элементов в последовательности и возвращает остальные элементы.
</td></tr>
<tr><td>
<code><b>function </b>SkipWhile(predicate: T-&gt;boolean): <b>sequence of</b> T;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Пропускает элементы в последовательности, пока они удовлетворяют заданному условию, и затем возвращает оставшиеся элементы.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Пропускает элементы в последовательности, пока они удовлетворяют заданному условию, и затем возвращает оставшиеся элементы.
</td></tr>
<tr><td>
<code><b>function </b>SkipWhile(predicate: (T,integer)-&gt;boolean): <b>sequence of</b> T;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Пропускает элементы в последовательности, пока они удовлетворяют заданному условию, и затем возвращает оставшиеся элементы (учитывается индекс элемента).
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Пропускает элементы в последовательности, пока они удовлетворяют заданному условию, и затем возвращает оставшиеся элементы (учитывается индекс элемента).
</td></tr>
</table>
<h2>Пример </h2><blockquote><code><strong>begin<br>&nbsp; var</strong> a :=
<h2>Пример </h2><blockquote><code><strong>begin<br>&nbsp; var</strong> a :=
Arr(1,2,3,4,5,6);<br>&nbsp; a.Take(3).Println; // 1 2 3<br>&nbsp; a.Skip(3).Println;
// 4 5 6<br>&nbsp; a.Skip(2).Take(3).Println; // 3 4 5<br>&nbsp; a.TakeWhile(x
-&gt; x&lt;3).Println; // 1 2

View file

@ -3,30 +3,30 @@
<param name="Keyword" value="ThenByDescending">
</object><meta http-equiv="Content-Type" content="text/html; charset=windows-1251"><title></title><link rel="StyleSheet" href="../../../default.css"></head>
<body>
<H1>Методы ThenBy,ThenByDescending</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<H1>Методы ThenBy,ThenByDescending</H1><h2>Описание методов</h2><p>Методы приведены для последовательности <code><b>sequence of</b> T</code>.</p><table>
<tr><td>
<code><b>function </b>ThenBy&lt;Key&gt;(keySelector: T-&gt;Key): System.Linq.IOrderedEnumerable&lt;T&gt;;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Выполняет дополнительное упорядочение элементов последовательности в порядке возрастания ключа и возвращает отсортированнную последовательность. keySelector - функция, проектирующая элемент на ключ.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Выполняет дополнительное упорядочение элементов последовательности в порядке возрастания ключа и возвращает отсортированнную последовательность. keySelector - функция, проектирующая элемент на ключ.
</td></tr>
<tr><td>
<code><b>function </b>ThenBy&lt;Key&gt;(keySelector: T-&gt;Key; comparer: IComparer&lt;Key&gt;): System.Linq.IOrderedEnumerable&lt;T&gt;;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Выполняет дополнительное упорядочение элементов последовательности в порядке возрастания с использованием компаратора comparer и возвращает отсортированнную последовательность. keySelector - функция, проектирующая элемент на ключ.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Выполняет дополнительное упорядочение элементов последовательности в порядке возрастания с использованием компаратора comparer и возвращает отсортированнную последовательность. keySelector - функция, проектирующая элемент на ключ.
</td></tr>
<tr><td>
<code><b>function </b>ThenByDescending&lt;Key&gt;(keySelector: T-&gt;Key): System.Linq.IOrderedEnumerable&lt;T&gt;;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Выполняет дополнительное упорядочение элементов последовательности в порядке убывания ключа и возвращает отсортированнную последовательность. keySelector - функция, проектирующая элемент на ключ.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Выполняет дополнительное упорядочение элементов последовательности в порядке убывания ключа и возвращает отсортированнную последовательность. keySelector - функция, проектирующая элемент на ключ.
</td></tr>
<tr><td>
<code><b>function </b>ThenByDescending&lt;Key&gt;(keySelector: T-&gt;Key; comparer: IComparer&lt;Key&gt;): System.Linq.IOrderedEnumerable&lt;T&gt;;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Выполняет дополнительное упорядочение элементов последовательности в порядке убывания с использованием компаратора comparer и возвращает отсортированнную последовательность. keySelector - функция, проектирующая элемент на ключ.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Выполняет дополнительное упорядочение элементов последовательности в порядке убывания с использованием компаратора comparer и возвращает отсортированнную последовательность. keySelector - функция, проектирующая элемент на ключ.
</td></tr>
</table>
<h2>Пример </h2><blockquote>
<h2>Пример </h2><blockquote>
<code>
<strong>begin</strong><br>&nbsp; <strong>var </strong>&nbsp;a
:= Arr(('Иванов', 20), ('Попов', 21), <br>&nbsp;&nbsp;&nbsp; ('Иванов', 18),
('Авилов', 28), ('Иванов', 25));<br>&nbsp; a.OrderBy(t -&gt; t[0]).ThenBy(t -&gt;
t[1]).Println;<br>&nbsp;&nbsp;&nbsp; // (Авилов,28) (Иванов,18) (Иванов,20)
(Иванов,25) (Попов,21)
:= Arr(('Иванов', 20), ('Попов', 21), <br>&nbsp;&nbsp;&nbsp; ('Иванов', 18),
('Авилов', 28), ('Иванов', 25));<br>&nbsp; a.OrderBy(t -&gt; t[0]).ThenBy(t -&gt;
t[1]).Println;<br>&nbsp;&nbsp;&nbsp; // (Авилов,28) (Иванов,18) (Иванов,20)
(Иванов,25) (Попов,21)
<br><strong>end</strong>.</code></blockquote>
</body>

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