Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 25.10.2012, 18:49   #1
powerdxs
 
Регистрация: 25.10.2012
Сообщений: 4
По умолчанию Вопрос про процедурный тип

В общем ситуация такая: препод по инфе спрашивает зачем в этой программе я использую процедурный тип( конкретно для вычисления значений y)

Код:

.unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, unit2;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    ComboBox1: TComboBox;
    Edit1: TEdit;
    Edit2: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation
Const 
Ix=60;  Iy=60;  //величины отступов от краев поля вывода
nt=100; //число интервалов на оси x
ndx=10;  ndy=10; //число разбиений по осям (x, y), сетка графика 
nc=7; mc=2; // константы для вывода оцифровки осей
Var  nom: integer; //номер графика в ComboBox1

{$R *.dfm}



procedure TForm1.Button1Click(Sender: TObject);
Var
x, y: array of real; //массивы точек графика в мировых координатах
kx, ky: array of integer; // массивы точек графика в экранных координатах
xmin, xmax: real; //минимальные и максимальные значения аргумента
ymin, ymax: real; // минимальные и максимальные значения функции
dx: real; //шаг аргумента при вычислении координат точек графика
cx, cy: real; //масштабные коэффициенты
dxx, dyy: real; //шаг оцифровки по осям
dxE, dyE: real; //расстояния между линиями сетки
xt, yt: real; //текущие значения оцифровки линий сетки графика
xtE, ytE: integer; //координаты начала линий
xmaxE, ymaxE, xminE, yminE: integer; // максим. и минимальные значения поля вывода
s: ShortString;  //выражение функции
i:integer;
nom: integer; //номер функции
begin
yminE:=0;
 xminE:=0;
 xmaxE:=ClientWidth;
  ymaxE:=ClientHeight ;
Form1.Canvas.Pen.Color:=clBlue;
  Form1.Canvas.Brush.Color:=clwhite;
  Form1.Canvas.Rectangle(xminE, yminE, xmaxE, ymaxE-Iy-35);//прямоугольник
  //Вычисление координат поля вывода графика
  xminE:=Ix; yminE:=Iy;
  xmaxE:= xmaxE-Ix;
  ymaxE:= ymaxE -2*Iy;
  xmin := StrToFloat( Edit1.Text );
   xmax := StrToFloat( Edit2.Text );

   //Выделение памяти для массивов
   SetLength (x, nt+1);    
  SetLength (y, nt+1);
   dx:=(xmax-xmin)/nt;
   ymin:= 1E30;
    ymax:= -1E30;
    nom := ComboBox1.ItemIndex;

      //Вычисление минимума и максимума
     For i:=0 to nt do
begin
     x[i]:= xmin+i*dx;
     y[i]:= F[nom+1](x[i]);
     if y[i]>ymax then
        ymax:=y[i];
     if y[i]<ymin then
       ymin:=y[i];
  end;
  //вычисление масштабных коэфициентов
  cx:=(xmaxE-xminE)/(xmax-xmin);
  cy:=(ymaxE-yminE)/(ymax-ymin);

  //выделение памяти для массивов с экранными координатами
  SetLength (kx, nt+1);
  SetLength (ky, nt+1);

  //вычисление экранных коорд.
  for i := 0 to nt do
  begin
    kx[i]:=ROUND(xminE+(x[i]-xmin)*cx);
    ky[i]:=ROUND(yminE+(ymax-y[i])*cy);
  end;
   dxx:=(xmax-xmin)/ndx;  //шаг оцифровки по оси Х линий сетки в мировых координатах
dxE:=(xmaxE-xminE)/ndx;   //расстояния между линиями сетки
Form1.Canvas.Pen.Color:= clGreen;
Form1.Canvas.Font.Color:= ClBlue;

