Приступая к разработке каждой программы, следует иметь ввиду, что она, как правило, является большой системой, поэтому необходимо принять меры для ее упрощения. Для этого такую программу разрабатывают по частям, которые называются программными модулями. А сам такой метод разработки программ называют модульным программированием.
Программный модуль — это любой фрагмент описания процесса, оформляемый как самостоятельный программный продукт, пригодный для использования в описаниях процесса. Это означает, что каждый программный модуль программируется, компилируется и отлаживается отдельно от других модулей программы, и тем самым, физически разделен с другими модулями программы.
Основные характеристики программного модуля.
-Размер модуля измеряется числом содержащихся в нем операторов (строк). Обычно рекомендуются программные модули размером от нескольких десятков до нескольких сотен операторов.
-Прочность модуля — это мера его внутренних связей. Чем выше прочность модуля, тем больше связей он может спрятать от внешней по отношению к нему части программы и, следовательно, тем больший вклад в упрощение программы он может внести.
Уроки Embird: Модули программы
-Сцепление модуля — это мера его зависимости по данным от других модулей. Характеризуется способом передачи данных. Чем слабее сцепление модуля с другими модулями, тем сильнее его независимость от других модулей.
-Рутинность модуля — это его независимость от предыстории обращений к нему. Модуль называется рутинным, если результат обращения к нему зависит только от значений его параметров (и не зависит от предыстории обращений к нему). Модуль называется зависящим от предыстории, если результат обращения к нему зависит от внутреннего состояния этого модуля, хранящего следы предыдущих обращений к нему.
Среди множества модулей различают:
— головной модуль — управляет запуском программного продукта (существует в единственном числе);
— управляющий модуль — обеспечивает вызов других модулей на обработку;
— рабочие модули — выполняют функции обработки;
— сервисные модули и библиотеки, утилиты — осуществляют обслуживающие функции.
Структурный подход к разработке программ: понятие, основные принципы. Примеры процессно-ориентированных языков программирования.
Структурное программирование — методология разработки программного обеспечения, в основе которой лежит представление программы в виде иерархической структуры блоков. Задача разбивается на большое число мелких подзадач, каждая из которых решается своей процедурой или функцией (декомпозиция задачи).
Структурное проектирование подразделяют на:
а) нисходящее (проектирование прог-мы происходит от общего к частному со всё большей детализацией на каж. этапе). Определяется задача в целом, в виде последовательности этапов, реализующих самостоятельные смысловые части алгоритма. Каж. этап детализируется, процесс детализации продолжается до тех пор, пока части алгоритма не станут простыми и легко реализуемыми. Результатом процесса детализации может быть структура прог-мы, описанная при помощи ориентированного графа, определяющего взаимосвязи подпрограмм. Каж. модуль представляется в виде детальнго описания его ф-ций, например в виде блок-схемы алгоритма.
Python 3. Архитектура программ. Работа с пакетами(модулями)
б) восходящее (сначала разрабатываются модули нисшего уровня, а затем они объединяются в модули более высокого уровня).
На практике обычно используют смешанный метод. Структурное проектирование реализует процессно-ориентированную модел разработки прог-м. В этой модели прог-ма представляется как ряд последовательно выполняемых операций (процедур). Такие прог-мы м/рассматривать как код, воздействующий на данные. Языки прог-ния, в которых реализован процессно-ориентированный подход назыв. процедурными: C, Pascal, Quick Basic.
Объектно-ориентированный подход к разработке программ: понятие, основные концепции. Примеры объектно-ориентированных языков программир-я.
Объектно-ориентированный подход к программированию -это подход к разработке программного обеспечения, основанный на объектах, а не на процедурах.
Примеры: Java, Си, Visual Basic
При процедурном программировании программа разбивается на части в соответствии с алгоритмом: каждая часть (подпрограмма,функция,процедура) является составной частью алгоритма. При объектно-ориентированном программировании программа строится как совокупность взаимодействующих объектов.
Объект – это базовое понятие ООП. Объекты, имеющие общие св-ва и поведение объединяются в классы. Таким образом, класс можно определить как некую общность конкретных объектов, как описание объекта – каким он должен быть и что должен делать. Класс должен каким-либо образом взаимодействовать с др.классами или программными элементами приложения.
Для получения и передачи данных в классе применяются свойства. Свойства представляют собой атрибуты, кот.составляют индивидуальность объекта и помогают описать его. Методы класса – это выполняемые классом функциональные обязанности, задаваемые при его проектировании.
К концепции ООП относится:
Полиморфизм – это взаимозаменяемость объектов с одинаковым интерфейсом. В зависимости от типа объекта одно и то же сообщение может соответствовать различным действиям – методам для достижения требуемого результата.
Наследование -возможность порождать один класс от другого с сохранением всех свойств и методов класса-предка и добавляя, при необходимости, новые свойства и методы. Наследование призвано отобразить такое свойство реального мира, как иерархичность.
Инкапсуляция — это принцип, согласно которому любой класс должен рассматриваться как чёрный ящик — пользователь класса должен видеть и использовать только интерфейс класса и не вникать в его внутреннюю реализацию. Смысл инкапсуляции состоит в том, что внешний пользователь не знает детали реализации объекта, работая с ним путём предоставленного объектом интерфейса.
Источник: cyberpedia.su
Overview of modules in C++
C++20 introduces modules, a modern solution that turns C++ libraries and programs into components. A module is a set of source code files that are compiled independently of the source files (or more precisely, the translation units that import them. Modules eliminate or reduce many of the problems associated with the use of header files. They often reduce compilation times. Macros, preprocessor directives, and non-exported names declared in a module aren’t visible outside the module. They have no effect on the compilation of the translation unit that imports the module.
You can import modules in any order without concern for macro redefinitions. Declarations in the importing translation unit don’t participate in overload resolution or name lookup in the imported module. After a module is compiled once, the results are stored in a binary file that describes all the exported types, functions, and templates. The compiler can process that file much faster than a header file. And, the compiler can reuse it every place where the module is imported in a project.
You can use modules side by side with header files. A C++ source file can import modules and also #include header files. In some cases, you can import a header file as a module, which is faster than using #include to process it with the preprocessor. We recommend that you use modules in new projects rather than header files as much as possible. For larger existing projects under active development, experiment with converting legacy headers to modules.
Base your adoption on whether you get a meaningful reduction in compilation times.
To contrast modules with other ways to import the standard library, see Compare header units, modules, and precompiled headers.
Enable modules in the Microsoft C++ compiler
As of Visual Studio 2022 version 17.1, C++20 standard modules are fully implemented in the Microsoft C++ compiler.
Before it was specified by the C++20 standard, Microsoft had experimental support for modules. The compiler also supported importing pre-built Standard Library modules, described below.
Starting with Visual Studio 2022 version 17.5, importing the Standard Library as a module is both standardized and fully implemented in the Microsoft C++ compiler. This section describes the older, experimental method, which is still supported. For information about the new standardized way to import the Standard Library using modules, see Import the C++ standard library using modules.
You can use the modules feature to create single-partition modules and to import the Standard Library modules provided by Microsoft. To enable support for Standard Library modules, compile with /experimental:module and /std:c++latest . In a Visual Studio project, right-click the project node in Solution Explorer and choose Properties. Set the Configuration drop-down to All Configurations, then choose Configuration Properties > C/C++ > Language > Enable C++ Modules (experimental).
A module and the code that consumes it must be compiled with the same compiler options.
Consume C++ Standard Library as modules (experimental)
This section describes the experimental implementation, which is still supported. The new standardized way of consuming the C++ Standard Library as modules is described in Import the C++ standard library using modules.
By importing the C++ Standard Library as modules rather than including it through header files, you can potentially speed up compilation times depending on the size of your project. The experimental library is split into the following named modules:
- std.regex provides the content of header
- std.filesystem provides the content of header
- std.memory provides the content of header
- std.threading provides the contents of headers , , , , , and
- std.core provides everything else in the C++ Standard Library
To consume these modules, add an import declaration to the top of the source code file. For example:
import std.core; import std.regex;
To consume the Microsoft Standard Library modules, compile your program with /EHsc and /MD options.
Basic example
The following example shows a simple module definition in a source file called Example.ixx . The .ixx extension is required for module interface files in Visual Studio. In this example, the interface file contains both the function definition and the declaration. However, you can also place the definitions in one or more separate module implementation files, as shown in a later example. The export module Example; statement indicates that this file is the primary interface for a module called Example . The export modifier on f() indicates that this function is visible when Example is imported by another program or module. The module references a namespace Example_NS .
// Example.ixx export module Example; #define ANSWER 42 namespace Example_NS < int f_internal() < return ANSWER; >export int f() < return f_internal(); >>
The file MyProgram.cpp uses the import declaration to access the name that is exported by Example . The name Example_NS is visible here, but not all of its members. Also, the macro ANSWER isn’t visible.
// MyProgram.cpp import Example; import std.core; using namespace std; int main() < cout
The import declaration can appear only at global scope.
Module grammar
module-name :
module-name-qualifier-seq opt identifiermodule-name-qualifier-seq :
identifier .
module-name-qualifier-seq identifier .module-partition :
: module-namemodule-declaration :
export opt module module-name module-partition opt attribute-specifier-seq opt ;module-import-declaration :
export opt import module-name attribute-specifier-seq opt ;
export opt import module-partition attribute-specifier-seq opt ;
export opt import header-name attribute-specifier-seq opt ;
Implementing modules
A module interface exports the module name and all the namespaces, types, functions, and so on that make up the public interface of the module. A module implementation defines the things exported by the module. In its simplest form, a module can consist of a single file that combines the module interface and implementation. You can also put the implementations in one or more separate module implementation files, similar to how .h and .cpp files are used.
For larger modules, you can split parts of the module into submodules called partitions. Each partition consists of a module interface file that exports a module partition name. A partition may also have one or more partition implementation files. The module as a whole has one primary module interface, the public interface of the module that may also import and export the partition interfaces.
A module consists of one or more module units. A module unit is a translation unit (a source file) that contains a module declaration. There are several types of module units:
- A module interface unit is a module unit that exports a module name or module partition name. A module interface unit has export module in its module declaration.
- A module implementation unit is a module unit that doesn’t export a module name or module partition name. As the name implies, it’s used to implement a module.
- A primary module interface unit is a module interface unit that exports the module name. There must be one and only one primary module interface unit in a module.
- A module partition interface unit is a module interface unit that exports a module partition name.
- A module partition implementation unit is a module implementation unit that has a module partition name in its module declaration, but no export keyword.
The export keyword is used in interface files only. An implementation file can import another module, but can’t export any names. Implementation files can have any extension.
Modules, namespaces, and argument-dependent lookup
The rules for namespaces in modules are the same as in any other code. If a declaration within a namespace is exported, the enclosing namespace (excluding non-exported members) is also implicitly exported. If a namespace is explicitly exported, all declarations within that namespace definition are exported.
When it does argument-dependent lookup for overload resolutions in the importing translation unit, the compiler considers functions declared in the same translation unit (including module interfaces) as where the type of the function’s arguments are defined.
Module partitions
A module partition is similar to a module, except it shares ownership of all declarations in the entire module. All names exported by partition interface files are imported and re-exported by the primary interface file. A partition’s name must begin with the module name followed by a colon. Declarations in any of the partitions are visible within the entire module. No special precautions are needed to avoid one-definition-rule (ODR) errors.
You can declare a name (function, class, and so on) in one partition and define it in another. A partition implementation file begins like this:
module Example:part1;
The partition interface file begins like this:
export module Example:part1;
To access declarations in another partition, a partition must import it, but it can only use the partition name, not the module name:
module Example:part2; import :part1;
The primary interface unit must import and re-export all of the module’s interface partition files like this:
export import :part1; export import :part2; .
The primary interface unit can import partition implementation files, but can’t export them. Those files aren’t allowed to export any names. This restriction enables a module to keep implementation details internal to the module.
Modules and header files
You can include header files in a module source file by putting the #include directive before the module declaration. These files are considered to be in the global module fragment. A module can only see the names in the global module fragment that are in headers it explicitly includes. The global module fragment only contains symbols that are used.
// MyModuleA.cpp #include «customlib.h» #include «anotherlib.h» import std.core; import MyModuleB; //. rest of file
You can use a traditional header file to control which modules are imported:
// MyProgram.h import std.core; #ifdef DEBUG_LOGGING import std.filesystem; #endif
Imported header files
Some headers are sufficiently self-contained that they can be brought in using the import keyword. The main difference between an imported header and an imported module is that any preprocessor definitions in the header are visible in the importing program immediately after the import statement.
import ; import «myheader.h»;
Источник: learn.microsoft.com
Структура модуля
Модули — это программные единицы, служащие для размещения фрагментов программ. При помощи содержащихся в них текстов программ и реализуется решаемая пользователем задача.
Начинается модуль словом unit, за которым следует имя модуля. Именно это имя упоминается в списке используемых модулей в инструкции uses главного модуля приложения.
Модуль состоит из следующих разделов:
Раздел интерфейса (начинается словом interface) сообщает компилятору, какая часть модуля является доступной для других модулей программы. В этом разделе перечислены (после слова uses) библиотечные модули, используемые данным модулем. Также здесь находится сформированное Delphi описание формы, которое следует за словом type.
Раздел реализации открывается словом implementation и содержит объявления локальных переменных, процедур и функций, поддерживающих работу формы.
Начинается раздел реализации директивой , указывающей компилятору, что в процессе генерации выполняемого файла надо использовать описание формы. Описание формы находится в файле с расширением dfm, имя которого совпадает с именем модуля. Файл описания формы генерируется средой Delphi на основе внешнего вида формы.
Рис. 2 Окно модуля
За директивой ($R *.DFM> следуют процедуры обработки событий для формы и ее компонентов. Сюда же программист может поместить другие процедуры и функции.
Раздел инициализации позволяет выполнить инициализацию переменных модуля. Инструкции раздела инициализации располагаются после раздела реализации (описания всех процедур и функций) между begin и end. Если раздел инициализации не содержит инструкций (как в приведенном примере), то слово begin не указывается.
Следует отметить, что значительное количество инструкций модуля формирует Delphi. Например, Delphi, анализируя действия программиста по созданию формы, генерирует описание класса формы (после слова type). В приведенном примере инструкции, набранные программистом, выделены фоном. Очевидно, что Delphi выполнила значительную часть работы по составлению текста программы.
Проект представляет собой набор файлов, используя которые компилятор создает исполняемый файл программы (EXE-файл).
Проект включает файлы:
¨ файл описания проекта (DOF-файл);
¨ файл главного модуля (DPR-файл);
¨ файл ресурсов (RES-файл);
¨ файлы описания форм (DFM-файлы);
¨ файлы модулей форм (PAS-файлы);
¨ файл конфигурации (CFG-файл).
Является основным и представляет собой программу: program Project1; < Имяпрограммы > uses Forms, Unit1 in ‘Unit1.pas’ ; begin Application.Initialize; Application.CreateForm(TForm1,Form1); Application.Run; end. Просмотреть и отредактировать код файла в окне Редактора кода можно с помощью команды: Project/ViewSource (Проект/Просмотр источника). | Для приложения с одной формой: совпадает с именем файла и указывается при сохранении файла на диске. Оператор Uses сообщает компилятору, что программа использует модуль с исходным кодом формы Unit1.pas. Имя подключаемого модуля Form1 указано в виде комментария. Кроме того, перечисляются подключаемые модули всех форм проекта. Файл ресурсов имеет имя, совпадающее с именем файла проекта. Можно подключить и другие ресурсы, добавив директивы и указав в них нужные имена. Операторы выполняют инициализацию приложения, создание формы и запуск приложения. При выполнении операций с проектом код файла проекта формируется Delphi автоматически. |
2.2. Файлы формы | Модуль формы и описание формы |
Для каждой формы создаются автоматически файл описания UNIT.DFM и файл модуля UNIT.PAS. Файл описания формы (*.dfm) содержит характеристики формы и ее компонентов (двоичный). При конструировании формы в Файл описания автоматически вносятся соответствующие изменения. Для каждой формы декларируется тип, определяющий эту форму как класс. Он содержится в модуле UNIT1.PAS Чтобы отобразить этот файл на экране необходимо: 1. Закрыть окно Конструктора той формы, для которой нужно отобразить файл описания; 2. Активизировать команду File/Open (Файл/Открыть); 3. В диалоговом окне (ДО) Open (Открыть) в списке типов файлов найти и установить маску *.dfm; 4. ![]() |
Используя Конструктор формы и Инспектор объектов, разработчик сам управляет этим файлом. Пример описания формы с кнопкой Button1. Object Form1:TForm1 Left = 193 Top = 246 Width = 544 Height = 375 Caption = ‘Form1’ Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = ‘MS Sans Serif’ Font.Style = [ ] OldCreateOrder = False PixelsPerInch = 96 TextHeight = 13 end. ![]() |
2.4. Файл ресурсов PROGECT.RES | |
При первом сохранении проекта автоматически создается файл ресурсов с именем, совпадающим с именем файла проекта. Файл содержит следующие ресурсы: — пиктограммы; — растровые изображения; — курсоры. Файл ресурсов первоначально содержит пиктограмму проекта. Его можно изменить, используя графический редактор ImageEditor 3.0. Вызывается редактор командой Tools / ImageEditor (Инструменты/Редактор изображений). ![]() |
Эти компоненты являются ресурсами Windows, поскольку они разработаны в соответствии со стандартами этой системы. На рисунке показано окно редактора, в которое загружен файл и выполняется редактирование пиктограммы приложения. Файл ресурсов имеет иерархическую структуру, в которой ресурсы разбиты на группы, а каждый ресурс имеет уникальное в пределах группы имя. Имя ресурса задается при его создании и в последующем используется в приложении для доступа к этому ресурсу. Программа проекта находится в группе Icon и по умолчанию имеет имя MAINICON. |
2.5. Файл параметры проекта PROGECT.OPT | |
Используется для установки параметров проекта с помощью команды меню Project / Options. Параметры разбиты на группы, каждая из которых располагается в соответствующем окне на своей странице. ![]() |
Этот файл представляет собой текстовой файл, который содержит текущие установки проекта: — настройки компилятора и компоновщика, — имена служебных каталогов, — условные директивы и параметры командной строки, — настройки проекта (какие окна открыты и в каких позициях они расположены), — конфигурацию проекта. Например: Проект может быть откомпилирован с отладочной информацией или без нее. Во время разработки целесообразно постоянно включать в проект отладочную информацию. Для этого необходимо установить опцию DebugInformation на странице Compiler данного диалогового окна (ДО). — файл конфигурации: *.DOF-файл, содержит текущие установки проекта, например, настройки компилятора, имена служебных папок и т.п. DSK –файл с настройками проекта. Он позволяет восстановить внешний вид рабочей среды проекта. |
2.5. Резервные файлы | |
Delphi создает резервные копии файла проекта, а также PAS- и DFM-файлов. Резервные копии: *.~DP файла проекта с расширением DPR. Создается при повторном сохранении проекта. *.~PA модуля проекта с расширением PAS. Создается при повторном сохранении проекта, если в исходном коде модуля были сделаны изменения. *.~DF файла формы. Создается в случае, если DFM-файл был открыт в виде текста, и в нем были сделаны изменения. | Если первый символ в расширении файла – тильда (~), речь идет о зарезервированной копии. *.~BP файла группы проектов с расширением BPG. Этот файл создается при повторном сохранении файла группы проектов. |
3. 0. Компиляция и выполнение проекта
Источник: studopedia.ru