C# 中的指针
C# 允许在标记为 unsafe
修饰符的功能或代码块中使用指针变量。unsafe
代码或非托管代码是指使用指针变量的代码块。
注意:为了在 codingground 上执行本章中的程序,请在 Project >> Compile Options >> Compilation Command 中设置编译选项为 mcs *.cs -out:main.exe -unsafe
指针
指针是一个变量,它的值是另一个变量的地址,即内存位置的直接地址。如同任何变量或常量一样,在使用它存储任何变量地址之前,必须声明一个指针。
指针声明的一般形式是:
type *var-name;
以下是有效的指针声明:
int *ip;
double *dp;
float *fp;
char *ch;
下面的例子演示了如何在 C# 中使用 unsafe
修饰符来使用指针:
using System;
namespace UnsafeCodeApplication {
class Program {
static unsafe void Main(string[] args) {
int var = 20;
int* p = &var;
Console.WriteLine("Data is: {0} ", var);
Console.WriteLine("Address is: {0}", (int)p);
Console.ReadKey();
}
}
}
当上述代码被编译和执行时,它产生如下结果:
Data is: 20
Address is: 99215364
除了声明整个方法为 unsafe
外,你还可以声明部分代码为 unsafe
。下面的示例展示了这一点。
通过指针获取数据值
你可以使用 ToString()
方法来获取存储在指针变量所指向的位置的数据。下面的例子演示了这一点:
using System;
namespace UnsafeCodeApplication {
class Program {
public static void Main() {
unsafe {
int var = 20;
int* p = &var;
Console.WriteLine("Data is: {0} " , var);
Console.WriteLine("Data is: {0} " , p->ToString());
Console.WriteLine("Address is: {0} " , (int)p);
}
Console.ReadKey();
}
}
}
当上述代码被编译和执行时,它产生如下结果:
Data is: 20
Data is: 20
Address is: 77128984
将指针作为方法参数传递
你可以将指针变量作为参数传递给方法。下面的例子演示了这一点:
using System;
namespace UnsafeCodeApplication {
class TestPointer {
public unsafe void swap(int* p, int *q) {
int temp = *p;
*p = *q;
*q = temp;
}
public unsafe static void Main() {
TestPointer p = new TestPointer();
int var1 = 10;
int var2 = 20;
int* x = &var1;
int* y = &var2;
Console.WriteLine("Before Swap: var1:{0}, var2: {1}", var1, var2);
p.swap(x, y);
Console.WriteLine("After Swap: var1:{0}, var2: {1}", var1, var2);
Console.ReadKey();
}
}
}
当上述代码被编译和执行时,它产生如下结果:
Before Swap: var1: 10, var2: 20
After Swap: var1: 20, var2: 10
使用指针访问数组元素
在 C# 中,数组名和指向与数组数据相同类型的数据的指针并不是相同的变量类型。例如,int *p
和 int[] p
并不是同一种类型。你可以递增指针变量 p
因为它不是固定在内存中的,但是数组地址在内存中是固定的,因此不能递增。
因此,如果你想使用指针变量来访问数组数据,就像我们在 C 或 C++ 中传统上所做的那样(请检查:C 指针),你需要使用 fixed
关键字来固定这个指针。
下面的例子演示了这一点:
using System;
namespace UnsafeCodeApplication {
class TestPointer {
public unsafe static void Main() {
int[] list = {10, 100, 200};
fixed(int *ptr = list)
for ( int i = 0; i < 3; i++) {
Console.WriteLine("Address of list[{0}]={1}",i,(int)(ptr + i));
Console.WriteLine("Value of list[{0}]={1}", i, *(ptr + i));
}
Console.ReadKey();
}
}
}
当上述代码被编译和执行时,它产生如下结果:
Address of list[0] = 31627168
Value of list[0] = 10
Address of list[1] = 31627172
Value of list[1] = 100
Address of list[2] = 31627176
Value of list[2] = 200
编译 unsafe
代码
对于编译 unsafe
代码,你需要在命令行编译器中指定 /unsafe
命令行开关。
例如,要编译一个含有 unsafe
代码的名为 prog1.cs
的程序,从命令行输入命令:
csc /unsafe prog1.cs
如果你正在使用 Visual Studio IDE,则需要在项目属性中启用 unsafe
代码的使用。
为此,请执行以下操作:
-
在解决方案资源管理器中双击属性节点以打开项目属性。
-
-