Пример программы с модулем

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

Перед подключением к главной программе модули компилируются и сохраняются на диске в виде файлов с тем же именем, но с расширением «.tpu» в каталоге, объявленном в меню Options-Compiler-Directories-EXE

Uses Roots;

Var W:char;

Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:

Источник: studopedia.ru

Как решать уравнения с модулем или Математический торт с кремом (часть 1) | Математика

Обзор модулей в C++

В C++20 представлены модули — современное решение, которое превращает библиотеки и программы C++ в компоненты. Модуль — это набор файлов исходного кода, которые компилируются независимо от исходных файлов (или, точнее, от единиц перевода, которые их импортируют). Модули устраняют или устраняют многие проблемы, связанные с использованием файлов заголовков.

Они часто сокращают время компиляции. Макросы, директивы препроцессора и неэкспортированные имена, объявленные в модуле, не видны за пределами модуля. Они не влияют на компиляцию единицы перевода, которая импортирует модуль. Модули можно импортировать в любом порядке, не беспокоясь о переопределениях макросов.

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

Модули можно использовать параллельно с файлами заголовков. Исходный файл C++ может import содержать модули, а также #include файлы заголовков. В некоторых случаях файл заголовка можно импортировать в виде модуля, что быстрее, чем использование #include для его обработки с помощью препроцессора. Рекомендуется как можно больше использовать модули в новых проектах, а не файлы заголовков.

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

Включение модулей в компиляторе Microsoft C++

Начиная с Visual Studio 2022 версии 17.1 стандартные модули C++20 полностью реализованы в компиляторе Microsoft C++.

#5. Математические функции и работа с модулем math | Python для начинающих

До того, как он был указан стандартом C++20, корпорация Майкрософт имела экспериментальную поддержку модулей. Компилятор также поддерживает импорт готовых модулей стандартной библиотеки, описанных ниже.

Начиная с Visual Studio 2022 версии 17.5 импорт стандартной библиотеки в виде модуля является стандартизованным и полностью реализован в компиляторе Microsoft C++. В этом разделе описывается старый экспериментальный метод, который по-прежнему поддерживается. Сведения о новом стандартизованном способе импорта стандартной библиотеки с помощью модулей см. в статье Импорт стандартной библиотеки C++ с помощью модулей.

Функцию модулей можно использовать для создания односекционных модулей и импорта модулей стандартной библиотеки, предоставляемых корпорацией Майкрософт. Чтобы включить поддержку модулей стандартной библиотеки, выполните компиляцию с /experimental:module помощью и /std:c++latest . В проекте Visual Studio щелкните правой кнопкой мыши узел проекта в Обозреватель решений и выберите свойства. В раскрывающемся списке Конфигурация выберите Все конфигурации, а затем выберите Свойства> конфигурацииC/C++>Язык>Включить модули C++ (экспериментальные).

Модуль и код, который его использует, должны быть скомпилированы с теми же параметрами компилятора.

Использование стандартной библиотеки C++ в качестве модулей (экспериментальная)

В этом разделе описывается экспериментальная реализация, которая по-прежнему поддерживается. Новый стандартизированный способ использования стандартной библиотеки C++ в качестве модулей описан в разделе Импорт стандартной библиотеки C++ с помощью модулей.

Импорт стандартной библиотеки C++ в виде модулей вместо ее включения в файлы заголовков позволяет ускорить компиляцию в зависимости от размера проекта. Экспериментальная библиотека разделена на следующие именованные модули:

  • std.regex предоставляет содержимое заголовка
  • std.filesystem предоставляет содержимое заголовка
  • std.memory предоставляет содержимое заголовка
  • std.threading предоставляет содержимое заголовков , , , , и
  • std.core предоставляет все остальное в стандартной библиотеке C++
Читайте также:
Программы похожие на Яндекс

Чтобы использовать эти модули, добавьте объявление импорта в начало файла исходного кода. Пример:

import std.core; import std.regex;

Чтобы использовать модули стандартной библиотеки Майкрософт, скомпилируйте программу с /EHsc параметрами и /MD .

Простой пример

В следующем примере показано простое определение модуля в исходном файле с именем Example.ixx . Расширение .ixx требуется для файлов интерфейса модуля в Visual Studio. В этом примере файл интерфейса содержит как определение функции, так и объявление . Однако определения можно также поместить в один или несколько отдельных файлов реализации модуля, как показано в следующем примере. Оператор export module Example; указывает, что этот файл является основным интерфейсом для модуля с именем Example . Модификатор export в f() указывает, что эта функция видна при Example импорте другой программой или модулем. Модуль ссылается на пространство имен Example_NS .

// Example.ixx export module Example; #define ANSWER 42 namespace Example_NS < int f_internal() < return ANSWER; >export int f() < return f_internal(); >>

Файл MyProgram.cpp использует объявление для import доступа к имени, экспортируемого . Example Здесь отображается имя Example_NS , но не все его члены. Кроме того, макрос ANSWER не отображается.

// MyProgram.cpp import Example; import std.core; using namespace std; int main() < cout

Объявление import может отображаться только в глобальных область.

Грамматика модуля

