ポインター型 (C# プログラミング ガイド)Pointer types (C# Programming Guide)

unsafe コンテキストの型には、ポインター型、値型、または参照型を設定できます。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

ポインター型の * の前に指定された型は、参照型と呼ばれます。The type specified before the * in a pointer type is called the referent type. 次の型はいずれも参照型になります。Any of the following types may be a referent type:

ポインター型は object を継承せず、ポインター型と 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.

同じ 1 つの宣言で複数のポインターを宣言する場合、アスタリスク (*) は基底の型だけに記述します。各ポインター名のプレフィックスとしては使用しません。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 は、整数へのポインターの 1 次元配列です。p is a single-dimensional array of pointers to integers.
char* p p は、char へのポインターです。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.

ポインターは、null にできます。A 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. たとえば、inout または ref パラメーターを介してポインターをローカル変数に返したり、関数の結果として返したりするメソッドがあるとします。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.

次の表は、unsafe コンテキストでポインターに使用できる演算子とステートメントの一覧を示しています。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