我不知道如果我理解正确的是如何通过引用传递的帕斯卡工作。它创建一个别名如在C ++(https://isocpp.org/wiki/faq/references)或它与C同样地工作,并且该过程获得的指针变量和使用该指针。
我想我可以提出我的问题是:通过引用是否帕斯卡尔支持实际移动,或者它被调用来完成通过共享。
例如FreePascal的参考状态,即该过程得到一个指针(https://www.freepascal.org/docs-html/current/ref/refsu65.html),但根据https://swinbrain.ict.swin.edu.au/wiki/Pass_by_Value_vs._Pass_by_Reference#Conclusion并且例如https://cgi.csc.liv.ac.uk/~frans/OldLectures/2CS45/paramPassing/paramPassing.html#callByReference通过引用传递以帕斯卡原理不同比C(其中指针被传递)。
如果任何人都可以解释多一点的差异或如何传递的参照意义已经改变(在现代语言,我们说通过引用传递,但其实他们是按值传递,例如像Java的)。那么什么是按引用传递的原始意义,它是如何工作的?它是怎样然后帕斯卡尔?
非常感谢你。
在Delphi,通过引用传递(使用VAR或出)指传递指针。但是请注意,有语义之间的差异“按值传递”或与实际通过“按引用传递”。
与C不同的是不实际的传递(通过指针),正是这些关键字的意思。变种简单地通过引用传递。走出对待某些托管类型不同,因为出来,你告诉编译器的输入值不能保证被初始化。否则,这些在技术上是相同的(但不是语义):(IOW,指针)的初始值传递的地址。
但实际产生的代码可能是不同的,优化的原因。特别是较大的结构(有多大取决于版本和平台 - 这是地方文件,并随时间发生变化)经常通过引用(如指针),即使语义说按值传递。在该例程中(即在第一begin
之前运行的隐藏代码)的序幕这种结构被复制到程序的本地帧。请注意,这不是在所有的调用约定完成。有时,一个完整副本的参数堆栈在拨打电话前,没有指针传递。
因为你还有一个本地副本,并没有修改原来,这仍然被认为是按值传递,就像你声明。所有的技术的东西都是透明的用户,所以区别只是在一个较低的水平。这只事项如果你写汇编程序或在CPU窗口必须阅读生成的代码。
如果一个值参数声明const
,原来是不无论如何修改,因此也可以省略大型结构到本地帧的复制和值可以访问(只读)由参考(指针),即使语义按值传递。小值总是通过了由值(在寄存器或堆栈),在这种情况下。
虽然它没有任何意义有const var
作为参数修饰符(东西要么是常量或变量,但不能同时),你仍然可以强制路过一个const
参数参考,使用[ref]
修改属性:const [ref] X: Integer
或[ref] const X: Integer
。整数通常会被传递由值(在寄存器或堆栈上,这取决于调用约定和平台)。
请注意,如果您按值传递引用类型(如对象,动态阵列等),传值语义只适用于引用自己,即你让他们的副本,你可以在不影响原有的修改提供参考。
但是:物品(对象,阵列等)上这些点的引用可以被修改。只有引用本身是本地副本,而不是它们所指向的内容。所以,如果你调用一个方法上按值传递的对象引用,该对象(在堆)可毕竟修改!那还不是因为通过按值或传递作为const的不正常工作,但因为什么引用。
多一点关于引用和指针可以在我的(非常流行)的文章Addressing pointers被发现。
一个简单的答案比(非常好)等。
做它与C同样地工作,并且该过程获得的指针变量和使用该指针。
是的,这是引擎盖下会发生什么。该程序得到真正的指针,地址,给变量。但是编译器,明知,使其透明。所以,这里声明了一个参数“a”,该语句的过程中:
a := a div 2;
可以用两种不同的方式进行编译。如果a
参数正常,即按值传递的声明,该声明被编译,如:
1 - 在地址“a”加载值 2 - 由两个整数除法 3 - 结果存储在地址“一”
相反,如果该参数被宣布为var
,意思是通过引用传递时,编译器:
1 - 在地址“a”加载值 2 - 在刚刚加载地址加载值(这是一个指针引用) 3 - 分 4 - 回存
以上四个语句完全什么C编译如果来源是:
*a = *a / 2;
我想我可以提出我的问题是:通过引用是否帕斯卡尔支持实际移动...?
答案是绝对肯定的,真正的引用传递,并没有太多的语言做这么好,干净。用于调用过程的源代码不改变,过程是否被称为以“通过参考”或“由值”。再次编译,知道形式参数如何被传递,隐藏的细节,与C.例如,拿一个呼叫到其中希望通过值传递的参数的过程:
myproc(a); // pascal and C are identical
如果程序期望通过引用传递事情变得不同:
myproc(a); // pascal: identical to before
myproc(&a); // C: the language does not hide anything
关于最后一点,有人认为C是最好的,因为它迫使程序员知道,通过变量可以由程序(功能)进行修改。我认为,取而代之的是,Pascal是更优雅,而程序员无论如何都应该知道是什么程序就行了。
这一切是“简单”的类型。如果我们谈论的字符串(和现代帕斯卡有他们的两个版本),这是相同的 - 帕斯卡。编译器的副本,增加引用计数,确实无论是需要有通过值或引用传递的全力支持。 C语言中没有类似的东西。
如果我们谈论班,情况就不同了,但他们必须无论如何不同,因为类的语义。
我希望能有补上一其他完整的答案。