Реферат по предмету "Информатика"


Разработка приложения вычисления определенных интегралов по формуле левых прямоугольников

Министерство образования и науки Республики Беларусь
Белорусский национальный технический университет
Международный институт дистанционного образования
Кафедра программного обеспечения вычислительной техники и автоматизированных систем
КУРСОВАЯ РАБОТА
по дисциплине:
«Конструирование программ и языки программирования»
Разработка приложения вычисления определенных интегралов по формуле левых прямоугольников
Выполнил:
ст. гр. 417313 Я
Принял:
доц. Гурский Н.Н.
Минск 2005
Введение
Delphi– это современный программный продукт, позволяющий создавать широкий спектр приложений. Он объединяет в себе высокопроизводительный компилятор с языка ObjectPascal, являющийся объектно ориентированным расширением структурного языка третьего поколения Pascal, средств наглядного (визуального) создания программ и масштабируемую технологию управления БД. Основное назначение Delphi– служить средством для быстрого создания широкого класса Windows приложений, включая приложения, отвечающие технологии распределенной обработки данных, называемой технологией клиент сервер.
Для разработки Windows приложений Delphiимеет следующие средства:
-высокопроизводительный компилятор
Имеющийся в составе Delphiкомпилятор с языка ObjectPascal, являющийся одним из самых производительным в мире, позволяющий компилировать приложения со скоростью до 120000 строк в минуту. Среда Delphiвключает в себя встроенный компилятор. При необходимости можно воспользоваться и пакетным компилятором DCC.EXE.
-объектно ориентированная модель компонентов
Основным назначением применения в Delphiмодели компонентов является обеспечение возможности многократного использования компонентов и создания новых. Для создания Delphiиспользовались те же компоненты, что входят в состав поставки. Тем не менее, внесенные в объектную модель изменения, в первую очередь, были вызваны необходимостью поддержки технологии визуального программирования. При этом язык остался совместимым с языком Pascal, поддерживаемым компилятором BorlandPascal7.0
-быстрая среда разработки (RAD)
Среда Delphiсодержит полный набор визуальных средств для быстрой разработки приложений, поддерживающих как создание пользовательских интерфейсов, так и обработку корпоративных данных (с использованием соответствующих средств). Использование библиотеки визуальных компонентов (VCL) и визуальных объектов для работы с данными позволяет создавать приложения с минимальными затратами на непосредственное кодирование. При этом компоненты, включенные в состав Delphi, максимально инкапсулируют вызовы функций WindowsAPI, тем самым облегчая процесс создания программ.
-расширяемость
Delphiявляется системой с открытой архитектурой, что позволяет дополнять ее новыми средствами и переносить на различные платформы.
-средства для построения БД
Delphiподдерживает практически все форматы существующих реляционных таблиц. Delphiвключает в себя локальный сервер InterBase, для того, чтобы можно было разрабатывать расширяемые на любые внешние SQL серверы приложения в онлайновом режиме.
Итак, Delphi– это новый продукт, позволяющий создавать широкий спектр приложений для Windows. Среда Delphiвключает в себя полный набор визуальных средств для быстрой разработки приложений, поддерживающих как создание пользовательских интерфейсов, так и таблиц базы данных. Библиотека классов, входящих в Delphi, содержит большое количество классов, инкапсулирующих различные группы функций WindowsAPI. Delphiявляется системой с открытой архитектурой, что позволяет дополнять ее новыми средствами, и переносить на различные платформы.
1. Математическая формулировка задачи
Требуется составить программу вычисления определенного интеграла по формуле левых прямоугольников.
/>
Начальные данные:
/>
Формула левых прямоугольников имеет вид:
/>
Вычислить значение интеграла. Подынтегральную функцию представить в графическом виде, показать геометрическое значение интеграла в виде заштрихованной площади.
2. Описание программы
Программа включает 4 формы:
1. Главную, на которой располагаются элементы управления:
2. Форму, отображающую заставку:
3. Форму для About:
4. Форму для COM-сервера.
Структурная схема программы.
В программе используется конвертация данных расчета в приложение Microsoft Office Excel. Создана справочная система программы.
4. Руководство пользователя
Для запуска программы необходимо запустить файл “Pintegral.exe”.
Внешний вид главной формы представлен в ч.3.
1. Ввод данных.
Для правильной работы программы необходимо загрузить в неё данные посредством ввода их в поля TЕdit:
/>
2. Вычисление значения интеграла.
Для вычисления значения интеграла есть возможность воспользоваться пунктом Данные->Применитьла из главного меню
/>
или кнопкой Применить, расположенной на форме:
/>
После вычисления результат отобразится на форме, будет построен график подинтегральной функции и создана таблица результатов расчета.
3. Конвертация данных расчета в приложение Microsoft Office Excel.
Данную операцию можно совершить либо выбрав в главном меню Файл->Экспорт в Excelлибо нажав на кнопку />на главной форме.
5. Вызов справки.
Для вывода справочной информации ?->Справка либо нажав на кнопку />на главной форме.
Внешний вид окна справки:
/>
6. Вызов About.
Для вывода информации о программе ?->Aboutлибо нажав на кнопку />на главной форме.
Внешний вид окна представлен в ч.3.
7 Завершение приложения.
Для выхода из программы необходимо выполнить одно из следующих действий:
Выбрать в главном меню Файл->Выход
Нажать на кнопку />на главной форме.
Либо щёлкнуть на крестике в правом верхнем углу формы />
5. Методика испытаний
Целью проведения испытаний являлась проверка работоспособности программы при различных исходных данных.
1. Исходные данные:
значение левого предела интегрирования: 1,6;--PAGE_BREAK--
значение правого предела интегрирования: 2,7;
точность вычисления: 95;
После нажатия кнопки Применить был получен результат вычислений, построен график функции и составлена таблица с результатами расчета. Программа успешно экспортировала данные в приложение Microsoft Office, показала информацию о программе и файл помощи.
Заключение
В ходе тестирования не было выявлено ошибок и сбоев в работе приложения: процессы вычисления значений интегралов, вывода графиков функций и геометрических смыслов интегралов происходили по мере запросов без ошибок.
Доступ к методам класса, а также методам COM-сервера и динамической библиотеки “ pServer.dll” осуществлялся без ошибок.
Возможно использования приложения как вспомогательного средства при изучении интегрального исчисления.
Список использованных источников
Фаронов В.В. Delphi. Программирование на языке высокого уровня. — СПб: Издательство «Питер», 2000.- 639 с.
Марко Кэнту. Delphi 5 для профессионалов.-СПб.: Питер. 2001. – 944 с.
А.Я.Архангельский. Delphi 7. Учебное пособие. — СПб: Издательство «Питер», 2004.- 1087 с.
Электронные учебники
Приложение 1. Листинг программы
Сервер:
unit pServer_TLB;
// ****************************************************** //
// WARNING
// —
// The types declared in this file were generated from data read from a
// Type Library. If this type library is explicitly or indirectly (via
// another type library referring to this type library) re-imported, or the
// 'Refresh' command of the Type Library Editor activated while editing the
// Type Library, the contents of this file will be regenerated and all
// manual modifications will be lost.
// ********************************************************** //
// PASTLWTR: 1.2
// File generated on 15.11.2005 22:46:27 from Type Library described below.
// ************************************************* //
// Type Lib: C:\Documents and Settings\Sergh\Рабочий стол\Разработка приложения вычисления определенных интегралов по формуле левых прямоугольников (Delphi)\Source\Server\pServer.tlb (1)
// LIBID: {73AF5EFB-ABD6-4565-91C3-0E7C137DA989}
// LCID: 0
// Helpfile:
// HelpString: pServer Library
// DepndLst:
// (1) v2.0 stdole, (C:\WINDOWS\system32\stdole2.tlb)
// ********************************************************* //
{$TYPEDADDRESS OFF} // Unit must be compiled without type-checked pointers.
{$WARN SYMBOL_PLATFORM OFF}
{$WRITEABLECONST ON}
{$VARPROPSETTER ON}
interface
uses Windows, ActiveX, Classes, Graphics, StdVCL, Variants;
// ****************************************************//
// GUIDS declared in the TypeLibrary. Following prefixes are used:
// Type Libraries: LIBID_xxxx
// CoClasses: CLASS_xxxx
// DISPInterfaces: DIID_xxxx
// Non-DISP interfaces: IID_xxxx
// ********************************************************//
const
// TypeLibrary Major and minor versions
pServerMajorVersion = 1;
pServerMinorVersion = 0;
LIBID_pServer: TGUID = '{73AF5EFB-ABD6-4565-91C3-0E7C137DA989}';
IID_IIntegral: TGUID = '{2877719B-94E7-45FB-82BE-7F9CD8A6017C}';
CLASS_Integral: TGUID = '{3AD7BD31-8C15-49ED-A0B5-436060913721}';
type
// ***************************************************//
// Forward declaration of types defined in TypeLibrary
// *******************************************************//
IIntegral = interface;
// *******************************************************//
// Declaration of CoClasses defined in Type Library
// (NOTE: Here we map each CoClass to its Default Interface)
// *********************************************************//
Integral = IIntegral;
// *******************************************************//
// Interface: IIntegral
// Flags: (0)
// GUID: {2877719B-94E7-45FB-82BE-7F9CD8A6017C}
// *****************************************************//
IIntegral = interface(IUnknown)    продолжение
--PAGE_BREAK--
['{2877719B-94E7-45FB-82BE-7F9CD8A6017C}']
function Func(x: Double): Double; stdcall;
end;
// **********************************************************//
// The Class CoIntegral provides a Create and CreateRemote method to
// create instances of the default interface IIntegral exposed by
// the CoClass Integral. The functions are intended to be used by
// clients wishing to automate the CoClass objects exposed by the
// server of this typelibrary.
// ***********************************************************//
CoIntegral = class
class function Create: IIntegral;
class function CreateRemote(const MachineName: string): IIntegral;
end;
implementation
uses ComObj;
class function CoIntegral.Create: IIntegral;
begin
Result := CreateComObject(CLASS_Integral) as IIntegral;
end;
class function CoIntegral.CreateRemote(const MachineName: string): IIntegral;
begin
Result := CreateRemoteComObject(MachineName, CLASS_Integral) as IIntegral;
end;
end.
unit uFunc;
{$WARN SYMBOL_PLATFORM OFF}
interface
uses
Windows, ActiveX, Classes, ComObj, pServer_TLB, StdVcl;
type
TIntegral = class(TTypedComObject, IIntegral)
protected
function Func(x: Double): Double; stdcall;
end;
implementation
uses ComServ;
// Вычисление значения уравнения
function TIntegral.Func(x: Double): Double;
begin
Result := (x + 0.8) / sqrt (x * x + 1.2);
end;
initialization
TTypedComObjectFactory.Create(ComServer, TIntegral, Class_Integral,
ciMultiInstance, tmApartment);
end.
Клиент:
unit uMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, ExtCtrls, TeEngine, Series, TeeProcs, Chart,
Grids, Menus, ToolWin, ComCtrls, ImgList;
type
TfrmMain = class(TForm)
GroupBox1: TGroupBox;
edtA: TEdit;
Label1: TLabel;
edtB: TEdit;
Label2: TLabel;
edtN: TEdit;
Label3: TLabel;
btnApply: TBitBtn;
pnlRes: TPanel;
Chart1: TChart;
Series1: TAreaSeries;
grdAll: TStringGrid;
MainMenu1: TMainMenu;
N1: TMenuItem;
Excel: TMenuItem;
N2: TMenuItem;
nExit: TMenuItem;
N3: TMenuItem;
NApply: TMenuItem;
N5: TMenuItem;
NSave: TMenuItem;
NLoad: TMenuItem;
OpenDialog: TOpenDialog;
SaveDialog: TSaveDialog;    продолжение
--PAGE_BREAK--
ToolBar1: TToolBar;
ToolButton1: TToolButton;
ToolButton2: TToolButton;
ToolButton3: TToolButton;
ToolButton4: TToolButton;
ToolButton5: TToolButton;
ToolButton6: TToolButton;
ToolButton7: TToolButton;
ToolButton8: TToolButton;
ToolButton9: TToolButton;
N4: TMenuItem;
nAbout: TMenuItem;
ToolButton10: TToolButton;
NHelp: TMenuItem;
N6: TMenuItem;
ImageList1: TImageList;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure nExitClick(Sender: TObject);
procedure ExcelClick(Sender: TObject);
procedure NApplyClick(Sender: TObject);
procedure NLoadClick(Sender: TObject);
procedure NSaveClick(Sender: TObject);
procedure nAboutClick(Sender: TObject);
procedure NHelpClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
frmMain: TfrmMain;
implementation
uses uLogo, uIntegral, uAbout;
var
Integral: TIntegral;
{$R *.dfm}
// Создание формы
procedure TfrmMain.FormCreate(Sender: TObject);
var
// Объявляем объект формы логотипа
logo: TfrmLogo;
begin
// Создаем форму
logo := TfrmLogo.Create(self);
// Отображаем форму
logo.ShowModal;
// Создаем объект Integral
Integral := TIntegral.Create(1.6, 2.7, 95);
pnlRes.Caption := 'Результат = ' + FloatToStr(Integral.Calculate);
Integral.Draw(Series1);
Chart1.ZoomPercent(90);
Integral.FillTable(grdAll);
end;
procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
// Очищаем память
Integral.Destroy;
end;
procedure TfrmMain.nExitClick(Sender: TObject);
begin
Close;
end;
procedure TfrmMain.ExcelClick(Sender: TObject);
begin
Integral.ExcelExport(grdAll);
end;
procedure TfrmMain.NApplyClick(Sender: TObject);
begin
Integral.A := StrToFloat(edtA.Text);
Integral.B := StrToFloat(edtB.Text);
Integral.N := StrToInt(edtN.Text);
pnlRes.Caption := 'Результат = ' + FloatToStr(Integral.Calculate);
Integral.Draw(Series1);
Integral.FillTable(grdAll);
end;
procedure TfrmMain.NLoadClick(Sender: TObject);
begin
if (OpenDialog.Execute) then begin    продолжение
--PAGE_BREAK--
Integral.LoadFromFile(OpenDialog.FileName);
edtA.Text := FloatToStr(Integral.A);
edtB.Text := FloatToStr(Integral.B);
edtN.Text := IntToStr(Integral.N);
pnlRes.Caption := 'Результат = ' + FloatToStr(Integral.Calculate);
Integral.Draw(Series1);
Integral.FillTable(grdAll);
end;
end;
procedure TfrmMain.NSaveClick(Sender: TObject);
begin
if (SaveDialog.Execute) then begin
Integral.SaveToFile(SaveDialog.FileName);
end;
end;
procedure TfrmMain.nAboutClick(Sender: TObject);
begin
frmAbout.ShowModal;
end;
procedure TfrmMain.NHelpClick(Sender: TObject);
begin
Application.HelpCommand(0,0);
end;
end.
unit uLogo;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls;
type
TfrmLogo = class(TForm)
Panel1: TPanel;
Label1: TLabel;
Label3: TLabel;
Label2: TLabel;
Image1: TImage;
Timer1: TTimer;
procedure Panel1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
frmLogo: TfrmLogo;
implementation
{$R *.dfm}
// Нажатие мышкой где-либо
procedure TfrmLogo.Panel1Click(Sender: TObject);
begin
// Закрываем форму
Close;
end;
procedure TfrmLogo.FormClose(Sender: TObject; var Action: TCloseAction);
begin
// Очистить память
Action := caFree;
end;
// Кода таймер сработает
procedure TfrmLogo.Timer1Timer(Sender: TObject);
begin
// Закрыть форму
Close;
end;
end.
unit uIntegral;
interface
uses pServer_TLB, Series, Chart, SysUtils, grids,
ComObj, ActiveX, Windows, StdCtrls;
{Класс TIntegral}
type
TIntegral = class
private
_A, _B: real;
_N: integer;
// Методы записи для property-значений
procedure SetA(const Value: real);
procedure SetB(const Value: real);
procedure SetN(const Value: integer);    продолжение
--PAGE_BREAK--
public
// Конструктор (принимает все необходимые для вычислений значения)
constructor Create(ANew, BNew: real; NNew: integer);
// Необходимые property
property A: real read _A write SetA; // начало интегрирования
property B: real read _B write SetB; // конец интенрирования
property N: integer read _N write SetN; // кол-во разбиений
// Вычисление интеграла (возвращаем интегральную сумму)
function Calculate: real;
// Загрузка данных из файла
procedure LoadFromFile(fName: string);
// Сохранение данных в файл
procedure SaveToFile(fName: string);
// Рисование графика
procedure Draw(Series: TAreaSeries);
// Процедура заполнения таблицы
procedure FillTable(Stg: TStringGrid);
// Экспорт в Excel
procedure ExcelExport (Stg: TStringGrid);
end;
implementation
uses Dialogs;
// Вычисление интеграла (возвращаем интегральную сумму)
function TIntegral.Calculate: real;
var
i: Integer;
tmp, h, s: real;
{Объявляем объект интерфейса}
Func: IIntegral;
begin
s := 0;
{Создаем объект интерфейса}
Func := CoIntegral.Create;
h := (_B — _A)/_N; // Вычисляем шаг
for i := 0 to _N do
begin
tmp := i * h;
s := s + h * Func.Func(_A + tmp); // релизация метода
end;
Result := s; // возвращаем результат
Func._Release;
end;
// Конструктор (принимает все необходимые для вычислений значения)
constructor TIntegral.Create(ANew, BNew: real; NNew: integer);
begin
_A := ANew;
_B := BNew;
_N := NNew;
end;
// Рисование графика
procedure TIntegral.Draw(Series: TAreaSeries);
var
i: Integer;
tmp, h: real;
{Объявляем объект интерфейса}
Func: IIntegral;
begin
Series.Clear;
{Создаем объект интерфейса}
Func := CoIntegral.Create;
h := (_B — _A)/_N; // Вычисляем шаг
for i := 0 to _N do
begin
tmp := i * h;
{добавляем в график}
Series.AddXY(_A + tmp, h*Func.Func(_A + tmp));
end;
Func._Release;
end;
// Экспорт в Excel
procedure TIntegral.ExcelExport (Stg: TStringGrid);
var
j: Integer;
Unknown: IUnknown;
Result: HResult;
AppProgID: String;
App, Ch: Variant;
begin    продолжение
--PAGE_BREAK--
// Указать программный идентификатор приложения-сервера
AppProgID := 'Excel.Application';
Result := GetActiveObject(ProgIDToClassID(AppProgID),nil,Unknown);
if (Result = MK_E_UNAVAILABLE) then
// Создать один экземпляр сервера
App := CreateOleObject(AppProgID)
else
// Соединиться с уже запущенной копией сервера
App := GetActiveOleObject(AppProgID);
//------------------------------------------------------
App.Workbooks.Add();
j:=App.Workbooks.Count;
App.Workbooks[j].Activate;
//Обращение к страницам
App.ActiveWorkbook.WorkSheets[1].Name := 'Результат';
//Подготовка данных для построения графика
For j:=1 to _N-1 do
begin
App.ActiveWorkbook.WorkSheets[1].Cells[j,1].Value :=StrToFloat(Stg.Cells[1,j+1]);
App.ActiveWorkbook.WorkSheets[1].Cells[j,2].Value := StrToFloat(Stg.Cells[2,j+1]);
end;
App.DisplayAlerts:=False;
// показать окно приложения на экране
App.Visible := True;
end;
procedure TIntegral.FillTable(Stg: TStringGrid);
var
i: Integer;
tmp, h: real;
{Объявляем объект интерфейса}
Func: IIntegral;
begin
{Создаем объект интерфейса}
Func := CoIntegral.Create;
Stg.RowCount := _N + 1;
Stg.Cells[0,0] := 'N';
Stg.Cells[1,0] := 'X';
Stg.Cells[2,0] := 'Y';
h := (_B — _A)/_N; // Вычисляем шаг
for i := 0 to _N-1 do
begin
tmp := i * h;
{добавляем в таблицу}
Stg.Cells[0,i+1] := IntToStr(i+1);
Stg.Cells[1,i+1] := FloatToStr(_A + tmp);
Stg.Cells[2,i+1] := FloatToStr(h*Func.Func(_A + tmp));
end;
Func._Release;
end;
// Загрузка данных из файла
procedure TIntegral.LoadFromFile(fName: string);
var
f: file of real;
fa, fb, fn: real;
res: boolean;
begin
{$I-}
{Открываем файл}
AssignFile(f, fName);
Reset(f);
{Читаем данные из файла}
Read(f, fa);
Read(f, fb);
Read(f, fn);
{Закрываем файл}
CloseFile(f);
{$I+}
{Проверяем на ошибку}
res := (IOResult = 0) and (fName '');
if (res = false) then
ShowMessage('Неправильное чтение из файла')
else begin {Записываем данные в класс}
_A := fa;
_B := fb;
_N := Round(fn);
end;
end;    продолжение
--PAGE_BREAK--
// Сохранение данных в файл
procedure TIntegral.SaveToFile(fName: string);
var
f: file of real;
fn: real;
res: boolean;
begin
{$I-}
{Открываем файл или создаем}
AssignFile(f, fName);
Rewrite(f);
{$I+}
{Проверяем на ошибку}
res := (IOResult = 0) and (fName '');
if (res = false) then
ShowMessage('Неправильное чтение')
else begin {Записываем данные в файл}
{Пишем данные в файл}
Write(f, _A);
Write(f, _B);
fn := _N;
Write(f, fn);
end;
{Закрываем файл}
CloseFile(f);
end;
// Описание методов записи для property-значений
procedure TIntegral.SetA(const Value: real);
begin
_A := Value;
end;
procedure TIntegral.SetB(const Value: real);
begin
_B := Value;
end;
procedure TIntegral.SetN(const Value: integer);
begin
_N := Value;
end;
end.
unit uAbout;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TfrmAbout = class(TForm)
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
frmAbout: TfrmAbout;
implementation
{$R *.dfm}
procedure TfrmAbout.Button1Click(Sender: TObject);
begin
Close;
end;
end.


