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

unsafe コンテキストの型には、ポインター型、値型、または参照型を設定できます。 ポインター型の宣言は、次のいずれかの形式になります。

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

次の型はいずれもポインター型になります。

ポインター型は object を継承せず、ポインター型と object 間の変換は存在しません。 また、ボックス化とボックス化解除もポインターをサポートしません。 ただし、異なるポインター型の間で変換したり、ポインター型と整数型の間で変換したりすることはできます。

同じ 1 つの宣言で複数のポインターを宣言する場合、アスタリスク (*) は基底の型だけに記述します。各ポインター名のプレフィックスとしては使用しません。 たとえば、次のようにします。

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

オブジェクト参照は、それを指すポインターがあってもガベージ コレクションされる可能性があるため、ポインターが、参照や参照を含む構造体を指すことはできません。 ガベージ コレクターは、オブジェクトを指すポインター型があるかどうかを追跡しません。

myType* 型のポインター変数の値は、myType 型の変数のアドレスです。 ポインター型の宣言の例を次に示します。

説明

int* p

p は、整数へのポインターです。

int** p

p は、整数へのポインターのポインターです。

int*[] p

p は、整数へのポインターの 1 次元配列です。

char* p

p は、char へのポインターです。

void* p

p は、未知の型へのポインターです。

ポインター間接演算子 * を使用すると、ポインター変数が指す位置にあるコンテンツにアクセスできます。 たとえば、次のような宣言があるとします。

int* myVariable;

この例の式 *myVariable は、myVariable に含まれているアドレスの位置にある int 変数を示しています。

トピック「fixed ステートメント (C# リファレンス)」と「ポインター変換 (C# プログラミング ガイド)」にポインターの例がいくつかあります。次の例は、unsafe キーワードと fixed ステートメントの必要性、および内部ポインターのインクリメント方法を示しています。このコードは、コンソール アプリケーションの Main 関数に貼り付けて実行することができます (プロジェクト デザイナーでアンセーフ コードを有効にすることを忘れないでください。[プロジェクト] を選択し、メニュー バーの [プロパティ] をクリックし、[ビルド] タブで [アンセーフ コードの許可] を選択します)。

// 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);
        // Deferencing 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]);
Console.ReadLine();

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

間接演算子は、void* 型のポインターに適用できません。 ただし、void ポインターと他のポインター型はキャストを使用して相互に変換できます。

ポインターは、null にできます。 null ポインターに間接演算子を適用すると、実装で定義されている動作が発生します。

ポインターをメソッド間で引き渡すと、未定義の動作が発生する可能性があります。 たとえば、Out パラメーターや Ref パラメーターを介してポインターをローカル変数に返したり、関数の結果として返したりする場合です。 ポインターが固定ブロックに設定されていた場合は、そのポインターが指す変数が既に固定されていない可能性があります。

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

演算子/ステートメント

使用方法

*

ポインターの間接参照を実行します。

->

ポインター経由で構造体のメンバーにアクセスします。

[]

ポインターにインデックスを付けます。

&

変数のアドレスを取得します。

++ および --

ポインターをインクリメントおよびデクリメントします。

+ および -

ポインター演算を実行します。

==、!=、<、>、<=、>=

ポインターを比較します。

stackalloc

スタックにメモリを割り当てます。

fixed ステートメント

変数を一時的に固定して、そのアドレスを取得できるようにします。

C# 言語仕様

詳細については、「C# 言語仕様」を参照してください。言語仕様は、C# の構文と使用法に関する信頼性のある情報源です。

参照

関連項目

unsafe コードとポインター (C# プログラミング ガイド)

ポインター変換 (C# プログラミング ガイド)

ポインター式 (C# プログラミング ガイド)

unsafe (C# リファレンス)

fixed ステートメント (C# リファレンス)

stackalloc (C# リファレンス)

ボックス化とボックス化解除 (C# プログラミング ガイド)

概念

C# プログラミング ガイド

その他の技術情報

型 (C# リファレンス)