Основы программирования в паскале

Автор работы: Пользователь скрыл имя, 16 Сентября 2009 в 13:41, Не определен

Описание работы

Учебник по программированию

Файлы: 16 файлов

Pascal процедуры и функции.doc

— 181.00 Кб (Скачать файл)

      end. 

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

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

      Стандартные процедуры (функции) Турбо Паскаля не могут передаваться рассмотренным способом.

      В программе могут быть объявлены  переменные процедурных типов, например, так:

      var

          p1     : Proс1;

          fl, f2  : Func2;

          ар     : array [1..N] of Proс1; 

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

      После такого присваивания имя переменной становится синонимом имени подпрограммы, например:

      type

      Proc = Procedure (n: word; var a: Byte) ;

      var

          ProcVar: Proc;

          x, у   : Byte;

      Procedure Proc1(x: word; var y: Byte); far;

      begin

      if x > 255 then

      y:=x mod 255

      else

          у := Byte(x)

  end;

      begin                   {Главная.программа}

      ProcVar := Proc1;

      for x := 150 to 180 do

      begin

      ProcVar (x + 100, у);

      Write (у:8)

      end

end. 

      Разумеется, такого рода присваивания допустимы и для параметров-функций, пример:

      type

          FuncType = Function (i : Integer) : Integer;

      vаг

          VarFunc : FuncType;

          i : Integer;

      Function MyFunc (count : Integer) : Integer; far;

      Begin

      ....

      end; {MyFunc}

        begin {Основная программа}

      …..

      i :=MyFunc(l);   (Обычное использование результата функции}

      …..

    VarFunc := MyFunc; {Присваивание переменной процедурного типа имени функции MyFunc}

      ……

      end. 

      Отметим, что присваивание

              VarFunc := MyFunc(l); 

будет недопустимым, так как слева и справа от знака  присваивания используются несовместимые типы: слева - процедурный тип, а справа - INTEGER; имя функции со списком фактических параметров MyFunc(1) трактуется Турбо Паскалем как обращение к значению функции, в то время как имя функции без списка параметров рассматривается как имя функции.

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

      8.5. НЕТИПИЗИРОВАННЫЕ  ПАРАМЕТРЫ-ПЕРЕМЕННЫЕ ,,

      Еще одно очень полезное нововведение фирмы  Borland - возможность использования нетипизированных параметров.

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

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

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

      Нетипизированные  параметры в сочетании с механизмом совмещения данных в памяти (см. п.4.4) можно использовать для передачи подпрограмме одномерных массивов переменной длины (этот способ можно использовать в Турбо Паскале версии 6.0 и более ранней, в которых нет открытых массивов).

      В примере 8.4 функция NORMA вычисляет норму вектора, длина которого меняется случайным образом. Стандартная константа MAXINT содержит максимальное значение целого типа INTEGER и равна 32767.

      Следует учесть, что при обращении к  функции NORMA массив Х помещается в стек и передается по ссылке, поэтому описание локальной переменной А в виде одномерного массива максимально возможной длины в 65532 байта (встроенная константа MAXINT определяет максимально возможное значение типа INTEGER и равна 32767), совпадающего с X, на самом деле не приведет к выделению дополнительного объема памяти под размещение этой переменной.

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

      Пример 8.4

      const

      NN = 100; {Максимальная длина вектора}

        var

      а       : array [1..NN] of Real;

      i, j, N : Integer;

      {------------------}

      Function Norma (var x; N: Integer): Real;

      var

          a : array [1..2*MaxInt div SizeOf(Real)] of Real absolute x;

          i : Integer;

          s : Real;

      begin {Norma}

          s :=0;

      for i :=1 to N do

        s := s + sqr(a[i]) ;

      Norma := sqrt(s)

      end {Norma};

      {------------------}

      begin {main}

          for i := 1 to 10 do

            begin

      N := Random(NN) + 1; {Текущая длина вектора}

      for j := 1 to N do

      a[j] := Random;

      WriteLn ('N = ', N:2, ' норма =', Norma (a, N) : 10:7)

      end

  end {main}. 

      Как видно из рассмотренного примера, передача одномерных массивов переменной длины не вызывает никаких трудностей.

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

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

      8.6. РЕКУРСИЯ И ОПЕРЕЖАЮЩЕЕ  ОПИСАНИЕ

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

      Рассмотрим  классический пример - вычисление факториала (пример 18)). Программа вводит с клавиатуры целое число N и выводит на экран значение –N!, которое вычисляется с помощью рекурсивной функции FAC.

      Для выхода из программы необходимо либо ввести достаточно большое целое число, чтобы вызвать nepеполнение при умножении чисел с плавающей запятой, либо нажать Ctrl-Z и Enter.

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

      В примере 8.5 решение при N =0 тривиально и используется для остановки рекурсии.

      Пример 8.5

      Program Factorial;

      {$S+} {Включаем контроль переполнения стека}

        var

      n: Integer;

      Function Fac(n: Integer): Real;

      {Рекурсивная функция, вычисляющая n!}

        begin {Fac}

        if n < 0 then

      WriteLn ('Ошибка в задании N')

      else

      if n=0 then

      Fac := 1

      else Fac := n * Fac(n-l)

        end   {Fac};

      {-----------------}