Не сдавайте скачаную работу преподавателю!
Данный реферат Вы можете использовать для подготовки курсовых проектов.

Поделись с друзьями, за репост + 100 мильонов к студенческой карме :

Пишем реферат самостоятельно:
! Как писать рефераты
Практические рекомендации по написанию студенческих рефератов.
! План реферата Краткий список разделов, отражающий структура и порядок работы над будующим рефератом.
! Введение реферата Вводная часть работы, в которой отражается цель и обозначается список задач.
! Заключение реферата В заключении подводятся итоги, описывается была ли достигнута поставленная цель, каковы результаты.
! Оформление рефератов Методические рекомендации по грамотному оформлению работы по ГОСТ.

Читайте также:
Виды рефератов Какими бывают рефераты по своему назначению и структуре.

Сейчас смотрят :

Реферат Недостаточность кровообращения 2А степени
Реферат Особенности организации охраны в гостинице Белгород
Реферат Особенности организации боевой службы заставы в районе ЧП в условия
Реферат Влияние мирового финансового кризиса на банковскую систему Испании
Реферат Основи бойового застосування військ РХБ захисту
Реферат Оценка воздействия объекта на окружающую среду
Реферат Оценка устойчивости объекта народного хозяйства к действию поражаю
Реферат Отравляющие и сильно действующие ядовитые вещества общеядовитого д
Реферат Устойчивость систем автоматического управления
Реферат Ответы по ОБЖ для 11 класса;
Реферат Порядок та зміст роботи командира механізованого взводу у сторожовій охороні
Реферат Проникающая радиация Воздействие на людей, здания и технику
Реферат Помещение для нарезки и хранения хлеба столовой воинской части на 2000 человек
Реферат Подтверждение цикла работы автоматики винтовки с клиновым запиранием под патрон 762 газоотводного
Реферат Подготовка к работе и проверка работоспособности АСУ 9К58Б