Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Введение. для студентов специальностей




В. С. Романчик, А. Е. Люлькин

Минск

Учебное пособие

ПРОГРАММИРОВАНИЕ В С++ BUILDER

 

по курсу «МЕТОДЫ ПРОГРАММИРОВАНИЯ»

для студентов специальностей

G31 03 01 «Математика», G31 03 03 «Механика»

 

 

 

УДК 004.43(075.8)

ББК 32.973.26-018.1я73

Б69

А в т о р ы:

Р е ц е н з е н т ы:

старший преподаватель Н. А. Аленский,

кандидат физико-математических наук, доцент, зав. кафедрой информационных технологий БГУК П. В. Гляков

кандидат физико-математических наук, доцент С. В. Суздаль

 

 

Рекомендовано Ученым советом

механико-математического факультета БГУ

2006 года, протокол № ___

 

Программирование в C++ BUILDER: учебное пособие для студ. механико-матем. фак. / В. С. Романчик, А.Е.Люлькин. Мн.: БГУ, 2007. –126 с. ISBN 985-485-498-1.   В пособии рассматриваются вопросы, относящиеся к использованию технологии объектно-ориентированного программирования в системе C++ Builder. Описание методологии построения классов и использования компонентов сопровождается многочисленными примерами. Предназначено для студентов 2-го курса механико-математического факультета, изучающих курс «Методы программирования».

 

УДК 004.43(075.8)

ББК 32.973.26-018.1я73

 

©Романчик В.С.,

Люлькин А.Е.

ISBN 985-485-498-1 БГУ, 2007

 

 

Основные характеристики С++Builder. C++Builder включает язык C++, компилятор, интегрированную среду разработки приложений IDE (Integrated Development Environment), отладчик и различные инструменты. C++Builder содержит комплект общих элементов управления, доступ к Windows API, библиотеку ви­зуальных компонентов VCL (Visual Component Library), компоненты и инструменты для работы с базами данных.

C++Builder добавляет к процессу программирования на языке C++ возможность быстрой визуальной разработки интерфейса приложений. Кроме библиотек OWL (Object Windows Library) и MFC (Microsoft Foundation Classes), он использует библиотеку VCL и позволяет включить в форму диалоги с пользователем, оставляя разработчику для реализации только функциональную часть, воплощающую алгоритм решения задачи.

C++Builder имеет общую с Delphi библиотеку классов, часть из которых осталась написанной на языке Object Pascal. Благодаря этому, а также включению в С++Builder компиляторов С++ и Object Pascal, в приложениях можно использовать компоненты и код, написанные на Object Pascal, а также формы и модули Delphi.

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

Компоненты разделяются на видимые (визуальные) и невидимые (невизуальные). Визуальные компоненты появляются как во время выполнения, так и во время проектирования. Невизуальные компоненты появляются во время проектирования как пиктограммы на форме. Они не видны во время выполнения, но обладают функциональностью. Для добавления компонента в форму можно выбрать мышью нужный компонент в Палитре компонентов и щелкнуть левой клавишей мыши в нужном месте проектируемой формы. Компонент появится на форме, и далее его можно перемещать и изменять. Каждый компонент C++ Builder имеет три характеристики: свойства, события и методы. Инспектор объектов автоматически показывает свойства и события, которые могут быть использованы с компонентом. Свойства являются атрибутами компонента, определяющими его внешний вид и поведение. Инспектор объектов отображает опубликованные (published) свойства компонентов на странице свойств (properties) и используется для установки published-свойств во время проектирования. Для изменения свойств компонента во время выполнения приложения нужно добавить соответствующий код. Помимо published-свойств, компоненты могут иметь открытые (public) свойства, которые доступны только во время выполнения приложения.

 

 

Рис. 1. Окно Инспектора объектов

События. Страница событий (Events) Инспектора объектов показывает список событий, распознаваемых компонентом и возникающих при изменении состояния компонента. Каждый экземпляр компонента имеет свой собственный набор функций - обработчиков событий. Создавая обработчик события, вы поручаете программе выполнить указанную функцию, если это событие произойдет. Чтобы добавить обработчик события, нужно выбрать компонент, затем открыть страницу событий Инспектора объектов и дважды щелкнуть левой клавишей мыши рядом с событием. Это заставит C++ Builder сгенерировать текст пустой функции с курсором в том месте, где следует вводить код. Далее нужно ввести код, который должен выполняться при наступлении данного события.

