Структурирование программы

Описание и использование процедур и функций. Формальные и фактические параметры. Структурные части модуля, осуществление его взаимодействия с программой через интерфейсную часть. Составление программы, подсчитывающей количество элементов в массиве.

Рубрика Программирование, компьютеры и кибернетика
Вид курсовая работа
Язык русский
Дата добавления 11.06.2012
Размер файла 25,7 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru/

Министерство образования Российской Федерации

КАЗАНСКИЙ НАЦИОНАЛЬНЫЙ ИССЛЕДОВАТЕЛЬСКИЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ

Кафедра ЕНДиИТ

КУРСОВАЯ РАБОТА

По курсу «Структура алгоритмизации и обработки данных»

СТРУКТУРИРОВАНИЕ ПРОГРАММЫ

Руководитель: Галиуллин Д.К

Студент: Мхитарян В.Г гр. 24201

Альметьевск 2012

Оглавление

Теоретические сведения

Описание и использование процедур и функций

Процедуры

Функции

Формальные и фактические параметры

Локальные и глобальные параметры

Рекурсивные процедуры и функции

Процедурные типы

Модуль пользователя

Стандартные модули Паскаля

Пример стандартного модуля Паскаля

Практические задания.

Процедуры

Функции

Список использованной литературы

программа массив модуль процедура

Теоретические сведения

Описание и использование процедур и функций

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

Процедуры

Подпрограмма-процедура предназначена для выполнения некоторой логически законченной последовательности действий. Описание процедуры состоит из заголовка, раздела описаний и раздела операторов. Завершается описание процедуры точкой с запятой. Заголовок процедуры имеет вид:

procedure имя процедуры (список формальных параметров);

В качестве формальных параметров, как правило, указываются входные и выходные параметры процедуры. Список формальных параметров может быть разбит на группы, разделённые точками с запятыми. В группу включаются однотипные параметры. Для каждого формального параметра указывается его имя и тип. Тип формального параметра - идентификатор. Список формальных параметров может отсутствовать.

Примеры:

procedure summa(a:integer; var b,c:real); {a,b,c формальные параметры}

procedure t;

procedure a(var x:d); {d - имя (идентификатор) нестандартного типа, описанного ранее в разделе type}

Оператор вызова процедуры имеет вид:

имя процедуры (список фактических параметров);

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

Примеры операторов вызова процедур

