Создание своих процедур

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

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

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

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

  • Подпрограмма - это фактически отдельная программа. Она может иметь свои переменные, метки, константы, равно как и вложенные подпрограммы.

  • Она может использовать переменные, общие для всей программы (глобальные переменные), с учетом того, что они были описаны в основной программе до самой подпрограммы.

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

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

Создание своих процедур

Создаваемая процедура в Паскале имеет следующие элементы:

  • Служебное слово Procedure;

  • Собственное имя, по которому она будет использоваться в программе. Оно идет после служебного слова Procedure

  • Параметры, передаваемые программе (необязательно).

  • Свои разделы var, const, label (необязательно).

  • Собственный раздел begin - end, причем end - это конец подпрограммы. После него всегда ставиться точка с запятой: ";"

  • Внутри этой конструкции - любые элементы языка: циклы, сравнения, дополнительные блоки begin - end.

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

    1. До основной программы составим процедуру, в качестве параметров которой будет передаваться два числа. В этой процедуре будет:

      1. Числа, переданные как параметры складываются друг с другом;

      2. Получившееся значение выводиться на экран;

    2. Сделаем цикл repeat - until. Внутри след. действия:

      1. Запрашиваем 1-е число;

      2. Запрашиваем 2-е число;

      3. Вызываем нашу процедуру, передав ей в качестве параметров эти два числа;

      4. Спрашиваем - повторить?

    3. Цикл повторяется, пока ответ "ДА".

    Вот такая вот простая программка. Исходный код:

    Program P1;
    uses Crt;
    Procedure Add(a, b: Integer);
    var
    C: Integer;
    begin
    C := A + B;
    Write(C);
    end;
    var
    N1, N2: Integer;
    C: Char;
    begin
    repeat
    { Очищаем экран }
    ClrScr;
    { Читаем переменные }
    Write('Введите число N1: ');
    Readln(N1);
    Write('Введите число N2: ');
    Readln(N2);
    Writeln;
    { Вызываем нашу процедуру }
    Add(N1, N2);
    { Спрашиваем - Выйти? }
    Writeln;
    Write('Выйти? (Y/N): ');
    Readln(C);
    until UpCase(C) = 'Y';
    end.

    Теперь давайте разберемся, как создается процедура.

    В первую очередь, посморите на служебное слово Procedure. Это и есть подпрограмма, являющаяся в нашем случае процедурой (помните, есть еще функции). Дальше идет имя процедуры - Add, по этому имени мы обращаемся к ней в программе.

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

    список_переменных: тип

    В этой конструкции имеются некоторые особенности, которые я перечислю:

    1. Список переменных-параметров может отсутствовать - в том случае, если подпрограмме они не требуется:

      Procedure Add;

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

      Procedure Add(A,B: Integer; C: Word; B: Boolean; S: String);

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

    Оформление процедуры

    Procedure

    имя_процедуры (список_параметров: тип);

    const

    список_констант_процедуры;

    var

    список_переменных_процедуры: тип;

    begin

    ... тело_процедуры ...

    end;

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

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

    Составление функций

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

    Последнее реализуется путем простого присваивания какого-нибудь значения самому имени функции. Модифицируем написанную выше программу:

    Program P2;
    uses Crt;
    Function Add(a, b: Integer): Integer;
    var
    C: Integer;
    begin
    Add := A + B;
    end;
    var
    N1, N2: Integer;
    C: Char;
    begin
    repeat
    { Очищаем экран }
    ClrScr;
    { Читаем переменные }
    Write('Введите число N1: ');
    Readln(N1);
    Write('Введите число N2: ');
    Readln(N2);
    Writeln;
    { Вызываем нашу процедуру }
    Write(Add(N1, N2));
    { Спрашиваем - Выйти? }
    Writeln;
    Write('Выйти? (Y/N): ');
    Readln(C);
    until UpCase(C) = 'Y';
    end.

    Обратите внимание на три главных момента в использовании функций.

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

    2. Возвращаемое значение задается простым присваиванием значения имени функции внутри ее.

    3. Как и стандартные функции Паскаля, собственные могут быть использованы внутри процедур:

    Write(Add(N1, N2)); - печатаем значение, возвращаемое функцией Add;

    Так и внутри стандартных конструкций:

    If Add(N1, N2) > 100 then Write('Сумма больше 100!');

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


    Вопросы - ответы

    Вопрос 1.

    Допустим строковой переменной StrNumber присвоили некоторое значение в виде последовательности чисел, т.е. StrNumber:='231456'; Как записать в переменную Count целого типа результат суммирования данных чисел?

    В данной формулировке задачи слова "чисел" следует заменить на слова "цифр", иначе задача не имеет смысла, так как в строке записано единственное число, в исправленной формулировке задача имеет такое решение:

    ...............

    Sum:=0;

    S:=StrNumber;

    while(s[0]<>0)do

    begin

    Val(S[1],i,code);

    inc(Sum,i);

    delete(s,1,1);

    end;

    writeln('Сумма равна ',sum);

    ...............

    Проверка на корректность строки здесь не делается.

    Вопрос 2. Есть такие процедуры как FindFirst и FindNext. Мне нужно организовать поиск, например, всех архивных файлов (пусть будут ARJ, RAR и ZIP) не только в текущем каталоге, указанном в качестве одного из операндов, но и во всех подкаталогах указанного каталога. Чего-то не пойму как это сделать. Судя по NC, VC и FAR - они уже давно определились с этой задачей. Подскажите где взять стандартное решение или одно из возможных?

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

    uses dos;
    Procedure FileFind(Dir,FindName : PathStr);
    {Поиск файлов по маске по всему диску}
    Procedure SearchDir(Dir : PathStr);
    Var
    SRec : SearchRec;
    begin
    {Поиск файлов по маске}
    if Dir[Length(Dir)] <> '' then Dir := Dir+'';
    FindFirst(Dir + FindName, AnyFile, SRec);
    While DosError = 0 do
    begin
    With SRec do
    if Attr and (VolumeID + Directory) = 0 then
    WriteLn(Dir + Name);
    FindNext(SRec);
    end;
    {Поиск всех вложенных каталогов, в т.ч. скрытых, системных, r/o}
    FindFirst(Dir+'*.*', Directory or ReadOnly or Hidden or SysFile, SRec);
    While DosError = 0 do
    begin
    With SRec do
    if (Attr and Directory <> 0) and (Name[1] <> '.') then
    SearchDir(Dir+Name);
    FindNext(SRec);
    end;
    end;
    begin
    SearchDir(Dir);
    end;
    {------------------------------------------}
    {Пример поиска всех .TXT файлов на диске С:}
    begin
    FileFind('c:','*.txt');
    end.



  • Опубликовал admin
    16 Ноя, Воскресенье 2003г.



    Программирование для чайников.