Инструменты пользователя

Инструменты сайта


bb:redbook:205

Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Предыдущая версия справа и слева Предыдущая версия
Следующая версия
Предыдущая версия
bb:redbook:205 [2017/08/30 10:30]
prospero78 [2.2 Инициализация типа tString]
bb:redbook:205 [2020/10/29 07:08] (текущий)
Строка 29: Строка 29:
  
 ==== 2.2 Инициализация типа tString ==== ==== 2.2 Инициализация типа tString ====
-Поскольку теперь у нас не просто массив литер в кодировке Unicode, а целая запись с полями — прежде чем использовать такую структуру её нужно привести в порядок. Из примеров, которые встречались ранее известно, что переменные без начального присвоения содержат мусор. Ниже приводится текст процедуры, которая как раз подготавливает к использования пользовательский тип туСтрока:+Поскольку теперь у нас не просто массив литер в кодировке ''Unicode'', а целая запись с полями — прежде чем использовать такую структуру её нужно привести в порядок. Из примеров, которые встречались ранее известно, что переменные без начального присвоения содержат мусор. Ниже приводится текст процедуры, которая как раз подготавливает к использования пользовательский тип ''туСтрока'':
 <code=oberon2> <code=oberon2>
 PROCEDURE (сам: туСтрока) Настр, NEW; PROCEDURE (сам: туСтрока) Настр, NEW;
- VAR +VAR 
- (* счётчик инициализации строки *) + (* счётчик инициализации строки *) 
- цИтер: INTEGER;+ цИтер: INTEGER;
 BEGIN BEGIN
  мЛог.String('[Инициализация текстового массива]'); Log.Ln;  мЛог.String('[Инициализация текстового массива]'); Log.Ln;
Строка 40: Строка 40:
  сам.длин_текущ := 0;  сам.длин_текущ := 0;
  FOR цИтер := 0 TO сам.длин_макс DO  FOR цИтер := 0 TO сам.длин_макс DO
- сам.текст[цИтер] := ''+ сам.текст[цИтер] := ' '
  END;  END;
 END Настр; END Настр;
 </code> </code>
-В этой процедуре сразу заметно отличие объявления процедуры от того, что объявлено ранее. Обозначение формальной принадлежности процедуры к типу ''туСтрока'' -- ''сам'' является калькой с английского  ''self''. Можно использовать вместо ''сам''-- всё-что угодно, но автор рекомендует по методическим соображением использовать именно ''сам''. Перед именем процедуры в скобках приведён параметр тип ''туСтрока''. Таким образом происходит привязка этой процедуры к записи. После такого определения можно обратиться к этой процедуре следующим образом:+В этой процедуре сразу заметно отличие объявления процедуры от того, что объявлено ранее. Обозначение формальной принадлежности процедуры к типу ''туСтрока'' -- ''сам'' является калькой с английского  ''self''. Можно использовать вместо ''сам'' -- всё-что угодно, но автор рекомендует по методическим соображением использовать именно ''сам''. Перед именем процедуры в скобках приведён параметр тип ''туСтрока''. Таким образом происходит привязка этой процедуры к записи. После такого определения можно обратиться к этой процедуре следующим образом:
  
  стр.Настр; (* стр — экземпляр записи типа PONTER TO туСтрока*)  стр.Настр; (* стр — экземпляр записи типа PONTER TO туСтрока*)
  
