C# 中的指针和引用

发布日期:2026-07-14 02:11:02   来源 : 杭州电子商务研究院    浏览量 :13
杭州电子商务研究院 发布日期:2026-07-14 02:11:02  
13

介绍

首先,让我们澄清一些基本术语。在 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;
}
    

但仅靠这个包装器还不足以解决问题。我们需要启用以下内容。

使用指针

当你在不安全的上下文中工作时,可能会有三种不同的类型:

  1. 指针
  2. 价值
  3. 参考

我们假设我们在声明周围使用不安全的包装器,这样我们可以减少代码大小并更多地关注指针。

指针声明的骨架如下所示:

      <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 关键字与替代方案之间的区别。我希望这值得您花时间,并且您找到了您要找的东西。

以上内容来自杭州电子商务研究院推送
关注
关于我们
热门推荐
合作伙伴
免责声明:本站部分资讯来源于网络,如有侵权请及时联系客服,我们将尽快处理
Copyright © 2025-2027 ToB产业网址导航 公安备案 浙公网安备33010602013138号 浙ICP备16025413号-9
支持 反馈 关注 数据