指针类型(C# 编程指南)Pointer types (C# Programming Guide)

在不安全的上下文中,类型可以是指针类型、值类型或引用类型。In an unsafe context, a type may be a pointer type, a value type, or a reference type. 指针类型声明采用下列形式之一:A pointer type declaration takes one of the following forms:

type* identifier;
void* identifier; //allowed but not recommended

在指针类型中的 * 之前指定的类型被称为“referent 类型” 。The type specified before the * in a pointer type is called the referent type. 只有非托管类型可为引用类型。Only an unmanaged type can be a referent type.

指针类型不从对象继承,并且指针类型与 object 之间不存在转换。Pointer types do not inherit from object and no conversions exist between pointer types and object. 此外,装箱和取消装箱不支持指针。Also, boxing and unboxing do not support pointers. 但是,你可在不同的指针类型之间以及指针类型和整型之间进行转换。However, you can convert between different pointer types and between pointer types and integral types.

在同一个声明中声明多个指针时,星号 (*) 仅与基础类型一起写入;而不是用作每个指针名称的前缀。When you declare multiple pointers in the same declaration, the asterisk (*) is written together with the underlying type only; it is not used as a prefix to each pointer name. 例如:For example:

int* p1, p2, p3;   // Ok
int *p1, *p2, *p3;   // Invalid in C#

指针不能指向引用或包含引用的结构,因为无法对对象引用进行垃圾回收,即使有指针指向它也是如此。A pointer cannot point to a reference or to a struct that contains references, because an object reference can be garbage collected even if a pointer is pointing to it. 垃圾回收器并不跟踪是否有任何类型的指针指向对象。The garbage collector does not keep track of whether an object is being pointed to by any pointer types.

myType* 类型的指针变量的值为 myType 类型的变量的地址。The value of the pointer variable of type myType* is the address of a variable of type myType. 下面是指针类型声明的示例:The following are examples of pointer type declarations:

示例Example 说明Description
int* p p 是指向整数的指针。p is a pointer to an integer.
int** p p 是指向整数的指针的指针。p is a pointer to a pointer to an integer.
int*[] p p 是指向整数的指针的一维数组。p is a single-dimensional array of pointers to integers.
char* p p 是指向字符的指针。p is a pointer to a char.
void* p p 是指向未知类型的指针。p is a pointer to an unknown type.

指针间接寻址运算符 * 可用于访问位于指针变量所指向的位置的内容。The pointer indirection operator * can be used to access the contents at the location pointed to by the pointer variable. 例如,请考虑以下声明:For example, consider the following declaration:

int* myVariable;

表达式 *myVariable 表示在 int 中包含的地址处找到的 myVariable 变量。The expression *myVariable denotes the int variable found at the address contained in myVariable.

fixed 语句指针转换主题中有几个指针示例。There are several examples of pointers in the topics fixed Statement and Pointer Conversions. 下面的示例使用 unsafe 关键字和 fixed 语句,并显示如何递增内部指针。The following example uses the unsafe keyword and the fixed statement, and shows how to increment an interior pointer. 你可将此代码粘贴到控制台应用程序的 Main 函数中来运行它。You can paste this code into the Main function of a console application to run it. 这些示例必须使用 -unsafe 编译器选项集进行编译。These examples must be compiled with the -unsafe compiler option set.

// Normal pointer to an object.
int[] a = new int[5] { 10, 20, 30, 40, 50 };
// Must be in unsafe code to use interior pointers.
unsafe
{
    // Must pin object on heap so that it doesn't move while using interior pointers.
    fixed (int* p = &a[0])
    {
        // p is pinned as well as object, so create another pointer to show incrementing it.
        int* p2 = p;
        Console.WriteLine(*p2);
        // Incrementing p2 bumps the pointer by four bytes due to its type ...
        p2 += 1;
        Console.WriteLine(*p2);
        p2 += 1;
        Console.WriteLine(*p2);
        Console.WriteLine("--------");
        Console.WriteLine(*p);
        // Dereferencing p and incrementing changes the value of a[0] ...
        *p += 1;
        Console.WriteLine(*p);
        *p += 1;
        Console.WriteLine(*p);
    }
}

Console.WriteLine("--------");
Console.WriteLine(a[0]);

/*
Output:
10
20
30
--------
10
11
12
--------
12
*/

你无法对 void* 类型的指针应用间接寻址运算符。You cannot apply the indirection operator to a pointer of type void*. 但是,你可以使用强制转换将 void 指针转换为任何其他指针类型,反之亦然。However, you can use a cast to convert a void pointer to any other pointer type, and vice versa.

指针可以为 nullA pointer can be null. 将间接寻址运算符应用于 null 指针将导致由实现定义的行为。Applying the indirection operator to a null pointer causes an implementation-defined behavior.

在方法之间传递指针会导致未定义的行为。Passing pointers between methods can cause undefined behavior. 考虑这种方法,该方法通过 inoutref 参数或作为函数结果返回一个指向局部变量的指针。Consider a method that returns a pointer to a local variable through an in, out, or ref parameter or as the function result. 如果已在固定块中设置指针,则它指向的变量不再是固定的。If the pointer was set in a fixed block, the variable to which it points may no longer be fixed.

下表列出了可在不安全的上下文中对指针执行的运算符和语句:The following table lists the operators and statements that can operate on pointers in an unsafe context:

运算符/语句Operator/Statement 使用Use
* 执行指针间接寻址。Performs pointer indirection.
-> 通过指针访问结构的成员。Accesses a member of a struct through a pointer.
[] 为指针建立索引。Indexes a pointer.
& 获取变量的地址。Obtains the address of a variable.
++--++ and -- 递增和递减指针。Increments and decrements pointers.
+-+ and - 执行指针算法。Performs pointer arithmetic.
==!=<``><=>===, !=, <, >, <=, and >= 比较指针。Compares pointers.
stackalloc 运算符stackalloc operator 在堆栈上分配内存。Allocates memory on the stack.
fixed 语句fixed statement 临时固定变量以便找到其地址。Temporarily fixes a variable so that its address may be found.

要详细了解与指针相关的运算符,请参阅与指针相关的运算符For more information about pointer related operators, see Pointer related operators.

C# 语言规范C# language specification

有关详细信息,请参阅 C# 语言规范指针类型部分。For more information, see the Pointer types section of the C# language specification.

请参阅See also