Среда разработки (IDE). C++ Builder представляет собой приложение, главное окно которого содержит меню (сверху), инструментальную панель (слева) и Палитру компонентов (справа). Помимо этого при запуске C++ Builder появляются окно Инспектора объектов и окно Object TreeView (слева), а также форма нового приложения (справа). Под окном формы приложения находится окно Редактора кода.

 

 

Рис. 2. Главное окно интегрированной среды разработки

Создание приложений в С++Builder. Первым шагом в разработке приложения C++ Builder является создание проекта. Чтобы создать новый проект, нужно выбрать пункт меню File|New| Application.

C++ Builder создает файл Project.bpr, а также головной файл проекта Project.cpp, содержащий функцию WinMain(). Функция WinMain() в Windows-приложениях используется вместо функции main(). При добавление новой формы C++ Builder обновляет файл проекта и создает следующие дополнительные файлы:

· файл формы с расширением.dfm, содержащий информацию о форме;

· файл модуля с расширением.cpp, содержащий код на C++;

· заголовочный файл с расширением.h, содержащий описание класса формы.

 
 

Для того чтобы откомпилировать текущий проект, нужно выбрать пункт меню Compile. Для того чтобы откомпилировать проект и создать исполняемый файл, из меню Run нужно выбрать пункт Run. В результате выполнения будет получена следующая форма:

Рис. 3. Результат выполнения приложения

 

Структура файла проекта. Для каждого приложения C++Builder создается xml-файл проекта Project.bpr и файл ресурсов. Еще один файл - головной файл проекта, содержащий функцию WinMain(), генерируется при выборе пункта меню File|New Application. Первоначально по умолчанию этому файлу присваивается имя Project1.cpp. Если в процессе разработки приложения добавляются формы и модули, C++Builder обновляет файл. Для просмотра файла следует выбрать пункт меню Project|View Source.

В головном файле проекта имеется определенный набор ключевых элементов:

· Директива препроцессора #include <vcl.h> предназначена для включения заголовочного файла, ссылающегося на описания классов библиотеки VCL.

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

· Директива USEFORM показывает модули и формы используемые в проекте.

· Директива USERES компилятора присоединяет файлы ресурсов к выполняемому файлу. При создании проекта автоматически создается файл ресурсов.res для хранения курсоров, пиктограмм и других ресурсов.

· Application->Initialize(). Это утверждение инициализирует приложение.

· Application->CreateForm(). Это утверждение создает форму приложения. Каждая форма в приложении имеет свое утверждение CreateForm.

· Application->Run(). Это утверждение запускает приложение.

· Блок try...catch используется для корректного завершения приложения в случае возникновения ошибки.

Типичный головной файл проекта имеет следующий вид:

 

//Project1.cpp --------------------------------------------------------

#include <vcl.h>

#pragma hdrstop

USERES("Project1.res");

USEFORM("Unit1.cpp", Form1);

//---------------------------------------------------------------------------

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)

{

try

{

Application->Initialize();

Application->CreateForm(__classid(TForm1), &Form1);

Application->Run();

}

catch (Exception &exception)

{ Application->ShowException(&exception); }

return 0;

}

 

Структура файла Project1.bpr. Файл Project1.bpr представляет XML-проект (C++Builder XML Project), со­держащий описание создаваемого приложения. Это текстовый файл, содержащий указания на то, какие файлы должны компилироваться и компоноваться в проект, а также пути к используемым каталогам.

Структура модуля. Модуль содержит реализацию функциональной части объекта на языке C++ и по умолчанию представляет собой файл Unit1.cpp. Каждый такой файл компилируется в объектный файл с расширением.obj. При добавлении к проекту новой формы генерируется новый модуль.

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

Ниже приводится текст модуля, генерируемый для исходной формы:

 

//Unit1.cpp ------------------------------------------------------------

#include <vcl.h>

#pragma hdrstop

#include "Unit1.h"

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm1 *Form1;//указатель на объект

//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner): TForm(Owner)

{ } //реализация конструктора

 

Структура заголовочного файла. Заголовочный файл (файл с расширением.h, по умолчанию Unit1.h) генерируется при создании нового модуля и содержит описание класса формы. Такие описания генерируются автоматически и изменяются при внесении в форму новых компонентов или генерации новых обработчиков событий. В заголовочном файле содержится интерфейс, а в самом модуле – реализация методов.

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

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

