目录
1. 引言
2. Pass By Value
3. Pass By Reference
4. Equality - Pass by Value
5. Equality - Pass by Reference
1. 引言
本章介绍霍尔逻辑和指针编程,通过Ada语言来阐述函数的传参方法。主要讲解了两种传参方式,分别是按值传递(Pass By Value)和按引用传递(Pass By Reference),同时讨论了这两种方式在比较两个对象是否相等时的不同表现。
2. Pass By Value
procedure Pass_By_Value istype Rec is recordX : Integer;end record;R : Rec;procedure Print_R isbeginPut("R.X: "); Put(R.X); New_Line;end Print_R;procedure CheckR(givenR : in out Rec) is beginput("In CheckR"); New_Line;givenR.X := R.X + 1;Print_R;end CheckR;beginR.X := 5;CheckR(R);Put("CheckR done"); New_Line;Print_R;
end Pass_By_Value;
- 在这个例子中,我们创建了一个记录类型
Rec
,包含一个整型字段X
,并且定义了一个该类型的变量R
。 - 然后,我们定义了两个程序
Print_R
和CheckR
。Print_R
程序负责打印R.X
的值,CheckR
程序接受一个Rec
类型的参数givenR
,并将其X
字段设为R.X + 1
,然后打印R
的值。 - 在主程序中,我们首先将
R.X
设为5,然后调用CheckR(R)
,最后打印R
的值。 - 霍尔逻辑中的重要思想是程序的状态通过程序变量来表现,这种按值传递的方式,被调用函数会复制一份实参的值,对复制的值进行修改并不会影响到原实参的值。因此,调用
CheckR
后,R
的值并未改变。
procedure CheckR(givenR : in out Rec) is beginput("In CheckR"); New_Line;givenR.X := R.X + 1;Print_R;end CheckR;
CheckR中的Print_R;会打印什么?
In CheckR
R.X 5
CheckR done
R.X 6
3. Pass By Reference
procedure Pass_By_Rererence istype Rec is record X: Integer;end record;-- pointer typetype RecPtr is access all Rec;-- allows constructing pointers to RR : aliased Recprocedure Print_R isbeginPut("R.X: "); Put(R.X); New_Line;end Print_R; -- takes a pointer as its argumentprocedure CheckR(givenR : in RecPtr) isbeginPut("In CheckR"); New_Line;givenR.X := R.X + 1; print_R;end CheckR;beginR.X := 5;CheckR(R'Access);Put("CheckR done"); New_Line;Print_R;end Pass_By_Rererence;
In CheckR
R.X 6
CheckR done
R.X 6
- 这个例子和前一个例子很类似,不同的是我们引入了指针类型
RecPtr
,并将R
定义为别名(aliased)类型,使得我们可以获取R
的引用(使用R'Access
)。 - 在
CheckR
程序中,我们接受一个RecPtr
类型的参数givenR
。在这个程序中,我们将givenR.X
设为R.X + 1
,然后打印R
的值。 - 在主程序中,我们首先将
R.X
设为5,然后调用CheckR(R'Access)
,最后打印R
的值。 - 按引用传递方式下,被调用函数得到的是实参的地址,对地址所指向的值进行修改,会直接影响到实参。因此,调用
CheckR
后,R
的值被改变。
4. Equality - Pass by Value
procedure Pass_By_Value istype Rec is record X : Integer;end record;R : Rec;procedure CheckR(givenR : in out Rec) is begingivenR.X := R.X + 1;if GivenR = R then Put("Equal");elsePut("Not Equal");end if;New_Line;end CheckR;beginR.X := 5;CheckR(R);
end Pass_By_Value;
Prints “Not Equal”
- 这个例子和第一个例子类似,不同的是在
CheckR
程序中,我们在修改givenR.X
后,使用if
语句检查givenR
和R
是否相等。如果相等则打印“Equal”,否则打印“Not Equal”。 - 按值传递时,由于
givenR
是R
的复制品,所以givenR
的修改并不会影响到R
,即使他们的X
字段相等,givenR
和R
在内存中仍然是两个不同的对象,因此打印出“Not Equal”。
5. Equality - Pass by Reference
procedure Pass_By_Reference istype Rec is record X : Integer;end record;type RecPtr is access all Rec;R : aliased Rec;procedure CheckR(givenR : in RecPtr) is begingivenR.X :=R.X + 1;if GivenR = R'Access then put("Equal");elsePut("Not Equal");end if;New_Line;end CheckR;beginR.X := 5;CheckR(R'Access);
end Pass_By_Reference;
Prints “Equal”
- 这个例子和第二个例子类似,不同的是在
CheckR
程序中,我们在修改givenR.X
后,使用if
语句检查givenR
和R
的引用(R'Access
)是否相等。如果相等则打印“Equal”,否则打印“Not Equal”。 - 按引用传递时,
givenR
是R
的引用,它们指向内存中的同一个对象。因此,即使我们修改了givenR.X
,givenR
和R
仍然相等,所以打印出“Equal”。
这些例子清晰地展示了按值传递和按引用传递的不同,以及它们在判断等价性时的不同表现。