Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
АиП теория 1-22.rtf
Скачиваний:
0
Добавлен:
01.03.2025
Размер:
1.86 Mб
Скачать

№16 1.Передача параметров по адресу в подпрограмме. Назначение параметров

Подпрограммы часто используются для многократного выполнения стереотипных действий над различными данными. Подпрограмма обычно имеет доступ к объектам данных, описанным в основной программе (по крайней мере, к некоторым из них), поэтому для того, чтобы передать в подпрограмму обрабатываемые данные, их достаточно присвоить, например, глобальным переменным. Но такой путь не особенно удобен и чреват ошибками. Для обеспечения контролируемой передачи параметров в подпрограмму и возврата результатов из неё используется механизм параметров. Параметры описываются при описании подпрограммы (в её заголовке) и могут использоваться внутри процедуры аналогично переменным, описанным в ней. При вызове процедуры значения каждого из параметров указываются в команде вызова (обычно после имени вызываемой подпрограммы).

program SubProgExample2;

// Описание подпрограммы subprog

procedure subprog(Line: String); // Заголовок, включающий имя подпрограммы

begin // начало тела подпрограммы

WriteLn(Line);

end; // конец тела подпрограммы

begin

WriteLn('Hello');

subprog('Good bye,'); // 1-й вызов

subprog('my love,'); // 2-й вызов

subprog('good bye!'); // 3-й вызов

end.

Способ передачи параметров в подпрограмму

Существует несколько способов передачи параметров в подпрограмму.

-Передача параметров по значению. Формальному параметру присваивается значение фактического параметра. В этом случае формальный параметр будет содержать копию значения, имеющегося в фактическом, и никакое воздействие, производимое внутри подпрограммы на формальные параметры, не отражается на параметрах фактических. Так, если в качестве фактического параметра будет использована переменная, и внутри подпрограммы значение соответствующего формального параметра будет изменено, то фактический параметр останется без изменений.

int func1(int x) { x=x+1; return x; }

-Передача параметров по ссылке. В формальный параметр может быть помещён сам фактический параметр (обычно это реализуется путём помещения в формальный параметр ссылки на фактический). При этом любое изменение формального параметра в подпрограмме отразится на фактическом параметре — оба параметра во время вызова подпрограммы суть одно и то же. Параметры, передаваемые по ссылке, дают возможность не только передавать параметры внутрь подпрограммы, но и возвращать вычисленные значения в точку вызова. Для этого параметру внутри подпрограммы просто присваивается нужное значение, и после возврата из подпрограммы переменная, использованная в качестве фактического параметра, получает это значение.

void func2(int &x) { x=x+1; }

-Передача параметров по имени. В формальный параметр может быть помещено произвольное выражение. При этом вычисление этого выражения произойдёт внутри подпрограммы в тот момент, когда потребуется его значение. Если это значение фигурирует несколько раз, то и вычисляться оно будет тоже несколько раз. Параметры, передаваемые по имени, дают возможность писать довольно универсальные подпрограммы. Такой способ передачи параметров используется, к примеру в языках Алгол или Алгол 68.

-Передача параметров через стек. Это фактически разновидность передачи параметра по значению «с ручным приводом», в данном случае отсутствует понятие формальных и фактических параметров. Все параметры лежат на стеке, причём их типы, количество и порядок не контролируются компилятором. Данный подход реализован в языке Форт.

Язык программирования может предоставлять возможность передавать параметры в подпрограммы либо только по значению (так сделано в языке Си), либо по значению и по ссылке (это реализовано в ПаскалеАде,C++), либо по имени и значению (это реализовано в языках Алгол и Алгол 68). В последних двух случаях для различения способов передачи параметра используются отдельные синтаксическая конструкции (в Паскале это ключевое слово var при описании параметра). В действительности, если язык содержит понятие ссылки (указателя), то можно обойтись и без передачи параметра по ссылке (её всегда можно смоделировать, описав параметр типа «ссылка»), но эта возможность удобна, так как позволяет работать с формальным параметром-ссылкой без разыменования, а также повышает надёжность и безопасность программы.