begin {main}

        repeat

      ReadLn(n) ;

      WriteLn('n! = ',Fac(n))

      until EOF

end {main}. 

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

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

      Если, например, попытаться заменить тип  REAL функции FAC (см. пример 8.5) на EXTENDED, программа перестанет работать уже при N = 8.

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

      Вот правильный вариант примера 8.5 для  работы с типом EXTENDED: 

      Program Factorial;

      {$S+,N+,E+} {Включаем контроль стека и работу сопроцессора}

          var

          n: Integer;

          Function Fac(n: Integer): extended;

          var

            F: extended; {Буферная переменная для разгрузки стека сопроцессора}

      {Рекурсивная  функция, вычисляющая  п!}

        begin {Fac}

        if n < 0 then

      WriteLn ('Ошибка в задании N')

          else

            if n = 0 then

            Fac := 1

            Else

              Begin

                F := Fac(n-l);

                Fac := F * n

            End

  end   {Fac};

      {------------------}

      begin {main}

      repeat

      ReadLn(n) ;

      WriteLn('n! = ',Fac(n))

      until EOF

  end {main}. 

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

Procedure A (i : Byte) ;

      Begin

      ……

      B(i);

      Procedure В (j : Byte) ;

Pascal динамические структуры данных.doc

— 147.00 Кб (Просмотреть файл, Скачать файл)

Pascal и графика.DOC

— 116.50 Кб (Просмотреть файл, Скачать файл)

Program Graph.doc

— 19.00 Кб (Просмотреть файл, Скачать файл)

Unit GraphApp.doc

— 21.50 Кб (Просмотреть файл, Скачать файл)

Unit GraphObj.doc

— 21.50 Кб (Просмотреть файл, Скачать файл)

Краткие основы Паскаля.doc

— 217.00 Кб (Просмотреть файл, Скачать файл)

Общие понятия программирования.doc

— 80.00 Кб (Просмотреть файл, Скачать файл)

Основные принципы ООП.doc

— 151.00 Кб (Просмотреть файл, Скачать файл)

Основы разработки программ.doc

— 148.00 Кб (Просмотреть файл, Скачать файл)

Паскаль на 5-КУ 85 листов.doc

— 651.50 Кб (Скачать файл)

Модуль CRT.doc

— 30.00 Кб (Просмотреть файл, Скачать файл)

Модуль Graph.doc

— 77.50 Кб (Просмотреть файл, Скачать файл)

Структура модуля.doc

— 38.00 Кб (Просмотреть файл, Скачать файл)

Практичесое занятие по работе с модулем граф.doc

— 52.00 Кб (Просмотреть файл, Скачать файл)

Целочисленная арифметика TURBO PASCAL.doc

— 92.00 Кб (Просмотреть файл, Скачать файл)

Информация о работе Основы программирования в паскале