Paw*_*hra 19 .net c# recursion
说我有以下代码:
void Main()
{
int a = 5;
f1(ref a);
}
public void f1(ref int a)
{
if(a > 7) return;
a++;
f1(ref a);
Console.WriteLine(a);
}
Run Code Online (Sandbox Code Playgroud)
输出是:
8 8 8
Run Code Online (Sandbox Code Playgroud)
即,当堆栈展开时,保持ref参数的值.
这是否意味着将ref keyword要int parameter使其得到盒装?
在递归调用期间,实际堆栈如何?
All*_*hty 25
通过引用传递值类型会导致其在堆栈上的位置传递而不是值本身.它与装箱和拆箱无关.这使得在递归调用期间堆栈的外观变得相当容易,因为每个调用都指向堆栈上的"相同"位置.
我认为很多混淆来自MSDN关于拳击和拆箱的段落:
Boxing是给定进程的名称,其中值类型被转换为引用类型.当您装入变量时,您将创建一个指向堆上的新副本的引用变量.引用变量是一个对象,...
您可能会在两个不同的事物之间混淆:1)按照您的意愿"转换"一个值类型来表示一个对象,根据定义它是一个引用类型:
int a = 5;
object b = a; // boxed into a reference type
Run Code Online (Sandbox Code Playgroud)
和2)与值类型参数的通过由参考:
main(){
int a = 5;
doWork(ref a);
}
void doWork(ref int a)
{
a++;
}
Run Code Online (Sandbox Code Playgroud)
这是两件不同的事情.
小智 9
创建一个程序可以很容易地给出不同的结果,具体取决于是否ref int装箱:
static void Main()
{
int a = 5;
f(ref a, ref a);
}
static void f(ref int a, ref int b)
{
a = 3;
Console.WriteLine(b);
}
Run Code Online (Sandbox Code Playgroud)
你得到了什么?我看到3印刷了.
拳击涉及创建副本,所以如果ref a盒装,输出将是5.相反,无论是a和b是原来的引用a变量Main.如果它有帮助,你可以大多数(不完全)将它们视为指针.
在现有答案中添加这是如何实现的:
CLR 支持所谓的托管指针。 ref将托管指针传递到堆栈上的变量。您还可以传递堆位置:
var array = new int[1];
F(ref array[0]);
Run Code Online (Sandbox Code Playgroud)
您还可以传递对字段的引用。
这不会导致固定。运行时(特别是 GC)可以理解托管指针。它们是可重定位的。它们是安全且可验证的。
| 归档时间: |
|
| 查看次数: |
1805 次 |
| 最近记录: |