Ниже приводится заголовочный файл для исходной формы:

 

//Unit1.h---------------------------------------------------------------------------

#ifndef Unit1H

#define Unit1H

//---------------------------------------------------------------------------

#include <Classes.hpp>

#include <Controls.hpp>

#include <StdCtrls.hpp>

#include <Forms.hpp>

class TForm1: public TForm

{

__published: // IDE-managed Components

private: // User declarations

public: // User declarations

__fastcall TForm1(TComponent* Owner);

};

//---------------------------------------------------------------------------

extern PACKAGE TForm1 *Form1;

#endif

//---------------------------------------------------------------------------

Файл формы. Форма является одним из важнейших элементов приложения C++ Builder. Процесс редактирования формы происходит при добавлении к форме компонентов, изменении их свойств, создании обработчиков событий. Когда к проекту добавляется новая форма, создаются три отдельных файла: 1) файл модуля (*.cpp) содержит код методов, связанных с формой; 2) заголовочный файл (*.h) содержит описание класса формы; 3) файл формы (*.dfm) содержит сведения об опубликованных (доступных в Инспекторе объектов) свойствах компонентов, содержащихся в форме.

При добавлении компонента к форме заголо­вочный файл и файл формы модифицируются. При редактирова­нии свойств компонента в Инспекторе объектов эти изменения сохраняются в файле формы.

Хотя в C++ Builder файл *.dfm сохраняется в двоичном формате, его содержание можно просмотреть с помощью редактора кода. Для этого нужно нажать правую клавишу мыши над формой и из контекстного меню формы выбрать пункт View as Text.

Ниже приводится листинг файла некоторой формы:

 

//Unit1.dfm---------------------------------------------------------------------------

object Form1: TForm1

Left = 197

Top = 358

Width = 544

Height = 181

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

 

Простейшее приложение. Важнейшей особенностью C++Builder является автоматическая генерация кода программы. Когда к форме добавляете компонент, в тексте файла Unit1.h появляется объявление объекта класса данного компонента. Например, перенос на пустую форму компонента кнопки TButton сгенерирует объявление объекта Button1, а определение события OnClick – объявление метода ButtonlClick, являющегося обработчиком этого события.

Рассмотрим простейшее приложение. Создается форма для сложе­ния двух чисел. Используются компоненты: TEdit – для ввода чисел и отображения результата; TLa­bel – для вывода строк “+” и “=”; TButton – кнопка, связанная с событием OnClick, для сложения чисел.

Будем использовать следующие свойства и методы для компонен­тов:

TEdit: Name (имя объекта), ReadOnly (режим "только чтение"), Text (тексто­вое поле);

TLabel: Caption (текстовое поле);

TButton: Caption (надпись на кнопке), OnClick (событие типа на­жатия кнопки).

На рис. 4 приводятся окна Инспектора объектов в процессе ра­боты со свойствами компонентов.

Двойной щелчок по компоненту Button1 приведет к выводу окна редактиро­вания для Unit1.cpp и предложит определить тело метода Button1Click(), ко­торое для рассматриваемой задачи должно иметь вид:

 

void __fastcall TForm1::Button1Click(TObject *Sender)

{

Edit3->Text=IntToStr(StrToInt(Edit1->Text)+StrToInt(Edit2->Text));

}

 

       
   

 

Рис. 4. Работа с компонентами Edit1 и Button1

Для преобразования строки в целое число и обратно используются функции StrToInt() и IntToStr(), соответственно. На рис. 5 показан ре­зультат выполнения приложения.

 

 

 
 

Рис. 5. Форма в процессе выполнения приложения

 

Рассмотрим основные инструменты визуальной разработки приложений.

Администратор проектов. Предназначен для манипуляций с текущим проектным файлом с расширением.срр. Чтобы открыть окно администратора, выполните команду View|Project|Manager.

Редактор форм. Форма представляет объект, отображаемый в виде окна с управляющими компонентами. C++Builder создает форму в окне Редактора при добавлении формы к проекту или берет ее из Хранилища объектов.

Инспектор объектов. Инспектор объектов используется при проектировании объектов и методов и имеет две вкладки: Свойства (Properties) и События (Events).

Просмотрщик объектов Object TreeView позволяет просматривать дерево объектов.

Хранилище объектов. Обеспечивает возможность разделения (sharing) или повторного использования (reuse) содержащихся в нем объектов. В качестве объектов хранения могут выступать созданные пользователем формы, проекты, модули данных.

