首页  >  文章  >  后端开发  >  C# 中的指针

C# 中的指针

王林
王林原创
2024-09-03 15:06:41420浏览

指针被定义为包含另一个变量的内存地址的变量。 C# 中的指针在存在不安全且由 unsafe 关键字标记的语句时使用。这些类型的语句不受垃圾收集器的控制并使用指针变量。

语法: 指针可以声明为

type  *var name;
int* a;

这里 * 称为解引用运算符,a 是包含 int 类型地址的变量。

示例

int *p = & x;    // where &x is the memory address of x
Console.WriteLine((int)p) // displaying memory address
Console.WriteLine(*p) // displaying value at memory address

指针在 C# 中如何工作?

下面的示例展示了它在 C# 中的工作原理。

C# 中的指针 – 示例#1

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Pointers
{
class Demo
{
public void Method()
{
unsafe
{
int a = 40;
int b = 20;
int* ptr1 = &a;
int* ptr2 = &b;
Console.WriteLine(*ptr1);    // displaying the value
Console.WriteLine(*ptr2);    // displaying the value
Console.WriteLine((int)ptr1); // displaying the address
Console.WriteLine((int)ptr2); // displaying the address
}
}
}
class Example
{
// main method
public static void Main()
{
Demo d = new Demo();
d.Method();
}
}
}

有不同的方法可以执行不安全的语句,如修饰符、构造函数等。在上面的示例中,一组语句被标记为不安全。在上面的代码中,有两个变量a和b,其值分别为40和20,指针包含它们的地址。 Console.WriteLine() 用于显示变量的值和地址。

输出:

C# 中的指针

C# 中的指针 – 示例#2

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Pointers
{
class Demo
{
public unsafe void Method()
{
int a = 50;
int b = 20;
int* ptr1 = &a;
int* ptr2 = &b;
Console.WriteLine(*ptr1);       // displaying the value
Console.WriteLine(*ptr2);       // displaying the value
Console.WriteLine((int)ptr1);   // displaying the address
Console.WriteLine((int)ptr2);   // displaying the address
}
}
class Example
{
// main method
public static void Main()
{
Demo d = new Demo();
d.Method();
}
}
}

在上面的示例中,unsafe 与有两个变量 a 和 b 的方法一起使用,其值分别为 50 和 20。指针 *ptr1 和 *ptr2 指向它们的内存地址。

输出:

C# 中的指针

C# 中的指针 – 示例#3

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Pointers
{
class Demo
{
public unsafe static void Main()
{
int[] array = { 10, 20, 30, 40, 50 };    // declaring array
fixed (int* ptr = array)                 // fixed for pinning the object
/* let us have array address in pointer */
for (int i = 0; i < 5; i++)
{
Console.WriteLine("Value of array[{0}]={1}", i, *(ptr + i));
Console.WriteLine("Address of array[{0}]={1}", i, (int)(ptr + i));
Console.ReadKey();
}
}
}
}

上面的代码中,定义了一个由五个元素组成的数组,并使用 Console.WriteLine() 显示数组元素的值和数组元素的地址。 C# 中有一个概念,称为对象的固定。上面的代码中,使用了一个fixed语句来固定对象,这样垃圾收集器就不会让对象移动并“固定”它。可能会影响运行效率。

输出:

C# 中的指针

C# 中的指针 – 示例 #4

using System;
namespace Pointers
{
// Struct employee
struct Employee
{
// members
// employee id and salary
public int empid;
public double salary;
// Constructor to initialize values
public Employee(int e, double s)
{
empid = e;
salary = s;
}
}; // end of struct
class Program
{
// Main Method
static void Main(string[] args)
{
// unsafe so as to use pointers
unsafe
{
// Declaring two employee Variables
Employee E1 = new Employee(798, 30000);
Employee E2 = new Employee(799, 31000);
// Declaring two employee pointers
// and initializing them with addresses
// of E1 and E2
Employee* E1_ptr = &E1;
Employee* E2_ptr = &E2;
// Displaying details of employees using pointers
// Using  the arrow ( -> ) operator
Console.WriteLine("Details of Employee 1");
Console.WriteLine("Employee Id: {0} Salary: {1}",
E1_ptr->empid, E1_ptr->salary);
Console.WriteLine("Details of Employee 2");
Console.WriteLine("Employee Id: {0} Salary: {1}",
E2_ptr->empid, E2_ptr->salary);
} // end unsafe
} // end main
} // end class
}

在上面的示例中,employee 结构体包含成员员工 ID 和薪水,并参数化构造函数来初始化值。指针指向包含原始值类型的结构,而不是包含引用类型的结构。在main方法中,有两个员工变量和员工指针,分别用地址E1和E2进行初始化。 Console.WriteLine() 用于使用指针显示员工的详细信息。

输出:

C# 中的指针

C# 中的指针 – 示例 #5

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Pointers
{
class Demo
{
public static void Main()
{
unsafe
{
int* arr = stackalloc int[6];   // declaring array
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;
arr[3] = 40;
arr[4] = 50;
arr[5] = 60;
for (int i = 0; i < 6; i++)
{
Console.WriteLine($"Value at {i}: {arr[i]}");
Console.ReadKey();
}
}
}
}
}

上面的代码中使用了stackalloc关键字,即在栈上分配内存。堆栈块上执行的内存是在方法执行期间创建的。 stackalloc性能更好,而且不需要pin数组。它比堆分配的数组更好,因为不需要释放它,因为它会在方法返回时自动释放。

输出:

C# 中的指针

在指针中,转换有隐式和显式类型。隐式类型转换就像任何指针类型到 void* 类型以及 null 到任何指针类型。在显式类型中,转换是从 byte、sbyte、ushort、short、uint、int、ulong、long 到任何指针类型,反之亦然,以及一个指针到另一个指针。

结论 – C# 中的指针

因此指针用于指向内存地址并使用不安全的语句代码执行它们。它仅在非托管环境中使用,并且不会被垃圾收集器跟踪。指针用于栈、队列等

以上是C# 中的指针的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
上一篇:C# object to dictionary下一篇:C# Literals