过程或函数问题(急!!!)(200分)

  • 主题发起人 吉祥雨
  • 开始时间

吉祥雨

Unregistered / Unconfirmed
GUEST, unregistred user!
[:(]我在书中看到一个过程作为过程参数的例子:

type TDummyProcedure=Procedure(I:Integer);

procedure p(proc:TDummyProcedure);
var
AProc:TDummyProcedure;

procedure Foo(I:Integer);
begin
I:=0;
I:=I+1;
end;

begin
AProc:=Foo;
P(Aproc);
end;

为什么我将它写入程序中进行编译时提示错误:
Local Procedure/Function 'Foo' assigned to procedure variable
有哪位高手能告诉我应怎样解决?我是严格照书抄下来的。

注明:我将procedure Foo(I:Integer);放在了procedure p(proc:TDummyProcedure);
过程之外就能正常通过编译,但由于变量的问题,我必须使用嵌套,
有哪位高手能帮我?在此先行道谢了!


 
過程函數是不能放在過程里面的,放在外面為什麼不行?
你想達到什麼功能?
 
是不能放在外边。
 
是不能在里面
 
谢谢各位朋友,我有一个大计算函数,原先是用Pascal写的,想转到Delphi上,函数是这样
的:
type
gFunc=function(x,y:real) :real;
fFunc=function(x:real) :real;

function dsp2(c,d: real; m: integer; f1,f2:real; g:gFunc) : real;
var p,q,e,y,u,v: real;
j,m1: integer;

function dsp1(a,b: real; n: integer; f:fFunc): real;
var h,x,y: real;
i: integer;
begin
h:=(b-a)/(2*n);
x:=a;
y:=f(x);
for i:=1 to n do
begin
x:=x+h;
y:=f(x)*4+y;
x:=x+h;
y:=f(x)*2+y;
end;
y:=f(x)*(-1)+y;
dsp1:=y*h/3;
end; (*DSP1*)

function w(s: real): real;
begin
w:=g(s,y);
end;

begin
u:=0;
m1:=m;
y:=c;
p:=dsp1(f1,f2,m1,w);
e:=(d-c)/(2*m1);
for j:=1 to m1 do
begin
y:=y+e;
p:=dsp1(f1,f2,m1,w)*4+p;
y:=y+e;
p:=dsp1(f1,f2,m1,w)*2+p;
end;
p:=dsp1(f1,f2,m1,w)*(-1)+p;
p:=p*e/3;
dsp2:=p;
end; (*DSP2*)

由于在嵌套函数 function w(s: real): real;中使用了函数
function dsp2(c,d: real; m: integer; f1,f2:real; g:gFunc) : real;中定义的
局部变量y以及函数f(x)的调用关系,我Delphi又是生手,使我不知如何是好,拜托各位了!!
 
是不是什么教科书上抄的?[:(]我在书中看到一个过程作为过程参数的例子:
procedure Foo(I:Integer);
begin
I:=0;
I:=I+1;
end;

何不写成 procedure foo(i:integer);
begin
i:=1;
end;

如果编译通过的话,一运行就会死机,无限循环,系统堆栈耗尽

 
过程类型
Object Pascal 的另一个独特功能是可定义过程类型。过程类型属于语言的高级功能,
Delphi 程序员不会经常用到它。因为后面章节要讨论相关的内容(尤其是“方法指针”
Delphi用得特别多),这里不妨先了解一下。如果你是初学者,可以先跳过这部分,
当学到一定程度后再回过头阅读这部分。

Pascal 中的过程类型与C语言中的函数指针相似。过程类型的声明只需要参数列表;如果
是函数,再加个返回值。例如声明一个过程类型,该类型带一个通过引用传递的整型参数:


type
IntProc = procedure (var Num: Integer);
这个过程类型与任何参数完全相同的例程兼容(或用C语言行话来说,具有相同的函数特征
)。下面是一个兼容例程:

procedure DoubleTheValue (var Value: Integer);
begin
Value := Value * 2;
end;
注意:在16位Delphi中,如果要将例程用作过程类型的实际值,必须用far指令声明该例程。

过程类型能用于两种不同的目的:声明过程类型的变量;或者把过程类型(也就是函数指针)
作为参数传递给另一例程。利用上面给定的类型和过程声明,你可以写出下面的代码:

var
IP: IntProc;
X: Integer;
begin
IP := DoubleTheValue;
X := 5;
IP (X);
end;
这段代码与下列代码等效:

var
X: Integer;
begin
X := 5;
DoubleTheValue (X);
end;
上面第一段代码明显要复杂一些,那么我们为什么要用它呢?因为在某些情况下,调用什
么样的函数需要在实际中决定,此时程序类型就很有用。这里不可能建立一个复杂的例子
来说明这个问题,不过可以探究一下简单点的例子,该例名为ProcType。该例比前面所举
的例子都复杂,更接近实际应用。

如图6.3所示,新建一个工程,在上面放两个radio按钮和一个push按钮。例中有两个过程,
一个过程使参数的值加倍,与前面的DoubleTheValue过程相似;另一个过程使参数的值变成
三倍,因此命名为TripleTheValue


procedure TripleTheValue (var Value: Integer);
begin
Value := Value * 3;
ShowMessage ('Value tripled: ' + IntToStr (Value));
end;
两个过程都有结果显示,让我们知道他们已被调用。这是一个简单的程序调试技巧,你可以
用它来检测某一代码段是否或何时被执行,而不用在代码中加断点。

当用户按Apply 按钮,程序会根据radio按钮状态选择执行的过程。实际上,当窗体中有两
个radio按钮时,你只能选择一个,因此你只需要在Apply 按钮的OnClick 事件中添加代码
检测radio按钮的值,就能实现程序要求。不过为了演示过程类型的使用,我舍近求远选择
了麻烦但有趣的方法:只要用户选中其中一个radio按钮,按钮对应的过程就会存入过程变
量:

procedure TForm1.DoubleRadioButtonClick(Sender: TObject);
begin
IP := DoubleTheValue;
end;
当用户按Apply 按钮,程序就执行过程变量保存的过程:

procedure TForm1.ApplyButtonClick(Sender: TObject);
begin
IP (X);
end;
为了使三个不同的函数能访问IP和 X变量,需要使变量在整个窗体单元中可见,因此不能
声明为局部变量(在一个方法中声明)。一个解决办法是,把这些变量放在窗体声明中:

type
TForm1 = class(TForm)
...
private
{ Private declarations }
IP: IntProc;
X: Integer;
end;
学完下一章,你会更清楚地了解这段代码的意思,目前只要能知道怎样添加过程类型定义、
怎样修改相应的代码就行了。为了用适当的值初始化上面代码中的两个变量,你可以调用窗
体的OnCreate 事件(激活窗体后,在Object Inspector中选择这一事件,或者双击窗体)。
此外最好仔细看一看上例完整的源代码。

 
to haofang:
你介绍的内容我比较明白,谢谢!
只是由于我提的问题是一个辛普森二重积分的大函数,不想再 重新编写,
想找一条捷径,即在Delphi中,有什么办法能够使嵌套函数成立?
 
吉祥雨:
看這樣行不行? 行就給分我!!
type
gFunc=function(x,y:real) :real;
fFunc=function(x:real) :real;

function dsp2(c,d: real; m: integer; f1,f2:real; g:gFunc) : real;
var p,q,e,y,u,v: real;
j,m1: integer;

function dsp1(a,b: real; n: integer; f:GFunc): real;//f:fFunc------>f:GFunc
var h,x,yY: real; //注意我將你的這個Y變量改成了YY
i: integer;
begin
h:=(b-a)/(2*n);
x:=a;
y:=f(x,Y);
for i:=1 to n do
begin
x:=x+h;
yY:=f(x,Y)*4+yY;
x:=x+h;
yY:=f(x,Y)*2+yY;
end;
yY:=f(x,Y)*(-1)+yY;
dsp1:=yY*h/3;
end; (*DSP1*)

/* function w(s: real): real;
begin
w:=g(s,y);
end;
這個可以刪除了 */

begin
u:=0;
m1:=m;
y:=c;
p:=dsp1(f1,f2,m1,G);// p:=dsp1(f1,f2,m1,w); 這個W過程函數可以換成p:=dsp1(f1,f2,m1,G)
e:=(d-c)/(2*m1);
for j:=1 to m1 do
begin
y:=y+e;
p:=dsp1(f1,f2,m1,G)*4+p;// 改
y:=y+e;
p:=dsp1(f1,f2,m1,G)*2+p;//改
end;
p:=dsp1(f1,f2,m1,G)*(-1)+p;//改
p:=p*e/3;
dsp2:=p;
end; (*DSP2*)
 
参考这两部份就应该能够解惑了:
1.This is illegal, because the local procedure could then be called even
if the enclosing procedure is not active. This situation would cause the
program to crash if the local procedure tried to access any variables of
the enclosing procedure.
Delphi中是不允许把内嵌的 procedure/func 传给过程变量的.

2.过程内嵌的问题可这样解决
(引自shangshang)
procedure TForm1.Button3Click(Sender: TObject);
var
d:array[1..6] of single;
lb,lc:single;
k1,k2:byte;

function ResultLC:single; [red]//嵌套函数怎样定义?[/red]
var
k: Byte;
begin
result:=0;
for k:=k1 to k2 do result:=result+power(2,d[k]); [red]//已定义的LC变量如何返回值?[/red]
end;

begin //主过程
......
k1:=......;
k2:=......; //在值已经赋值
lc:=lc+ResultLC; [red]//怎样调用所嵌套的函数?[/red]//这里的lc是否要加,你看着办了,我的意思你明就行。
lb:=lc+.....; //需要使用
end;


 
to pdb:
你的答案我看过了,由于机器故障还未试过,我还有一点疑问,就是主函数和嵌套的函数
共同使用同一个函数做参数不会有问题吧?谢谢?
等我试过之后给你加分!

很抱歉,救救我,我在哪儿给你打分???

啊!我看到了,由于刚开始不会用,可能无意中将整分给了haofang朋友,不过这位朋友
也给了我不少帮助,我不后悔。不过pdb,我会记住你的,等有机会我会把分补给你!这次
我将发出12分的抱歉!
 
顶部