На параметры, передаваемые по ссылке, накладываются естественные ограничения: фактический параметр, подставляемый на место такого параметра при вызове, обязан быть переменной (то есть иметь адрес), а в языках со строгой типизацией — ещё и иметь в точности такой же тип данных.

17. 1. Строки данных.

В программировании, строковый тип (англ. string «нить, вереница») — тип данных, значениями которого является произвольная последовательность (строка) символов алфавита. Каждая переменная такого типа (строковая переменная) может быть представлена фиксированным количеством байтов либо иметь произвольную длину.

Представление в памяти. Некоторые языки программирования накладывают ограничения на максимальную длину строки, но в большинстве языков подобные ограничения отсутствуют. При использовании Unicode каждый символ строкового типа может требовать двух или даже четырёх байтов для своего представления. Основные проблемы в машинном представлении строкового типа:строки могут иметь достаточно существенный размер (до нескольких десятков мегабайтов);

изменяющийся со временем размер — возникают трудности с добавлением и удалением символов.

В представлении строк в памяти компьютера существует два принципиально разных подхода.. Представление массивом символов. В этом подходе строки представляются массивом символов; при этом размер массива хранится в отдельной (служебной) области. От названия языка Pascal, где этот метод был впервые реализован, данный метод получил название Pascal strings. Слегка оптимизированным вариантом этого метода является т. Н. формат c-addr u (от англ. Character-aligned address + unsigned number), применяемый в Форте. В отличие от Pascal strings, здесь размер массива хранится не совместно со строковыми данными, а является частью указателя на строку. Преимущества:программа в каждый момент времени «знает» о размере строки, и операции добавления символов в конец, копирования и получения размера строки выполняются достаточно быстро;

строка может содержать любые данные;возможно на программном уровне следить за выходом за границы строки при её обработке;возможно быстрое выполнение операции вида «взятие N-ого символа с конца строки».

Недостатки:проблемы с хранением и обработкой символов произвольной длины;увеличение затрат на хранение строк — значение «длина строки» также занимает место и в случае большого количества строк маленького размера может существенно увеличить требования алгоритма к оперативной памяти;ограничение максимального размера строки. В современных языках программирования это ограничение скорее теоретическое, так как обычно размер строки хранится в 32-битовом поле, что даёт максимальный размер строки в 4 294 967 295 байт (4 гигабайта).

Простейшие операции со строками:получение символа по номеру позиции (индексу) — в большинстве языков это тривиальная операция;конкатенация (соединение) строк.

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

Возможные задачи для строк на естественном языке

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

Представление символов строки

До последнего времени один символ всегда кодировался одним байтом (8 двоичных битов; применялись также кодировки с 7 битами на символ), что позволяло представлять 256 (128 при семибитной кодировке) возможных значений. Однако для полноценного представления символов алфавитов нескольких языков (многоязыковых документов, типографских символов — несколько видов кавычек, тире, нескольких видов пробелов и для написания текстов на иероглифических языках — китайском, японском и корейском) 256 символов недостаточно. Для решения этой проблемы существует несколько методов:

Переключение языка управляющими кодами. Метод не стандартизирован и лишает текст самостоятельности (то есть последовательность символов без управляющего кода в начале теряет смысл); использовался в некоторых ранних русификациях ZX-Spectrum и БК.

Использование двух или более байт для представления каждого символа (UTF-16, UTF-32). Главным недостатком этого метода является потеря совместимости с предыдущими библиотеками для работы с текстом при представлении строки как ASCIIZ. Например, концом строки должен считаться уже не байт со значением 0, а два или четыре подряд идущих нулевых байта, в то время как одиночный байт «0» может встречаться в середине строки, что сбивает библиотеку «с толку».

