gpt4 book ai didi

c# - C# 中的 ref 和 out 是否与 C++ 中的指针相同?

转载 作者:可可西里 更新时间:2023-11-01 17:04:31 35 4
gpt4 key购买 nike

我刚刚用 C# 编写了一个 Swap 例程,如下所示:

static void Swap(ref int x, ref int y)
{
int temp = x;
x = y;
y = temp;
}

它做的事情和这段 C++ 代码做的一样:

void swap(int *d1, int *d2)
{
int temp=*d1;
*d1=*d2;
*d2=temp;
}

那么 refout 关键字是否像 C# 的指针而不使用 unsafe 代码?

最佳答案

它们更受限制。您可以在指针上使用++,但不能在 refout 上使用。


编辑 评论中有些困惑,所以绝对清楚:这里的重点是与指针的功能进行比较。您不能对 ref/out 执行与 ptr++ 相同的操作,即使其寻址内存中的相邻位置。确实(但此处无关紧要)您可以执行与 (*ptr)++ 等效的操作,但那是将其与(而不是指针)的功能进行比较.


可以肯定的是,它们在内部只是指针,因为堆栈不会移动并且 C# 被仔细组织,因此 refout 始终引用一个堆栈的事件区域。


编辑 再次绝对清楚(如果从下面的示例中还不清楚的话),这里的重点不是 ref/out 可以 指向堆栈。就是它指向栈时,语言规则保证它不会成为悬空指针。这种保证是必要的(并且在这里是相关的/有趣的),因为堆栈只是根据方法调用导出丢弃信息,没有检查以确保任何引荐来源网址仍然存在。

相反,当 ref/out 引用 GC 堆中的对象时,这些对象能够在必要时保持事件状态也就不足为奇了:GC 堆是精确设计用于将对象保留其引用者所需的任意时间长度,并提供固定(参见下面的示例)以支持对象不得通过 GC 压缩移动的情况。


如果您曾经在不安全代码中玩过互操作,您会发现 ref 与指针密切相关。例如,如果 COM 接口(interface)声明如下:

HRESULT Write(BYTE *pBuffer, UINT size);

互操作程序集会将它变成这样:

void Write(ref byte pBuffer, uint size);

你可以这样做来调用它(我相信 COM 互操作的东西负责固定数组):

byte[] b = new byte[1000];
obj.Write(ref b[0], b.Length);

换句话说,ref 到第一个字节可以访问所有字节;它显然是指向第一个字节的指针。

关于c# - C# 中的 ref 和 out 是否与 C++ 中的指针相同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1167342/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com