//Цикл для выведения линий
for i := 0 to ndx do
 begin
  xt:= xmin + i*dxx; //текущее значение оцифровки линии сетки на оси Х
  Str(xt: nc: mc, s); //– преобразование значения оцифровки в строку
  xtE:= Round(xminE+ i*dxE);//– координата начала линии сетки

  Form1.Canvas.MoveTo(xtE,yminE);
  Form1.Canvas.LineTo(xtE, ymaxE);
  Form1.Canvas.TextOut(xtE-8*mc, ymaxE+4, s);
  end;
  dyy:=(ymax-ymin)/ndy;
  dyE:=(ymaxE-yminE)/ndy;
  //Тоже самое только с у
  for i := 0 to ndy do
  begin
    yt:=ymax - i*dyy;
    Str(yt: nc: mc, s);
    ytE:= Round(yminE + i*dyE);
    Form1.Canvas.MoveTo(xminE, ytE);
    Form1.Canvas.LineTo(xmaxE, ytE);
    Form1.Canvas.TextOut(xminE-24*mc, ytE-4, s);
  end;



  Form1.Canvas.Pen.Width:=2;

  Form1.Canvas.Pen.Color := clRed;
  Form1.Canvas.MoveTo(KX[0],KY[0]);
  //Вывод графика функции
  for I := 1 to nt do
    Form1.Canvas.LineTo(KX[I],KY[I]);
Form1.Canvas.Pen.Color:= rgb(210,10,24);


//Вывод текста сверху
s:= 'График функции ' + ComboBox1.items[ComboBox1.ItemIndex];

Form1.Canvas.TextOut ((xminE + xmaxE) div 2-Length(s) div 2-30, yminE div 2, s);


end;





procedure TForm1.Button2Click(Sender: TObject);
begin
close;
end;

procedure TForm1.FormCreate(Sender: TObject);
 var i : integer;
begin
  ComboBox1.ItemIndex:=0;
  for i := 0 to nn - 1 do
    ComboBox1.AddItem(FX[i+1], sender);
  Edit1.Text:='-5';
  Edit2.Text:='5';
end;

end.

end.


