ポインター型 (C# プログラミング ガイド)
unsafe コンテキストの型には、ポインター型、値型、または参照型を設定できます。 ポインター型の宣言は、次のいずれかの形式になります。
type* identifier;
void* identifier; //allowed but not recommended
次の型はいずれもポインター型になります。
sbyte、byte、short、ushort、int、uint、long、ulong、char、float、double、decimal、または bool。
任意の列挙型。
任意のポインター型。
アンマネージ型のフィールドのみを含むユーザー定義の struct 型。
ポインター型は 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# プログラミング ガイド)