русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

С РАЗЛИЧНЫМИ ИМЕНАМИ ТИПОВ


Дата добавления: 2014-11-27; просмотров: 554; Нарушение авторских прав


 

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

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

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

 

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

 

Program Middle1;

Type Xar = array[1..50] of real;

Yar = array[1..500] ofreal;

Zar = array[1..5000] of real;

Var i,nx,ny,nz : integer;

Sx,Sy,Sz : real;

X : Xar;

Y : Yar;

Z : Zar;

ProcedureMiddleAr(Var Buf:Xar; Var S:real; n:integer);

Var i : integer;

Begin

S:=0;

For i:=1 to n do

S:=S+Buf[i];

S:=S/n;

End { MiddleAr };



Begin

Ввод и печать nx, ny, nz, X, Y, Z

MiddleAr(X,Sx,nx);

MiddleAr(Y,Sy,ny);

MiddleAr(Z,Sz,nz);

Печать Sx, Sy, Sz

End.

 

Здесь при трансляции программы будет правильно воспринято лишь первое обращение к процедуре MiddleAr; для остальных обращений будет выдано сообщение о несоответствии типов фактических параметров Y, Z и формального параметра Buf.

 

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

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

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

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

 

 

ProgramMiddle2;

Type Xar = array[1..50] of real;

Yar = array[1..500] of real;

Zar = array[1..5000] of real;

Vari,nx,ny,nz : integer;

Sx,Sy,Sz : real;

X : Xar;

Y : Yar;

Z : Zar;

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

Procedure MiddleAr(Var Buf; Var S:real; n:integer);

Type RealAr = array[1..10000] of real;

Var i : integer;

Begin

S:=0;

Fori:=1 to n do

S:=S+RealAr(Buf)[i];

S:=S/n;

End { MiddleAr };



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

Begin

Ввод и печать nx, ny, nz, X, Y, Z

MiddleAr(X,Sx,nx);

MiddleAr(Y,Sy,ny);

MiddleAr(Z,Sz,nz);

Печать Sx, Sy, Sz

End.

 

Хотя "интерпретирующее" поле RealAr, накладываемое на формальную переменную Buf без типа, длиннее фактических переменных X, Y или Z, в процедуре MiddleAr выхода за пределы реальных массивов не произойдет, если переменные nx, ny, nz не превышают соответственно значений 50, 500, 5000.

Более предпочтительным для RealAr является объявление вида

RealAr = array[1..(2*MaxInt) div SizeOf(real)] of real.

Здесь компилятор определяет для RealAr максимально возможный размер, самостоятельно вычисляя количество элементов такого массива ( 2 × 32767 div6 = 10992 ).

Тип RealAr в процедуре MiddleAr накладывается на формальный параметр Buf без имени типа, который при обращении к процедуре заменяется именем фактического массива. Так как RealAr - это имя типа, а не описание переменной, то объекту с именем RealAr никакой памяти не выделяется. Как и любое имя типа, RealAr определяет множество значений, которые может принимать переменная с этим именем типа.

Как уже было отмечено, для формального параметра Buf в процедуре MiddleAr не указано никакого имени типа. Если бы в этой процедуре было записано S := S + Buf[i], то транслятор выдал бы сообщение об ошибке, поскольку в списке формальных параметров нет информации о том, что собой представляет идентификатор Buf (простая переменная, массив и т.п.). Можно было бы возразить, что эту информацию транслятор мог бы получить из обращения к процедуре MiddleAr. Но ведь описание процедуры предшествует разделу операторов. Следовательно, при трансляции этой процедуры еще не прочитаны обращения к ней, и тип переменной Buf остается неопределенным.

Запись приведенного выше оператора в форме S := S + RealAr(Buf)[i] снимает такое недоразумение, поскольку транслятору в этом случае указано, что имя Buf следует рассматривать как имя одномерного массива с вещественными компонентами.

 

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

 

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

Вначале составим отдельную программу обработки одного массива.

Для заданного массива X будем использовать буферный массив Y, в который пересылаются те элементы массива X, которые еще не записаны в массив Y.

 

Program DelElem;

Const Nmax = 500;

TypeAr = array[1..Nmax] of integer;

Var X,Y : Ar;

i, { параметр цикла }

