1.指针类型声明
类型为referent类型*
的指针变量存储的是类型为referent类型
的固定变量或可移动变量的地址。只有非托管类型可为referent类型
。
任何指针类型可以分配 null
。
//声明未初始化
//比如:byte*、int*、double*、char*.
referent类型* 指针变量;
//p 是指向整数的指针。
int* p;
//p 是指向整数的指针的指针。
int** p;
//p 是指向整数的指针的一维数组。
int*[] p;
//p 是指向字符的指针。
char* p;
//p 是指向未知类型的指针。
//允许但不推荐
void* p;
2.继承
指针类型没有从 System.Object 继承。
3.类型转换
指针类型与 System.Object 之间不存在转换。
任何指针类型都可以隐式转换为 void*
类型。任何指针类型可以使用强制转换表达式显式转换为任何其它指针类型。
任何整数类型可以显式转换为指针类型,或将任何指针类型显式转换为整数类型。
4.装箱(Boxing)和取消装箱(Unboxing)
指针类型不支持装箱与取消装箱。
5.函数指针(Function pointer)
可以使用 delegate*
语法定义函数指针。需在 unsafe
上下文中使用。
可以调用采用 delegate*
(或返回 delegate*
)的方法。
//第一种方法使用 System.Func<T1,T2,TResult> 委托类型。
public static T Combine<T>(Func<T, T, T> combinator, T left, T right) =>
combinator(left, right);
// 第二种方法使用具有相同参数和返回类型的 delegate* 声明。
public static T UnsafeCombine<T>(delegate*<T, T, T> combinator, T left, T right) =>
combinator(left, right);
只可在 static
函数上使用 &
运算符获取函数的地址。(此规则适用于成员函数和本地函数)。
static int localMultiply(int x, int y) => x * y;
int product = UnsafeCombine(&localMultiply, 3, 4);
6.unsafe关键字
unsafe
关键字表示不安全上下文,任何带指针的运算都需要使用 unsafe
上下文。
若要编译不安全代码,必须指定 AllowUnsafeBlocks 编译器选项。不能通过公共语言运行时验证不安全代码。
如果在类型或成员的声明中使用 unsafe
修饰符,则类型或成员的整个正文范围均被视为不安全上下文。不安全上下文的范围从参数列表到方法的结尾。
//参数包含指针
unsafe static void FastCopy ( byte* ps, byte* pd, int count ) {...}
unsafe static void FastCopy(byte[] src, byte[] dst, int count)
{
//方法体包含指针
}
还可以使用不安全块从而能够使用该块内的不安全代码。
unsafe
{
//代码块包含指针
}
7.&
(获取固定变量的地址)
&
(address-of运算符)用于获取固定变量(驻留在不受垃圾回收器操作影响的存储位置的变量)的地址。
类型A 变量a = 值;
类型A* 指针变量b = &变量a;
8.fixed语句(获取可移动变量的地址)
fixed
语句用于固定可移动变量(驻留在受垃圾回收器影响的存储位置的变量)并获取可移动变量的地址,获取的地址仅在 fixed
语句块中有效。
fixed
语句将为托管(managed)变量设置一个指针(指针为未托管类型),并在该语句的执行过程中“单边锁定”该变量。
fixed
语句可以固定 数组、字符串、固定大小的缓冲区(fixed-size buffer)或变量的地址(对象字段、数组元素)或非托管(unmanaged)变量,还可以固定任何实现了GetPinnableReference
方法的类型。GetPinnableReference
方法必须返回一个未托管(unmanaged)类型的 ref
变量。比如:System.Span<T> 结构和 System.ReadOnlySpan<T>结构。
fixed
语句仅允许存在于不安全上下文中。
在 fixed
语句中初始化的指针为只读变量。 如果想要修改指针值,必须声明第二个指针变量,并修改它。
fixed (byte* ps = srcarray, pd = dstarray)
{
byte* pSourceCopy = ps;
// point to the next element.
pSourceCopy++;
// invalid: cannot modify ps, as it is declared in the fixed statement.
ps++;
}
8.1用于数组
//数组
fixed (double* p = arr) { /*...*/ }
//等同于以下代码
//变量地址(数组元素)
double[] arr = { 0, 1.5, 2.3, 3.4, 4.0, 5.9 };
fixed (double* p = &arr[0]) { /*...*/ }
8.2用于字符串
//字符串
string str = "Hello World";
fixed (char* p = str) { /*...*/ }
//以下语句无效,因为str[0]是char,它是值,不是变量。
fixed (char* p = &str[0]) { /*...*/ }
8.3用于固定大小的缓冲区(Fixed-size buffer)
使用 fixed 语句来创建在数据结构中具有固定大小的数组的缓冲区。当编写与其它语言或平台的数据源进行互操作的方法时,固定大小的缓冲区很有用。 固定的数组可以采用允许用于常规结构成员的任何特性或修饰符。 唯一的限制是数组类型必须为 bool
、byte
、char
、short
、int
, long
、sbyte
、ushort
、uint
、ulong
、float
或 double
。
private fixed char name[30];
8.4用于变量地址
//变量地址(对象字段)
class Point
{
public int x;
public int y;
}
unsafe private static void ModifyFixedStorage()
{
Point pt = new Point();
fixed (int* p = &pt.x)
{
*p = 1;
}
}
9.*
(获取指针指向的变量)
*
(指针间接运算符,又称”取消引用运算符“)用于获取指针指向的变量,操作数必须是指针类型。
类型A 变量a = 值;
类型A* 指针变量b = &变量a;
*指针变量b = 新值;
原创文章,作者:huoxiaoqiang,如若转载,请注明出处:https://www.huoxiaoqiang.com/csharp/csharplang/14048.html