Использование кодировки с переменным размером символа. Например, в UTF-8 часть символов представляется одним байтом, часть двумя, тремя или четырьмя. Этот метод позволяет сохранить частичную совместимость со старыми библиотеками (нет символов 0 внутри строки и поэтому 0 можно использовать как признак конца строки), но приводит к невозможности прямой адресации символа в памяти по номеру его позиции в строке.

18.1.Записи данных

Запись – это структура данных, состоящая из фиксированного числа разнотипных компонент, называемых полями записи. Записи используются для представления разнородной, но логически связанной информации. Каждое поле записи имеет имя, которое даётся ему при объявлении записи. Тип полей записи может быть любым, в том числе и типом ранее объявленной записи, за исключением файлового типа. В Borland Pascal определены записи двух типов: записи с фиксированными полями и вариантные записи. В данной лабораторной работе рассматриваются только записи с фиксированными полями.

Данные типа записи можно использовать как простые переменные, так и формировать из них массивы. Объявление данных этого типа ничем не отличается от стандартных для языка способов. Объявление простых переменных можно выполнить непосредственно при объявлении переменных или через ранее объявленный тип записи. Принцип действия:Шлюз записи данных выступает в роли объекта, полностью повторяющего одну запись, например одну строку таблицы базы данных. Каждому столбцу таблицы соответствует поле записи. Обычно шлюз записи данных должен выполнять все возможные преобразования типов источника данных в типы, используемые приложением, однако эти преобразования весьма просты. Рассматриваемое типовое решение содержит все данные о строке, поэтому клиент имеет возможность непосредственного доступа к шлюзу записи данных. Шлюз выступает в роли интерфейса к строке данных и прекрасно подходит для применения всценариях транзакции (Transaction Script).

При реализации шлюза записи данных возникает вопрос: куда "пристроить" методы поиска, генерирующие экземпляр данного типового решения? Разумеется, можно воспользоваться статическими методами поиска, однако они исключают возможность полиморфизма (что могло бы пригодиться, если понадобиться определить разные методы поиска для различных источников данных). В подобной ситуации часто имеет смысл создать отдельные объекты поиска, чтобы у каждой таблицы реляционной базы данных был один класс для проведения поиска и один класс шлюза для сохранения результатов этого поиска.

Иногда шлюз записи данных трудно отличить от активной записи(Active Record). В этом случае следует обратить внимание на наличие какой-либо логики домена; если она есть, значит, это активная запись. Реализация шлюза записи данных должна включать в себя только логику доступа к базе данных и никакой логики домена.

Как и другие формы табличной инкапсуляции, шлюз записи данных можно применять не только к таблице, но и к представлению или запросу. Конечно же, в последних случаях существенно осложняется выполнение обновлений, поскольку приходиться обновлять таблицы, на основе которых были созданы соответствующие представления или запросы. Кроме того, если с одними и теми же таблицами работают два шлюза записи данных, обновление второго шлюза может аннулировать обновление первого. Универсального способа предотвратить эту проблему не существует; разработчикам просто необходимо следить за тем, как построены виртуальные шлюзы записи данных. В конце концов, это же может случиться и с обновляемыми представлениями. Разумеется, можно вообще не реализовать методы обновления.

Назначение:

Принимая решение об использовании шлюза записи данных, необходимо подумать о двух вещах: следует ли вообще использовать шлюз, и если да, то какой именно – шлюз записи данных или шлюз таблицы данных (Table Data Gateway).

Как правило, используют шлюз записи данных, когда есть сценарий транзакции. В этом случае доступ к базе данных легко реализовать таким образом, чтобы соответствующий код мог повторно использоваться другими сценариями транзакции.

