Программирование в школе

Методические заметки и задачи к урокам

Из портфолио учителя информатики и ИКТ     
Безрученко Людмилы Ивановны
e-mail:bezli@mail.ru     

   
  Условные конструкции  
  Циклы  
  Подпрограммы-функции
 
  Подпрограммы-процедуры
 
Назад

Раздел "Программирование"

Пользовательские процедуры

Цель: освоить опыт модульного программирования при решении задач на языке Паскаль; изучить особенности пользовательских процедур; передачу параметров по значению и по ссылке (или по адресу); выяснить, когда нужны var-параметры.

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

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

2. Передача параметра по ссылке (или по адресу).     

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

    Примечание. Необходимо помнить о следующих особенностях подпрограммы-процедуры:

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

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

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

    Примеры пользовательских процедур

    Процедуры очень удобно использовать при решении задач, в которых выполняется обработка структурированных данных - массивов и строк. При этом необходимо помнить, что при описании формальных параметров нельзя задавать тип данных с указанием конкретной размерности массива или конкретной длины строки -
    для структурированных типов данных необходимо вводить пользовательское имя.
    Например,
          type mas=array[1..n] of integer;
          type stroka=string[30];
          var
            a:mas;
            fio, name:stroka;
    procedure(var b:mas; n:integer); procedurt(var st:stroka,m:integer);

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

    Пример 1. Процедура печатает все делители заданного целого числа number и сообщает, является ли число простым или нет.

    procedure printdivisors(j: word; var flag:boolean);
    {j не меняет свое значение, а переменная flag изменяет свое значение }
       var
        m :word; {возможные делители}
      begin
          flag:=true;{гипотеза, что число простое}
          {Проверка производится до первого делителя}
          m:=2; {первый возможный делитель}
          while (m <j) and flag do
            begin
             if j mod m=0 then
              begin
                   flag:=false;
                   write(m,' ');
              end;
          m:=m+1
          end;{while}
      end;{printdivisors}

    Если в главной программе объявлены переменные
          n:word; prime: boolean;
    то вызов процедуры в главной программе выполняют операторы:
          printdivisors(n,prime);
          if prime then writeln(n,'- простое');

    Пример 2. Создание массива.

    Вариант 1. Ввод чисел с клавиатуры.
    procedure inputmas(var b : mas; n:integer);
      var
        i: integer;
    begin
      for i:= 1 to n do
        readln(b[i]);
      enf; {inputmas}

    Вариант 2. Заполнение массива случайными числами.
    procedure inputmas(var b : mas; n:integer);
      var
        i: integer;
    begin
      for i:= 1 to n do
        b[i]:=random(100);
      enf; {inputmas}

    Пример 3. Вывод массива на экран.

    procedure outmas(var b : mas; n:integer);
      var
        i: integer;
    begin
      for i : = 1 to n do
        write(b[i],' ');
      writeln;
      end; {outmas}

    Пример 4. Сортировка массива целых чисел методом "пузырька"
    Идея: Внешний цикл repeat ... until "прокручивает" внутренний цикл for..., пока не обнаружит, что при очередном просмотре ряда не произошло ни одной перестановки элементов.

    procedure sort(var a: mas; n : intejer);
    {упорядочение по возрастанию}
      var
        i : integer;
    begin
      repeat
        flag:=false;
        for i:=1 to n-1 do
          if a[i]>a[i+1] then
              begin {перестановка двух соседних элементов массива}
                     flag:=true;
                    temp:=a[i];
                    a[i]:=a[i+1];
                    a[i+1]:=temp
              end; {if...then}
      until flag=false
    end; {sort}

  • Упражнения

    Написать подпрограммы-процедуры:

  • расчета количества четных чисел в массиве n целых положительных чисел;
  • замены всех четных чисел в массиве нулями, а кратных трем - единицами;
  • заполнения массива заданным целым числом;
  • Perest(var a : mas; k, m : integer);
    для перестановки двух элементов с индексами
    k и m.