________
Код нужно оформлять по правилам:
тегом [CODE]..[/СODE] (это кнопочка с решёточкой #)
Не забывайте об этом!

Модератор.

Последний раз редактировалось Serge_Bliznykov; 25.10.2012 в 21:48.
powerdxs вне форума Ответить с цитированием
Старый 25.10.2012, 18:50   #2
powerdxs
 
Регистрация: 25.10.2012
Сообщений: 4
По умолчанию

Вот собственно модуль с функциями
Код:
unit Unit2;

interface
uses SysUtils, Math;
Const nn=4;
Type
Tfunc = Function (x:real):real;
TarrF = array[1..nn] of Tfunc;
TarrFX = array[1..nn] of ShortString;

Var
F: TarrF;
FX: TarrFX;
Function F1 (x:real):real;
Function F2 (x:real):real;
Function F3 (x:real):real;
Function F4 (x:real):real;
implementation
Function F1 (x:real):real;
  begin
    result :=x*sin(x);
  end;
Function F2 (x:real):real;
  begin
    result :=Exp(x)*(Sqr(x)+1);
  end;
Function F3 (x:real):real;
  begin
    result :=Cos(x)/ln(x);
  end;
Function F4 (x:real):real;
  begin
    result :=Sqrt(x)*sin(x);
  end;

initialization
F[1]:=F1;
F[2]:=F2;
F[3]:=F3;
F[4]:=F4;
FX[1]:='x*sin(x)';
FX[2]:='Exp(x)*(Sqr(x)+1)';
FX[3]:='Cos(x)/ln(x)';
FX[4]:='Sqrt(x)*sin(x)';

end.


________
Код нужно оформлять по правилам:
тегом [CODE]..[/СODE] (это кнопочка с решёточкой #)
Не забывайте об этом!

Модератор.

Последний раз редактировалось Serge_Bliznykov; 25.10.2012 в 21:42.
powerdxs вне форума Ответить с цитированием
Старый 25.10.2012, 19:49   #3
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,883
По умолчанию

Был бы я преподом, я бы сразу на месте спросил, оценил ответ и поставил оценку (да собственно, я так и делал, когда был преподом, правда не по программированию).

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

Однако, я Вам отвечу, если уж фрилансер, который это делал, не разъяснил.
Процедурный тип в данном случае объявляет некую спецификацию подпрограммы.
Код:
Tfunc = Function (x:real):real;
Потом создаются переменные этого типа ( сразу их массив), для сохранения в них указателей на некие подпрограммы, сохраняются они тут:
Код:
F[1]:=F1;
F[2]:=F2;
F[3]:=F3;
F[4]:=F4;
Все эти подпрограммы, естественно, отвечают спецификации типа.
Во время работы основного алгоритма, для гибкости оного и независимости от конкретной функции для построения её графика вызывается нужная запомненная в массиве указателей просто по индексу (взятому из комбобокса) - то , что у Вас красным, расчёт выполняет именно та функция, указатель на которую мы используем. Гибкость в том, что программу легко снабдить кучей функций, просто прописав их и увеличив массив, остальной код программы трогать не надо. Гибкость, конечно, не оптимальна, лучше бы создать саму функцию построения графика и в неё передавать параметром указатель на функцию расчёта, а привязка к кнопке и комбобоксу (да и канвасу конкретного экземпляра формы)- убивает гибкость по большей части.
phomm вне форума Ответить с цитированием
Старый 25.10.2012, 20:09   #4
xoodoo
Форумчанин
 
Регистрация: 11.04.2012
Сообщений: 212
По умолчанию

Цитата:
препод по инфе спрашивает зачем в этой программе я использую процедурный тип
Да, дитятко, препод мешает тебе жить.
xoodoo вне форума Ответить с цитированием
Старый 26.10.2012, 11:40   #5
powerdxs
 
Регистрация: 25.10.2012
Сообщений: 4
По умолчанию

Цитата:
То, что Вы спрашиваете, плюс смотря на код, говорит о том, что код не Ваш и оценку Вы не заслуживаете не при каком ответе.
Спрашиваю потому что уже отчаялся отвечать ему под чем сам понимаю процедуры, а по поводу кода, то писал сам просто подписывал на защите лабы преподу, т.к. он так защищает.


По поводу ответа, то я ему пытался объяснить примерно тоже что вы написали, но он после таких ответов вообще в этот день у меня лабу не принимает, говорит что я не понимаю что такое процедурный тип и все, больше никаких комментариев не дает.
Может есть какое-то определение для этого типа, просто все что в паутине нашел были отвергнуты.
powerdxs вне форума Ответить с цитированием
Старый 26.10.2012, 13:02   #6
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,883
По умолчанию

Хм.. я верю, когда мне говорят, поэтому свои "наезды" снимаю (просто исключения редки в таких случаях, и я даже рад что наткнулся на исключение).

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

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

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

Я не удивлюсь если препод отвергнет и этот ответ, который по сути является незыблемой истиной (если я не попутал конечно), ибо опирается на "железо", а не на какие-то там абстрактные определения, которое возможно он с Вас и выпытывает, тогда в этом случае Ваша обязанность была законспектировать его и выучить назубок.

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

ПС. Зашёл на самый уважаемый мной интернет-мануал по дельфи и подыскал Вам http://delphikingdom.com/asp/viewite...catalogid=1179 пункт 2.8.11

Последний раз редактировалось phomm; 26.10.2012 в 13:06.
phomm вне форума Ответить с цитированием
Старый 26.10.2012, 13:50   #7
powerdxs
 
Регистрация: 25.10.2012
Сообщений: 4
По умолчанию

phomm, спасибо большое за столь развернутый ответ, попробую с этой точки зрения объяснить ему, может получится.
powerdxs вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Процедурный тип Sweet-_-Orange Помощь студентам 3 01.02.2012 21:16
Процедурный тип. Интегралы. kuy Паскаль, Turbo Pascal, PascalABC.NET 2 26.11.2011 00:11
Процедурный тип в Delphi <Maria> Помощь студентам 1 14.11.2010 18:03
Процедурный тип в C++Builder sneksnek2006 C++ Builder 4 14.10.2010 10:46
Процедурный тип в паскале tanyhaftv Помощь студентам 0 24.03.2010 09:07