Не используют шлюз записи данных с моделью предметной области (Domain Model). Если отображение на объекты домена достаточно простое, его можно реализовать и с помощью активной записи, не добавляя дополнительный слой кода. Если же отображение сложное, для его реализации рекомендуется применитьпреобразователь данных (Data Mapper). Последний лучше справляется с отделением структуры данных от объектов домена, потому что объектам домена не нужно знать о структуре базы данных. Конечно же, шлюз записи данных можно использовать, чтобы скрыть структуру базы данных от объектов домена. Это очень удобно, если вы собираетесь изменить структуру базы данных и не хотите менять логику домена. Тем не менее в этом случае у вас появится три различных представления данных: одно в бизнес-логике, одно в шлюзе записи данных и еще одно в базе данных. Для крупномасштабных систем это слишком много. Поэтому обычно используют шлюзы записи данных, отражающие структуру базы данных.

Интересно, что шлюз записи данных и преобразователь данных вполне могут сосуществовать. Несмотря на то, что с первого взгляда это кажется излишней тратой сил, сочетание шлюза записи данных и преобразователя данных может оказаться весьма эффективным в том случае, если первый автоматически генерируется на основе метаданных, а второй создается вручную.

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

Билет №19

1. Стандартные математические функции

Набор встроенных математических функций в языке Паскаль невелик, он включает :

1. Abs(x) - абсолютная величина числа.

2. Int(x) - целая часть вещественного числа.

3. Frac(x) - дробная часть вещественного числа.

4. Trunc(x) - целая часть вещественного числа, преобразованная к типу LongInt.

5. Round(x) - округленное до целого вещественное число, преобразованное к типу LongInt.

6. Sqr(x) - квадрат числа.

7. Sqrt(x) - квадратный корень.

8. Exp(x) - экспонента.

9. Ln(x) - натуральный логарифм.

10. Pi - число пи.

11. Sin(x) - синус.

12. Cos(x) - косинус.

13. Arctan(x) - арктангенс.

Все остальные математические функции можно получить, пользуясь этим основным набором; например: десятичный логарифм - Ln(x)/Ln(10), тангенс - Sin(x)/Cos(x) и т.д. Аргументы функций могут быть любыми арифметическими выражениями и задаются в круглых скобках после имени функции, аргументы функций Sin и Cos выражаются в радианах. Вычислим квадрат синуса 70 градусов: Sqr(Sin(Pi/180*70))

Кроме перечисленных выше математических функций Паскаль предоставляет еще несколько полезных числовых функций и процедур разного назначения:

14. High (целый тип) - возвращает наибольшее возможное значение данного типа.

15. Low (целый тип) - возвращает наименьшее возможное значение данного типа.

Билет №20

1. Стандартные функции и процедуры преобразования

.Функция или процедура может быть уже включена в сам язык программирования, а может входить в модуль, который требуется «подключить» к программе.

Ниже описаны стандартные (включенные в язык) функции языка программирования Паскаль.

Арифметические функции

Арифметические функции можно использовать только с величинами целого и вещественного типа.Функция Назначение Тип результата

abs (x) абсолютное значение аргумента совпадает с типом аргумента

sqr (x) квадрат аргумента совпадает с типом аргумента

sqrt (x) квадратный корень аргумента вещественный

cos (x) косинус аргумента вещественный

sin (x) синус аргумента вещественный

arctan (x) арктангенс аргумента вещественный

exp (x) ex вещественный

ln (x) натуральный логарифм вещественный

int (x) целая часть числа вещественный

frac (x) дробная часть числа вещественный

Функции преобразования типов

Эти функции предназначены для преобразования типов величин, например, символа в целое число, вещественного числа в целое и т.д. ord (x) - возвращает порядковый номер аргумента и, таким образом, преобразует величину порядкового типа в величину целого типа.

round (x) - округляет вещественное число до ближайшего целого.

trunk (x) - выдает целую часть вещественного числа, отбрасывая дробную.

Экзаменационный билет № 22

  1. Стандартные функции и процедуры для работы со строками и символами.