Редактор кода. Предоставляет средство для просмотра и редактирования текста программного модуля (Unit).

Палитра компонентов. C++Builder поставляется вместе с Биб­лиотекой Визуальных Компонентов VCL (Visual Component Library), содержащей множество повторно используемых компо­нентов. C++Builder позволяет не только пользоваться готовыми компонентами, но и создавать новые компоненты.

Формы и диалоговые окна. Главная форма (Form1) открывается при открытии приложения. Метод Close() закрывает форму и прекращает выполнение приложения. Свойства формы могут устанавливаться как на этапе проектирования, так и на этапе выполнения приложения. Форма используется в качестве контейнера для размещения других компонентов. В табл. 1 приведены некоторые свойства формы.

С формой связаны события: OnActivate – вызывается при активи­зации формы после получения фокуса ввода; OnCreate –вызывается при создании формы; OnClose – вызывается при закрытии формы; OnClick – вызывается при щелчке кнопки; OnKeyDown, OnKePress –первое событие активизируется при нажатии любой клавиши, в том числе функциональной, для второго события клавиша не должна быть функциональной; OnMouseDown, OnMouseMove и другие – связаны с мышью. При возникновении каждого события вызывается соответ­ст­вующй метод-обработчик события. Например:

void __fastcall TForm1::FormClick(TObject *Sender){ }

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

Форма создается при создании приложения. Приложение может содержать несколько форм. Существует два вида оконных приложений: SDI и MDI. SDI-приложения могут отображать несколько окон, не привязанных к главному. Каждая форма может отображаться в мо­дальном режиме и требовать за­крытия при пе­реходе к другой форме (Form2->ShowModal(), Form2->Close()). Пока модальное окно не закрыто, нельзя перейти к другому окну. В немодальном режиме раз­решается дос­туп к нескольким формам. В качестве примера рассмот­рим при­ложе­ние, состоящее из двух немодальных SDI форм: Form1 и Form3. Создадим кнопку и за­пишем код обработчика события

void __fastcall TForm1::Button1Click(TObject *Sender)

{

Form3->Show();

}

При этом необходимо включить в заголовочный файл Unit1.h первой формы заголовочный файл второй формы: #include "Unit3.h"

На рис. 6 показан результат выполнения приложения.

Рассмотрим еще одно приложение состоящее из двух форм: Form1 и AboutBox. Для этого в меню выберем File|New|Forms|AboutBox. В свойствах формы AboutBox выберем: Visible=true и FormStyle=fsStayOnTop.

 

Таблица 1

ActiveControl Присваивается значение обекта, на который устанавливается фокус ввода при загрузке формы
Cursor Определяет форму указателя мыши
BorderStyle Вид рамки объекта. Принимает значения: bsNone (нет рамки); bsSingle (простая рамка); bsSizeable (рамка, позволяющая изменять размеры объекта мышью); bsDialog (рамка в стиле диалоговых окон); bsToolWindow (как bsSingle, но с небольшим заголовком); bsSizeToolWin (как bsSizeable, но с небольшим заголовком)
Caption Заголовок. Для одних объектов применяется, чтобы задать заголовок в окне или надпись на кнопке, для других – описывает их содержимое (например, у полей надписи)
Constraints Содержит четыре подсвойства, определяющие минимальный и максимальный допустимый размер объекта
Default Определяет, будет ли происходить для данного объекта событие OnClick, когда пользователь нажмет клавишу Enter (для этого свойство Default должно иметь значение true)
DragKind Определяет, можно ли объект произвольно перетаскивать по окну (dkDrag) или же его можно перемещать как стыкуемый объект (dkDock), который сам определяет свою форму при стыковке с другими объектами
Enabled Определяет доступность объекта. Когда свойство Enabled имеет значение false, объект становится недоступным для пользователя
Font Определяет шрифт, которым будут делаться все надписи внутри объекта. Содержит множество подсвойств
Height Высота объекта
Hint Текст подсказки, которая всплывает при наведении указателя мыши на объект. Эта подсказка будет показываться, если свойство ShowHint установлено в true
Name Имя объекта
PopupMenu Контекстное меню, связанное с объектом и вызываемое при щелчке правой кнопки мыши над этим объектом. Выбирается в раскрывающемся списке доступных меню
Scaled Если имеет значение true, то учитывается свойство PixelsPerlnch
ShowHint Определяет, надо ли показывать всплывающую подсказку, хранящуюся в свойстве Hint
Top Верхняя координата объекта на компоненте-родителе
Visible Определяет, будет ли видим объект во время работы программы (по умолчанию – false)
Width Ширина объекта

 