module-name :
module-name-qualifier-seq необ. identifier

module-name-qualifier-seq :
identifier .
module-name-qualifier-seq identifier .

module-partition :
: module-name

module-declaration :
export Выбрать module module-name module-partition Выбрать attribute-specifier-seq Выбрать ;

module-import-declaration :
export Выбрать import module-name attribute-specifier-seq Выбрать ;
export Выбрать import module-partition attribute-specifier-seq Выбрать ;
export Выбрать import header-name attribute-specifier-seq Выбрать ;

Реализация модулей

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

Для больших модулей можно разделить части модуля на подмодулы, называемые секциями. Каждая секция состоит из файла интерфейса модуля, который экспортирует имя секции модуля. Секция также может иметь один или несколько файлов реализации секции. Модуль в целом имеет один основной интерфейс модуля, открытый интерфейс модуля, который также может импортировать и экспортировать интерфейсы секций.

Модуль состоит из одной или нескольких единиц модуля. Модуль — это блок преобразования (исходный файл), содержащий объявление модуля. Существует несколько типов единиц модуля:

  • Единица интерфейса модуля — это единица модуля, которая экспортирует имя модуля или имя секции модуля. Единица интерфейса модуля содержит export module в объявлении модуля.
  • Единица реализации модуля — это модуль, который не экспортирует имя модуля или имя секции модуля. Как следует из названия, он используется для реализации модуля.
  • Основная единица интерфейса модуля — это единица интерфейса модуля, которая экспортирует имя модуля. В модуле должна быть только одна основная единица интерфейса модуля.
  • Единица интерфейса секции модуля — это единица интерфейса модуля, которая экспортирует имя секции модуля.
  • Единица реализации секции модуля — это единица реализации модуля, которая имеет имя секции модуля в объявлении модуля, но не export ключевое слово.

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

Модули, пространства имен и поиск, зависящий от аргументов

Правила для пространств имен в модулях такие же, как и в любом другом коде. При экспорте объявления в пространстве имен включающее пространство имен (за исключением неэкспортированных членов) также неявно экспортируется. Если пространство имен экспортируется явным образом, экспортируются все объявления в этом определении пространства имен.

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

Секции модулей

Раздел модуля аналогичен модулю, за исключением того, что он совместно владеет всеми объявлениями во всем модуле. Все имена, экспортированные файлами интерфейса секционирования, импортируются и повторно экспортируются основным файлом интерфейса. Имя секции должно начинаться с имени модуля, за которым следует двоеточие. Объявления в любой из секций отображаются во всем модуле.

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

Читайте также:
Имя файлу дает операционная система процессор программа

module Example:part1;

Файл интерфейса секции начинается следующим образом:

export module Example:part1;

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

module Example:part2; import :part1;

Основной блок интерфейса должен импортировать и повторно экспортировать все файлы разделов интерфейса модуля следующим образом:

export import :part1; export import :part2; .

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

Модули и файлы заголовков

Вы можете включить файлы заголовков в исходный файл модуля, поместив директиву #include перед объявлением модуля. Эти файлы считаются фрагментом глобального модуля. Модуль может видеть только имена в фрагменте глобального модуля, которые находятся в заголовках, которые он явно включает. Фрагмент глобального модуля содержит только используемые символы.

// MyModuleA.cpp #include «customlib.h» #include «anotherlib.h» import std.core; import MyModuleB; //. rest of file

Для управления импортируемыми модулями можно использовать традиционный файл заголовков:

// MyProgram.h import std.core; #ifdef DEBUG_LOGGING import std.filesystem; #endif

Импортированные файлы заголовков

Некоторые заголовки достаточно автономны, что их можно использовать с помощью import ключевое слово. Main разница между импортированным заголовком и импортированным модулем заключается в том, что все определения препроцессора в заголовке отображаются в программе импорта сразу после инструкции import .

import ; import «myheader.h»;

Источник: learn.microsoft.com

Модульное программирование

Все рассмотренные параметры подпрограмм позволяли выполнять один и тот же алгоритм с различными данными. В Паскале есть и другая возможность — параметризовать алгоритм функциями и процедурами. Это может пригодиться, если требуется выполнить одну и ту же последовательность действий, внутри которой выполняется обращение к разным функциям или процедурам.

Описание параметра подпрограммы в большинстве случаев состоит из имени и типа. Имя функции является константой процедурного ( функционального ) типа, который требуется описать в разделе type , например:

type fun = function(x : real) : real; pr = procedure; proc = procedure(a, b : word; var c : word);

Здесь вводится описание трех типов. Первый из них соответствует любой функции с одним аргументом вещественного типа, возвращающей вещественное значение, второй — процедуре без параметров, а третий — процедуре с тремя параметрами типа word . Как видно из примеров, описание процедурного (функционального) типа соответствует заголовку подпрограммы без имени. Имя типа используется затем в списке параметров подпрограммы аналогично другим типам.

Пример. Программа, вычисляющая определенные интегралы методом прямоугольников для двух функций

q=frac<2x></p><p>>qquadgamma=cos:x-0,2x

на интервале [a, b] с заданным количеством его разбиений ( пример 4.5).