t; {нет списка фактических параметров

summa(x,y,z); {x,y,z -фактические параметры; x: integer; у, z; real} a(z); {z - фактический параметр, z:d}

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

Функции

Подпрограмма-функция предназначена для вычисления некоторого значения. Описание функции содержит два отличия от описания процедуры.

Заголовок функции имеет вид:

function имя функции (список формальных параметров): тип функции;

Тип функции - это тип возвращаемого результата.

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

Пример:

function f (x:integer):real; begin

f :=sin(x)+sqr(x);

end;

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

Например:

у :=f(a); {а - фактический параметр}

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

Примеры:

function f (х: integer) :real; begin

result :=sin(x)+sqr(x);

end;

Локальная переменная Result может использоваться и в правой части оператора присваивания, не вызывая рекурсивного вызова функции

function f: integer; begin

result:=l; result:= result +1;

end;

Функция f будет возвращать значение 2. А выполнение функции g:

function g: integer; begin

g:=l;

g:=g+l;

end;

приведет к зацикливанию программы.

В Delphi функция может быть вызвана как процедура. При этом возвращаемое значение просто теряется.

Формальные и фактические параметры

Формальные параметры можно разбить на несколько категорий. Рассмотрим две из них:

параметры-значения;

параметры-переменные.

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

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

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

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

procedure summa(a:integer;b:real; var c:real); begin

c:=a+b;

end; {a, b- параметры-значения; с - параметр-переменная}

Локальные и глобальные параметры

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

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

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

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

Примеры:

program Project 1; var x,y,z: integer; procedure newval;

var x,y:integer; {x и у- локальные параметры} begin

х:=1;

y:=1;

end; {конец процедуры} begin х:=0; у:=0; newval; z:=x+y; writeln(z); readln end.

Результат z=0, так как переменные х и у, используемые в основной программе, остаются равными нулю. Для того, чтобы результат z стал равным 2, нужно параметры х и у использовать как глобальные, для этого в теле процедуры newval следует убрать описание переменных х и у:

program Project2; var x,y,z:integer; procedure newval; begin x:=l; y:=1; end; begin x:=0; y:=0;

newval; z:=x+y; writeln(z); readln; end.

Результат z=2, так как x и у - глобальные параметры.

Рекурсивные процедуры и функции

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

Процедурные типы

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

Описание процедурного типа:

type

имя типа - procedure(список формальных параметров); имя типа - function(список формальных параметров):тип функции; var имя переменной: имя типа;

Примеры:

type рrоg - procedure(var х,у: integer);

{процедура с двумя параметрами-переменными целого типа} fane = function(x:real):real;

{функция вещественного типа с одним параметром-значением}

var р:рrоg; f:func;

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

имя переменной: = имя подпрограммы;

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

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

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

Пример:

type

рrоg = procedure(var x,y:integer); func = function(a:real):real; var p:prog; f:func;

x,y:integer; procedure swap(var x,y:integer); var z:integer; begin

z:=x; x:=y; y:=z;

end;

function tan (a:real):real; begin

tan := sin(a)/ cos(a);

end;

begin

readln(x,y);

p:=swap;

f:=tan;

p(x,y);

writeln(x,y);

writeln(f(pi/4));

readln;

end.

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

Модуль пользователя

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

заголовок модуля;

интерфейсная часть модуля;

исполняемая часть модуля;

инициализирующая часть модуля.

Заголовок модуля имеет вид:

unit имя модуля;

Например: unit MyModul;

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

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

Исполняемая часть модуля также является обязательной и включает описание всех подпрограмм модуля. Она начинается со слова implementation. За тем после слова uses указываются имена модулей, используемых подпрограммами данной исполняемой части. Если какой-то модуль уже указан в интерфейсной части, то в исполняемой части его повторять не следует. Далее могут быть: описание локальных меток, констант, типов, переменных, затем описываются подпрограммы модуля. При описании подпрограмм в исполняемой части допустимо использовать сокращенные заголовки.

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

Например:

begin

assignfile(f,'file.dat');

end.

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

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

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

Например:

у:=х+ MyModul.x; {х - переменная программы; MyModul.x - переменная модуля}

Стандартные модули Паскаля

В Турбо Паскале имеется 8 стандартных модулей, в которых содержится множество различных типов, констант, процедур и функций. Этими модулями являются SYSTEM, DOS, CRT, GRAPH, OVERLAY, TURB03, GRAPH3. Модули Паскаля GRAPH , TURBO 3, GRAPH 3 выделены в отдельные TPU -файлы, а остальные входят в состав библиотечного файла TURBO . TPL . Лишь один модуль Паскаля SYSTEM подключается к любой программе автоматически, все остальные становятся доступны только после указания их имен в списке подключаемых модулей.

Модуль Паскаля SYSTEM. В него входят все процедуры и функции стандартного Паскаля, а также встроенные процедуры и функции, которые не вошли в другие стандартные модули (например, INC , DEC , GETDIR и т.п.). Модуль Паскаля SYSTEM подключается к любой программе независимо от того, объявлен ли он в предложении USES или нет, поэтому его глобальные константы, переменные, процедуры и функции считаются встроенными в Турбо Паскаль.

Модуль Паскаля PRINTER делает доступным вывод текстов на матричный принтер. В нем определяется файловая переменная LST типа TEXT, которая связывается с логическим устройством PRN. После подключения данного модуля Паскаля можно выполнить, например, такое действие:

Пример стандартного модуля Паскаля

Uses printer;

Begin

Writeln(lst, ` Турбо Паскаль ');

End.

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

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

Модуль Паскаля DOS . В модуле собраны процедуры и функции, открывающие доступ к средствам дисковой операционной системы MS - DOS .

Модуль Паскаля OVERLAY . Данный модуль необходим при разработке громоздких программ с перекрытиями. Турбо Паскаль обеспечивает создание программ, длина которых ограничивается лишь основной оперативной памятью. Операционная система MS - DOS оставляет программе около 580 Кбайт основной памяти. Память такого размера достаточна для большинства исполняемых программ, тем не менее, использование программ с перекрытиями снимает это ограничение.

Модули Паскаля TURBO 3 и GRAPH 3 введены для обеспечения совместимости с ранней версией системы Турбо Паскаль.

Практические задания

Процедуры

Условие задачи: Написать программу, содержащую процедуры, которые подсчитают:

В первом массиве сумму элементов делящихся на 3;

Во втором массиве сумму элементов делящихся на 7.

Решение задачи на Я.П. Pascal:

uses crt;

const n = 10;

type {объявляем типы arr1 и arr2}

arr1 = array [1..n] of integer;

arr2 = array [1..n] of integer;

procedure summa1(a:arr1); {начало описания процедуры summa1}

var i, k, s:integer;

begin

s := 0;

k := 0;

for i := 1 to n do

begin

if a[i] mod 3 = 0 then

begin

s := s + a[i];

k := k + 1;

end;

end;

writeln('Sum of elements in the FIRST ARRAY = ', s);

writeln('The number of elements in FIRST ARRAY are divides of 3: ', k);

end; {конец описания процедуры summa1}

procedure summa2(a:arr2); {начало описания процедуры summa2}

var i, k, s:integer;

begin

s := 0;

k := 0;

for i := 1 to n do

begin

if a[i] mod 7 = 0 then

begin

s := s + a[i];

k := k + 1;

end;

end;

writeln('Sum of elements in the SECOND ARRAY = ', s);

writeln('The number of elements in SECOND ARRAY are divides of 7: ', k);

end; {конец описания процедуры summa1}

var i:integer;

a:arr1;

b:arr2;

begin {начало основной программы}

clrscr;

writeln('************************************************************');

write('FIRST ARRAY: ');

randomize; {подключаем генератор случайных чисел}

for i := 1 to n do

begin

a[i] := random(100); {указываем диапазон случайных чисел от 0 до 100}

write(a[i],' ');

end;

writeln;

writeln('------------------------------------------------------------');

write('SECOND ARRAY: ');

randomize;

for i := 1 to n do

begin

b[i] := random(50); {указываем диапазон случайных чисел от 0 до 50}

write(b[i],' ');

end;

writeln;

writeln('************************************************************');

summa1(a); {использование процедуры summa1}

writeln('------------------------------------------------------------');

summa2(b); {использование процедуры summa2}

writeln('************************************************************');

writeln('Press "Enter" to exit...');

readln;

end. {конец основной программы}

Функции

Условие задачи №1: Написать программу, содержащую функции, которые вычисляют:

В первом массиве сумму элементов >25;

Во втором массиве сумму элементов > 40.

Решение задачи на Я.П. Pascal:

uses crt;

const n = 10;

type {объявляем типы arr1 и arr2}

arr1 = array [1..n] of integer;

arr2 = array [1..n] of integer;

function summ1(a:arr1) : integer; {начало описания функции summ1}

var i, s:integer;

begin

s := 0;

for i := 1 to n do

begin

if a[i] > 25 then

begin

s := s + a[i];

end;

end;

summ1 := s; {возвращаем значение функции}

end; {конец описания функции summ1}

function summ2(a:arr2):integer; {начало описания функции summ2}

var i, s:integer;

begin

s := 0;

for i := 1 to n do

begin

if a[i] > 40 then

begin

s := s + a[i];

end;

end;

summ2 := s; {возвращаем значение функции}

end; {конец описания функции summ2}

var x, y, i:integer;

a:arr1;

b:arr2;

begin {начало основной программы}

clrscr;

randomize; {подключаем генератор случайных чисел}

writeln('*******************************************************************');

write('FIRST ARRAY: ');

for i := 1 to n do

begin

a[i] := random(100); {указываем диапазон случайных чисел от 0 до 100}

write(a[i],' ');

end;

writeln;

writeln('-------------------------------------------------------------------');

write('SECOND ARRAY: ');

for i := 1 to n do

begin

b[i] := random(200); {указываем диапазон случайных чисел от 0 до 200}

write(b[i],' ');

end;

writeln;

writeln('*******************************************************************');

x := summ1(a); {использование функции summ1}

writeln('Sum elements in the FIRST ARRAY are > 25: ', x);

writeln('-------------------------------------------------------------------');

y := summ2(b); {использование функции summ2}

writeln('Sum elements in the SECOND ARRAY are > 40: ', y);

writeln('*******************************************************************');

writeln('Press "Enter" to exit...');

readln;

end. {конец основной программы}

Условие задачи №2:

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

F(Xi) = sqr(x) + sqrt(x);

F(X2) = x - 2 / 2;

F(X3) = x/ 2 + x/3.

Решение задачи на Я.П. Pascal:

uses crt;

function znach1(x:real):real; {начало описания функции znach1}

begin

znach1 := sqr(x) + sqrt(x);

end; {конец описания функции znach1}

function znach2(x:real):real; {начало описания функции znach2}

begin

znach2 := x - 2 / 2;

end; {конец описания функции znach2}

function znach3(x:real):real; {начало описания функции znach3}

begin

znach3 := x / 2 + x / 3;

end; {конец описания функции znach3}

var i:integer;

x:real;

begin {начало основной программы}

clrscr;

writeln('#','X':8, 'F(X1)':21, 'F(X2)':21, 'F(X3)':20); {формирование шапки таблицы}

writeln('------------------------------------------------------------------------');

randomize; {подключаем генератор случайных чисел}

for i := 1 to 15 do

begin

delay(1000); {делаем задержку в 1 секунду}

x := random(100); {указываем диапазон случайных чисел от 0 до 100}

textcolor(i); {выводим каждую строку таблицы своим цветом}

writeln(i, x:10:2, znach1(x):20:2, znach2(x):20:2, znach3(x):20:2);

end;

writeln('-------------------------------------------------------------------------');

textcolor(GREEN); {выводи функции по которым вёлся расчёт зелёным цветом}

writeln('F(X1) = sqr(x) + sqrt(x)');

writeln('F(X2) = x - 2 / 2');

writeln('F(X3) = x / 2 + x / 3');

textcolor(15); {возращаем белый цвет текста}

writeln('-------------------------------------------------------------------------');

writeln(' Done! ');

readln;

end. {конец основной программы}

Список использованной литературы

Немнюгин С.A. Turbo Pascal. Программирование на языке высокого уровня. СПб.: Питер, 2006.

Йенсен К., Вирт Н. Паскаль. Руководство для пользователя и описание языка, 1982.

Культин Н.Б. Turbo Pascal в задачах и примерах. СПб.: БХВ-Петербург, 2006.

1. Размещено на www.allbest.ru


Подобные документы

  • Разработка СУБД - программного модуля для систематизации, хранения и обработки сведений о работниках лаборатории. Технологический процесс машинной реализации задачи, составление алгоритма, описание переменных процедур и функций. Листинг программы.

    курсовая работа [1,7 M], добавлен 11.01.2013

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

    курсовая работа [146,6 K], добавлен 01.09.2010

  • Создание легкой и удобной в применении программы "Клавиатурный тренажер" с помощью программы Delphi7. Использование компонентов Panel, Timer, Button, Status Bar, Label. Описание процедур и функций программы. Руководство разработчика и пользователя.

    курсовая работа [276,3 K], добавлен 27.05.2015

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

    курсовая работа [1,3 M], добавлен 26.04.2015

  • Использование нестандартных функций и подпрограмм (процедур) для составления алгоритмов вычислений. Программы для вычисления значение корней нелинейного уравнения по методу половинного деления. Составление алгоритма операций над матрицами и интегралами.

    курсовая работа [580,0 K], добавлен 23.08.2015

  • Рассмотрение элементов автоматизированной системы планирования и контроля доходной части бюджета. Использование Microsoft Office Access и технологии ADO в Delphi для связи база данных с программой. Описание структуры и результатов работы программы.

    курсовая работа [691,6 K], добавлен 10.11.2013

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

    курсовая работа [529,7 K], добавлен 19.12.2010

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

    курсовая работа [1,7 M], добавлен 15.04.2015

  • Проектирование модульной структуры программы сетевого мессенджера, назначение модуля "frmMsg". Разработка главной формы и интерфейса пользователя программы. Проектирование модуля формы "About". Разработка методики тестирования и отладка программы.

    курсовая работа [606,7 K], добавлен 19.01.2012

  • Структурная диаграмма программного модуля. Разработка схемы программного модуля и пользовательского интерфейса. Реализация программного модуля: код программы; описание использованных операторов и функций. Вид пользовательской формы с заполненной матрицей.

    курсовая работа [215,3 K], добавлен 01.09.2010

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.