n, { реальный размер массива X }

m : word; { реальный размер массива Y }

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

FunctionFindElem(r:integer):boolean;

{ Определение признака включения элемента в массив Y }

Var i : word;

Begin

FindElem:=false;

Fori:=1 tom do

If r=y[i] then

Begin

FindElem:=true; Exit

End;

End{ FindElem };

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

Begin

Ввод и печать n, X

m:=0;

For i:=1 to n do

If not FindElem(x[i]) then{ элемент x[i] записывается }

Begin{ в массив Y, если в этом }

Inc(m); y[m]:=x[i] { массиве еще нет такого }

End;{ элемента }

X:=Y; n:=m;

Печать n,X

End.

 

В программе DelElem создается буферный (временный) массив Y, необходимый лишь на период обработки массива X в соответствии с использованным здесь алгоритмом. Размер массива Y в соответствии с его объявлением равен размеру массива X (учитывается частный случай, когда в массиве X нет одинаковых элементов). Если программу DelElem оформлять в виде процедуры, то массив Y должен создаваться в процессе работы этой процедуры, т.е. переменная Y должна быть локальной. Но, как было оговорено в условии задачи, процедура DelElem должна обрабатывать массивы с различными именами типов, имеющими в общем случае различные размеры. Поскольку локальный массив, объявляемый в процедуре, должен иметь вполне определенное, заранее указанное в тексте программы, имя типа, то обеспечить размер такого массива равным размеру обрабатываемого массива X, невозможно. Следовательно, алгоритм, использованный в программе DelElem, не позволяет оформить эту программу в виде процедуры для обработки массивов с различными именами типов. В данном случае необходимо разработать такой алгоритм решения задачи, для реализации которого не требуется дополнительный буферный массив.

В процедуре DelElems, приведенной ниже, производится последовательный просмотр элементов массива A, совмещенного по адресу с формальным массивом U, и, в случае обнаружения повторяющегося элемента, производится его удаление путем сдвига оставшейся части массива на один элемент влево.

 

ProgramDelar;

Type Xar = array[1..50] ofinteger;

Yar = array[1..500] of integer;

Zar = array[1..5000] of integer;

RealAr = array[1..2*MaxInt div SizeOf(integer)]

ofinteger;

Var i,nx,ny,nz : word;

X : Xar; Y : Yar; Z : Zar;

FileX,FileY,FileZ : text;

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

Procedure ReadVector(Var F:text; Var U; Var n:word);

Var A : RealAr absolute U;

Begin{ Чтение массива }

Reset(F); { из текстового файла }

n:=0;

While not eof(F) do

Begin

Inc(n); Read(F,a[n])

End;

End { ReadVector };

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

ProcedureWriteVector(VarU; n:word);

Vari,k : word;

A : RealAr absolute U;

Begin

k:=0; { Вывод массива }

For i:=1 to n do{ на экран }

Begin

Inc(k);

If k<10 then

Write(a[i]:6,' ')

Else

Begin

k:=0; Writeln(a[i]:6);

End;

End;

Ifk>0 then Writeln;

End { WriteVector };

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

ProcedureDelElems(Var U; Var n:word);

Var i,j,k,R : integer;

A : RealAr absolute U;

Begin

i:=1;

While i<n do{ Удаление всех }

Begin { повторяющихся }

R:=a[i]; j:=i+1; { элементов, кроме }

Whilej<=n do{ первого такого }

If R=a[j] then{ элемента }

Begin

Fork:=j ton-1 do

a[k]:=a[k+1];

Dec(n);

End

Else

Inc(j);

Inc(i);

End;

End { DelElems };

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

Begin

ReadVector(FileX,X,nx);

WriteVector(X,nx);

DelElems(X,nx);

WriteVector(X,nx);

 

ReadVector(FileY,Y,ny);

WriteVector(Y,ny);

DelElems(Y,ny);

WriteVector(Y,ny);

 

ReadVector(FileZ,Z,nz);

WriteVector(Z,nz);

DelElems(Z,nz);

WriteVector(Z,nz);

End.

 



<== предыдущая лекция | следующая лекция ==>
А Б С О Л Ю Т Н Ы Е П Е Р Е М Е Н Н Ы Е | Begin ................


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 0.009 сек.