-Запись компактна, и не возникает вопросов по поводу принадлежности процедуры "Init". Процедур "Init" даже в одном модуле может быть определено несколько, если они обладают различной принадлежностью и параметрами. При программировании на типизированных языках процедуры с одинаковым именем, но разными параметрами обладают разными сигнатурами("подписями"), именно по ним компилятор и различает эти процедуры. Определение процедур с одинаковыми сигнатурами недопустимо.+Запись компактна, и не возникает вопросов по поводу принадлежности процедуры ''Настр''. Процедур ''Настр'' даже в одном модуле может быть определено несколько, если они обладают различной принадлежностью и параметрами. При программировании на типизированных языках процедуры с одинаковым именем, но разными параметрами обладают разными [[https://ru.wikipedia.org/wiki/API#.D0.A1.D0.B8.D0.B3.D0.BD.D0.B0.D1.82.D1.83.D1.80.D0.B0_.D1.84.D1.83.D0.BD.D0.BA.D1.86.D0.B8.D0.B8|сигнатурами]] ("подписями"), именно по ним компилятор и различает эти процедуры. Определение процедур с одинаковыми сигнатурами //недопустимо//.
  
-После имени процедуры следует ключевое слово NEW. Это означает, что для указанного типа эта процедура вводится впервые. Записи объединённые с процедурами в КП называются объектами. А процедуры, привязанные к записям (и, автоматически уже объектам) — методами объекта. Поля записей в составе объектов называются свойства объекта (так реализуется объектно-ориентированный подход (ООП) в Компонентном Паскале).+После имени процедуры следует //ключевое слово// ''NEW''. Это означает, что для указанного типа эта процедура вводится впервые. Записи объединённые с процедурами в **КП** называются [[https://ru.wikipedia.org/wiki/%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)|объектами]]. А процедуры, привязанные к записям (и, автоматически уже объектам) — //методами// объекта. Поля записей в составе объектов называются //свойства// объекта (так реализуется объектно-ориентированный подход (ООП) в **Компонентном Паскале**).
  
-Метод, который производит первоначальную настройку объекта в ООП принято называть инициализацией.+Метод, который производит первоначальную настройку объекта в ООП принято называть //инициализацией//.
  
-В самой процедуре происходит начальное присвоение полям записи первичных значений, массив литер получает в каждом элементе значение "пробел". Целочисленный цикл перебирает элементы массива с индекса "0по "2048", т.е. всего 2049 элементов. Но, элемент с индексом "0в дальнейшем использовать не предполагается. +В самой процедуре происходит начальное присвоение полям записи первичных значений, массив литер получает в каждом элементе значение "пробел". Целочисленный цикл перебирает элементы массива с индекса ''0'' по ''2048'', т.е. всего ''2049'' элементов. Но, элемент с индексом ''0'' в дальнейшем использовать не предполагается. Ещё раз надо заметить, что строение ''туСтрока'' таково, что такое частное решение в данном случае -- избыточно.
- +
-В целях отладки, чтобы убедиться в правильности процедуры — при начале её работы выводится контрольная строкакоторую в конечной программе можно удалить[↑]+
  
 +В целях отладки, чтобы убедиться в правильности процедуры — при начале её работы выводится контрольная строка, которую в конечной программе можно удалить.
  
 ==== 2.3 Ввод данных ==== ==== 2.3 Ввод данных ====
 Ввод данных уже разбирался, применим его снова в виде метода объекта: Ввод данных уже разбирался, применим его снова в виде метода объекта:
-   
-В этом методе опять можно наблюдать привязку к записи типа "tString", не используются никакие сторонние переменные. Заполнение массива будет производиться до тех пор, пока либо не закончится текст, либо не будет исчерпана длина массива. После каждого успешного ввода длина текста наращивается на единицу. Обратите внимание, что индексация позиции вставки текстового массива осуществляется через свойство самого объекта "len_txt". [↑] 
  
 +<code=oberon2>
 +PROCEDURE (сам: туСтрока) Читать, NEW;
 +BEGIN
 + мЛог.String('[Чтение входного текста]'); Log.Ln;
 + мВв.Open;
 + WHILE мВв.Done & (сам.длин_текущ < сам.длин_макс) DO
 + мВв.Char(сам.текст[сам.длин_текущ]);
 + INC(сам.длин_текущ)
 + END;
 + мЛог.String('Длина введённого текста: '); Log.Int(сам.длин_текущ); Log.Ln
 +END Читать;
 +</code>
 +
 +В этом методе опять можно наблюдать привязку к записи типа ''туСтрока'', не используются никакие сторонние переменные. Заполнение массива будет производиться до тех пор, пока либо не закончится текст, либо не будет исчерпана длина массива. После каждого успешного ввода длина текста наращивается на единицу. Обратите внимание, что индексация позиции вставки текстового массива осуществляется через свойство самого объекта ''длин_текущ''.
  
 ==== 2.4 Вывод текста ==== ==== 2.4 Вывод текста ====
-Вывод текста не является обязательной задачей, но всё-таки сделаем это, чтобы убедиться, что текст действительно будет "развёрнут на месте". Этот же метод будет использован для вывода перевёрнутого текста. Текст метода: +Вывод текста не является обязательной задачей, но всё-таки сделаем это, чтобы убедиться, что текст действительно будет "развёрнут на месте". Этот же метод будет использован для вывода перевёрнутого текста. Текст метода: FIXME 
-  +<code=oberon2> 
-   +</code>
- +
-В связи с тем, что литерный массив выводится не полностью, а только та часть, что получила заполнение, пришлось ввести локальную переменную "i". Он позволит выводить массив до тех пор, пока он не станет равным заполнению на вводе. [↑]+
  
 +В связи с тем, что литерный массив выводится не полностью, а только та часть, что получила заполнение, пришлось ввести локальную переменную ''i''. Он позволит выводить массив до тех пор, пока он не станет равным заполнению на вводе.
  
 ==== 2.5 Разворот текста на месте ==== ==== 2.5 Разворот текста на месте ====
-Разворот массива на месте выполним с помощью дополнительной переменной литерного типа, в качестве промежуточного хранилища элемента литерного массива. Середина введённого текста может быть найдена через целочисленное деление длины ведённого текста пополам. Для этого используется ключевое слово DIV (сокращение от DIVISION, "деление"). В остальном, метод похож на предыдущие.+Разворот массива на месте выполним с помощью дополнительной переменной литерного типа, в качестве промежуточного хранилища элемента литерного массива. Середина введённого текста может быть найдена через целочисленное деление длины ведённого текста пополам. Для этого используется ключевое слово **DIV** (сокращение от **DIVISION**, "деление"). В остальном, метод похож на предыдущие.
      
-Точно также в начале метода используется диагностический вывод. [↑]+Точно также в начале метода используется диагностический вывод.
  
  
 ==== 2.6 Главная процедура модуля ==== ==== 2.6 Главная процедура модуля ====
-По аналогии с предыдущими программами, эта процедура будет называться "Start". Общий вид процедуры: +По аналогии с предыдущими программами, эта процедура будет называться ''Start''. Общий вид процедуры: FIXME 
 +<code=oberon2> 
 +</code>
      
-Часть кода занято диагностическим выводом, другая вызовом методов переменной, имеющей тип "tString", и здесь тоже всё достаточно прозрачно. Единственная инструкция, требующая пояснения: NEW(txt). "txt— это переменная, имеющая тип "POINTER TO RECORD(тип "УКАЗАТЕЛЬ НА ЗАПИСЬ"). Ключевое слово NEW указывает на то, что эта переменная создаётся динамически. Динамическое создание переменных используется очень часто, и использование NEW широко распространено. Если определить переменную "txtне как динамическую, а как статическую, то размер программы сразу вырастит до примерно 4600 байт — за счёт массива CHAR на 2049 элементов (4098 байт). Без статического определения массива программа занимает порядка 640 байт. [↑]+Часть кода занято диагностическим выводом, другая вызовом методов переменной, имеющей тип ''tString'' и здесь тоже всё достаточно прозрачно. Единственная инструкция, требующая пояснения: ''NEW(txt)''''txt'' — это переменная, имеющая тип ''POINTER TO RECORD'' (тип ''УКАЗАТЕЛЬ НА ЗАПИСЬ''). Ключевое слово **NEW** указывает на то, что эта переменная создаётся динамически. Динамическое создание переменных используется очень часто, и использование **NEW** широко распространено. Если определить переменную ''txt'' не как динамическую, а как статическую, то размер программы сразу вырастит до примерно 4600 байт — за счёт массива **CHAR** на 2049 элементов (4098 байт). Без статического определения массива программа занимает порядка 640 байт.
  
  
 ==== 2.7 Итоговый текст программы ==== ==== 2.7 Итоговый текст программы ====
   
-Пример текста модуля ниже.+Пример текста модуля ниже. 
  
-Hello12.odc +Hello12.odc FIXME 
- +<code=oberon2> 
-   +</code>
- [↑]+
  
 ==== 2.8 Ввод и вывод данных ==== ==== 2.8 Ввод и вывод данных ====
-Для ввода данных использовать этот текст: +Для ввода данных использовать этот текст: FIXME 
 +<code> 
 +</code>
      
 Вывод программы, если всё сделано училось правильно: Вывод программы, если всё сделано училось правильно:
-  +<code> 
-   +</code>
- +
-Как видно, вместо переводов строк появился парный символ "0DX 09X" (в шестнадцатиричном виде). Даже простой текст такому развороту поддаётся с сюрпризами. Это символ перевода строки. Результат не совсем такой, как ожидалось. Как работать со строками будет рассмотрено отдельно. В качестве самостоятельного задания попробуйте сделать так, чтобы перевод строки сохранялся[2]. [↑]+
  
 +Как видно, вместо переводов строк появился парный символ ''0DX 09X'' (в шестнадцатиричном виде). Даже простой текст такому развороту поддаётся с сюрпризами. Это символ перевода строки. Результат не совсем такой, как ожидалось. Как работать со строками будет рассмотрено отдельно. В качестве самостоятельного задания попробуйте сделать так, чтобы перевод строки сохранялся((В качестве подсказки: надо найти все комбинации ''0DX 09Х'' и заменить их на ''00Х 00Х''. После разворота, найти эти же символы и заменить их опять на ''0DX 09Х'')).
  
-==== 3. Примечания ==== 
-[↑] В Паскаль-семействе трюк с пропуском нулевого элемента массива применяется повсеместно. Он бывает полезен в строках, когда чтобы точно установить длину строки — её длина содержится в нулевом элементе. Такие короткие строки (до 255 литералов) и средние строки (до 65,5 тыс. литералов) до сих пор популярны у паскалистов. Если конец строки будет испорчен, то процедуры обработки всё-равно закончат обработку по её размеру в нулевой ячейке. В этом отношении Паскаль-семейство более безопасно, чем лагерь Си — там для обозначения окончания строки в конце добавляется бинарный "00X". Можно себе представить, если вдруг в ближайших мегабайтах памяти этого символа не окажется. ,) Кроме того, затраты на подсчёт длины строки в Паскале равны нулю — подсчёт происходит мгновенно. Аналогичный подсчёт строки в Си будет выполняться крайне медленно (особенно, если строка занимает мегабайты). 
  
-[↑] В качестве подсказки: надо найти все комбинации "0DX 09Х" и заменить их на "00Х 00Х". После разворота, найти эти же символы и заменить их опять на "0DX 09Х". 
  
-[ ← Назад  ] [ Вверх ↑ ] [ Далее → ] 
bb/redbook/205.1504078224.txt.gz · Последнее изменение: 2020/10/29 07:08 (внешнее изменение)