Рис. 6. Результат вывода формы в немодальном режиме

 

В результате получим следующий головной файл проекта:

USERES("Project2.res");

USEFORM("Unit1.cpp", Form1);

USEFORM("Unit2.cpp", AboutBox);

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int){

try

{

Application->Initialize();

Application->CreateForm(__classid(TForm1), &Form1);

Application->CreateForm(__classid(TAboutBox), &AboutBox);

Application->Run();

}

catch (Exception &exception)

{

Application->ShowException(&exception);

}

return 0;

}

Закроем форму AboutBox по нажатию кнопки OK. Для этого запишем следующий обработчик события для кнопки:

void __fastcall TAboutBox::OKButtonClick(TObject *Sender)

{

Close();

}

На рис. 7 показан результат выполнения приложения.


 

 

Рис. 7. Приложение с двумя формами

 

Для создания MDI приложения надо поменять свойство формы FormStyle с fsNormal на fsMDIForm. После этого новая подчиненная форма создается вместе с изменением свойства FormStyle на fsMDIChild. При попытке закрытия подчиненная форма сворачивается. Чтобы закрыть подчиненную форму, можно в обработчике события FormClose набрать: Action=caFree;.

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

void __fastcall TForm1::FormClick(TObject *Sender)

{

ShowMessage("Вывод в окно ShowMessage");

}

Это окно открывается модально.

Второе окно, используемое как для вывода, так и для ввода, вызывается функцией InputBox():

void __fastcall TForm1::FormKeyDown(TObject *Sender,

WORD &Key, TShiftState Shift)

{

String Name=InputBox("InputBox","What is your name","");

}

Результаты выполнения этих функций приведены на рис. 8.

 

 

Рис. 8. Примеры диалоговых окон

 

Окна для ввода и вывода можно также вызывать с помощью методов InputQuery("str1","str2", inputstr) и MessageDlg(str, mtInformation, TMsgDlgButtons() << mbOK, 0). Рассмотрим пример:

 

void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y)

{ String Name;

InputQuery("InputQuery","Prompt",Name);

MessageDlg("MessageDlg:"+Name, mtInformation, TMsgDlgButtons() << mbOK, 0);

}

 

Результаты выполнения функции приведены на рис. 9.

 

 

Рис. 9. Результаты вывода диалоговых окон

 

Вопросы

1. Из каких файлов состоит приложение C++Builder и как организованы эти файлы?

2. Какие коды автоматически генерируются в головном файле приложения при создании этого приложения?

3. В чем отличие действия команд Run, Make и Build при работе с проектом?

4. Каково назначение окон Инспектора объектов?

5. Для чего используется окно Редактора кода?

6. Что содержит файл представления формы (.dfm)?

7. Что такое событие и как создать обработчик события для компоненты?

8. Какие существуют отличия модальной формы, SDI и MDI форм?

9. Что находится в разделах __published, private и public класса в заголовочном файле формы Unit.h?

10. Что произойдет в результате выполнения кода:

{Form1->Button1Click(Form1);}

11. Что произойдет в результате выполнения кода:

Form1->WindowState = wsMaximized;

Form1->WindowState = wsMinimized;

Form1->WindowState = wsNormal;

 

Упражнения

1. Создать приложение, состоящее из модальной и SDI форм. Создать кнопки для закрытия этих форм. Изменить свойства форм.

2. Создать приложение, состоящее из формы AboutBox и двух MDI форм. Создать кнопки для закрытия этих форм. Изменить свойства форм.

3. Создать форму и написать несколько обработчиков событий, связанных с созданием и изменением свойств формы.

4. Из окна редактирования (Edit) ввести символьную строку и преобразовать в целое и вещественное числа. При преобразовании в число предусмотреть обработку исключительной ситуации

5. Разработать калькулятор, реализующий арифметические операции и операции со стандартными функциями.

6. Разработать калькулятор для перевода чисел в двоичную, восьмеричную и шестнадцатеричную системы счисления и реализовать основные операции.

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

 

 




Поделиться с друзьями:


Дата добавления: 2014-12-27; Просмотров: 1632; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.017 сек.