program integrals; type fun = function(x : real) : real; < 1 >var a, b : real; n : integer; function Q(x : real) : real; begin Q := 2 * x / sqrt(1 – sin(2 * x)); end; function R(x : real) : real; begin R := cos(x) – 0.2 * x; end; function integr(f : fun; a, b : real; n : integer) : real; var sum, x, h : real; i : integer; begin h := (b – a) / n; sum := 0; x := a; for i := 1 to n do begin sum := sum + f(x); x := x + h; end; integr := sum * h; end; begin writeLn(‘Введите интервал и количество шагов’); readln(a, b, n); writeln(‘Интеграл для первой функции: ‘, integr(Q, a, b, n):8:3); writeln(‘ Интеграл для второй функции: ‘, integr(R, a, b, n):8:3); end.
Листинг 4.5. Вычисление определенного интеграла методом прямоугольников

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

Итак, чтобы передать имя функции или процедуры в подпрограмму, необходимо:

  1. Определить соответствующий процедурный тип.
  2. Задать для функций и процедур, предназначенных для передачи в подпрограмму, ключ компилятора , определяющий дальнюю адресацию. При этом компилятор формирует полный адрес, состоящий из сегмента и смещения. Альтернативный способ — указать в заголовке каждой функции директиву far :

function Q(x : real) : real; far;

Рекурсивные подпрограммы

Рекурсивной называется подпрограмма, в которой содержится обращение к самой себе. Такая рекурсия называется прямой. Есть также косвенная рекурсия, когда две или более подпрограмм вызывают друг друга.

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

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

Читайте также:
Mass effect прекращена работа программы при запуске

Простой пример рекурсивной функции — вычисление факториала (это не означает, что факториал следует вычислять именно так). Чтобы получить факториал числа n, требуется умножить на n факториал ( n – 1)!. Известно также, что 0! = 1 и 1! = 1.

function fact(n : byte) : longint; begin if (n = 0) or (n = 1) then fact := 1 else fact := n * fact(n – 1); end;

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

Достоинством рекурсии является компактная запись. К недостаткам относятся расход времени и памяти на повторные вызовы функции и передачу ей параметров, а главное, опасность переполнения стека.

Модули

Модуль — это подключаемая к программе библиотека ресурсов. Он может содержать описания типов, констант, переменных и подпрограмм. В модуль обычно объединяют связанные между собой ресурсы: например, в составе оболочки есть модуль Graph для работы с экраном в графическом режиме. Модули применяются как библиотеки, которые могут использоваться различными программами, и для разбиения сложной программы на составные части.

Чтобы использовать модуль , достаточно знать только его интерфейс: детали реализации модуля скрыты от его пользователя. Это позволяет успешно создавать программы большого объема, поскольку мозг человека может хранить одновременно довольно ограниченный объем информации. Кроме того, использование модулей позволяет преодолеть ограничение в один сегмент на объем кода исполняемой программы, поскольку код каждого подключаемого к программе модуля содержится в отдельном сегменте.

Модули можно разделить на стандартные, которые входят в состав системы программирования, и пользовательские, то есть создаваемые программистом. Чтобы подключить модуль к программе, его требуется предварительно скомпилировать. Результат компиляции каждого модуля хранится на диске в отдельном файле с расширением .tpu.

Описание модулей

Исходный текст каждого модуля хранится в отдельном файле с расширением .pas. Модуль состоит из секций (разделов). Общая структура модуля:

unit имя; < заголовок модуля >interface < ————- интерфейсная секция модуля > < описание глобальных элементов модуля (видимых извне) >implementation < ————— секция реализации модуля > < описание локальных (внутренних) элементов модуля >begin < ——————- секция инициализации > < может отсутствовать >end.

ВНИМАНИЕ Имя файла, в котором хранится модуль, должно совпадать с именем, заданным после ключевого слова unit .

Модуль может использовать другие модули, для этого их надо перечислить в операторе uses , который может находиться только непосредственно после ключевых слов interface или implementation . Если модули подключаются к интерфейсной части, все константы и типы данных, описанные в интерфейсной секции этих модулей, могут использоваться в любом описании в интерфейсной части данного модуля. Если модули подключаются к части реализации, все описания из этих модулей могут использоваться только в секции реализации.

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

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

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

В оболочках Borland Pascal и Turbo Pascal результат компиляции по умолчанию размещается в оперативной памяти и на диск не записывается. Поэтому для сохранения скомпилированного модуля на диске требуется установить значение пункта Compile ( Destination в значение Disk. Компилятор создаст файл с расширением .tpu, который надо переместить в специальный каталог, путь к которому указан в пункте меню Options ( Directories в поле Unit Directories.

В качестве примера оформим в виде модуля подпрограмму вычисления среднего арифметического значения элементов массива из пример 4.1 ( пример 4.6).

unit Average; interface const n = 10; type mas = array[1 .. n] of real; procedure average(x : mas; var av : real); implementation procedure average(x : mas; var av : real); var i : integer; begin av := 0; for i := 1 to n do av := av + x[i]; av := av / n; end; end.
Листинг 4.6. Пример оформления модуля

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

Источник: intuit.ru

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru