C# 中的指针和引用
介绍
首先,让我们澄清一些基本术语。在 C# 中,我们有两种类型的代码,安全和不安全。当代码完全在 CLR(公共语言运行时)的监督下运行时,我们称该代码为安全代码。不安全代码是使用外部资源(如文件、音乐或视频文件或网络流)的代码。对于安全代码,GC(垃圾收集器)会释放不再需要的资源。对于不安全代码,我们需要调用GC.Collect()或实现机制来释放未使用的资源。
使用指针编译应用程序
指针只是一个保存其他类型或变量的内存地址的变量。默认情况下,C# 不允许您在应用中使用指针。本指南中的示例已针对 Visual Studio 2017 或更高版本进行了测试。
我们来看这个例子。
using System;
namespace Pointers
{
class refderef
{
static void Main(string[] args)
{
int* myPointer;
Console.ReadKey(); ;
}
}
}
当您声明一个指针时,您将看到以下错误。
注意:指针和固定大小缓冲区只能在不安全的环境中使用。
好的,C# 中的不安全上下文是什么?
它看起来像这样。
unsafe {
int* myPointer;
}
但仅靠这个包装器还不足以解决问题。我们需要启用以下内容。
使用指针
当你在不安全的上下文中工作时,可能会有三种不同的类型:
- 指针
- 价值
- 参考
我们假设我们在声明周围使用不安全的包装器,这样我们可以减少代码大小并更多地关注指针。
指针声明的骨架如下所示:
<type>* <name>;
一个实际的例子是:
int* myPointer;
单独的指针并没有什么用处。它只是一个指向另一个变量的内存位置的特殊变量。我们在 * 之前指定的类型称为引用类型。只有非托管代码才可以是引用类型,这非常重要。
我们可以在同一行声明多个指针。
string* firstName, lastName, nickName;
注意:指针不能指向引用或包含引用的结构。
您还可以定义指向指针或双指针的指针。
double** myDouble;
这意味着指向双精度指针的指针。通常用于当您想要交换或修改基于另一个指针的指针值时。
让我们通过一个例子来检查一下值和地址是怎样的。
using System;
namespace Pointers
{
class refderef
{
static void Main(string[] args)
{
unsafe {
int myNumber = 10;
int* myPointer;
int** myPointerPointer;
myPointer = &myNumber;
myPointerPointer = &myPointer;
Console.WriteLine($"The value of {nameof(myNumber)} is {myNumber}, the address of {nameof(myPointer)} is {(int)myPointer}, and address of {nameof(myPointerPointer)} is {(int)myPointerPointer}!");
}
Console.ReadKey(); ;
}
}
}
这将产生以下输出:
The value of myNumber is 10, the address of myPointer is 9432328, and address of myPointerPointer is 9432324!
如果您愿意,您也可以在方法声明中使用unsafe关键字。这样做时,您不必使用 unsafe 语句包装指针代码或与其相关的任何内容,因为函数定义将提供此包装器。
我们用以下代码来演示一下:
using System;
namespace Pointers
{
class refderef
{
static unsafe void unsafeMethod() {
int myNumber = 10;
int* myPointer;
myPointer = &myNumber;
Console.WriteLine($"Coming from unsafe method: {nameof(myNumber)} value is {myNumber}, and the pointer {nameof(myPointer)} with address: {(int)myPointer} has the following value: {*myPointer}");
}
static void Main(string[] args)
{
unsafeMethod();
Console.ReadKey(); ;
}
}
}
调用时,我们将得到以下输出。
Coming from unsafe method: myNumber value is 10, and the pointer myPointer with address: 15724316 has the following value: 10
GC 进程将在后台进行内存管理并在内存中移动对象。我们可以选择使用fixed关键字来修复内存中的对象。
此关键字通常用于创建表,我们通过该表向 GC 描述哪些对象应固定在可执行代码的特定区域中。这可能会导致堆碎片化,因此需要谨慎使用。仅在绝对必要时才修复对象。
引用和取消引用
我们已经在上面的代码中演示了如何使用指针。现在的问题是,“ &和\运算符是什么?” 运算符&称为引用运算符,它用于检索变量的地址。这反过来可以分配给指针。\运算符称为取消引用运算符。它用于从指针引用的地址获取值。
结论
正如我们从本指南中了解到的那样,指针与不安全的上下文相关联,这可能使它们看起来更难在您的应用程序中使用和利用。一方面,这是事实,因为它们引入了额外的复杂性,并且可能出现更多问题。但是,我们制定的规则允许您找到平衡并利用 C# 的这一功能为自己谋利。不要忘记记住函数上下文中的 unsafe 关键字与替代方案之间的区别。我希望这值得您花时间,并且您找到了您要找的东西。
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~