ポインタ変数
C# では、ポインターも変数ですが、その値は別の変数のメモリ アドレスです。ポインターを使用する前に、ポインターを宣言する必要もあります。ポインターを宣言する構文は次のとおりです。
type* var_name;
次の表に、ポインターを定義する例をいくつか示します。
例 | 説明する |
---|---|
int*p | p は整数へのポインタです |
double*p | p は double へのポインタです |
float*p | p は浮動小数点数へのポインタです |
int**p | p は整数へのポインタへのポインタです |
int*[]p | p は整数へのポインタの 1 次元配列です。 |
char*p | は文字へのポインタです |
void*p | p は未知の型へのポインタです |
変数の宣言と同じように、次のように 1 行のコードで複数のポインターを宣言することもできます。
int* p1, p2, p3;
注: ポインタ型はオブジェクトから継承できず、ボックス化とアンボックス化はポインタをサポートしませんが、異なるポインタ型間およびポインタと整数の間の変換は可能です。
[例] 次の例は、C# での安全でないキーワードとポインターの使用を示しています。
using System;
namespace it-kiso.com
{
class Demo
{
static unsafe void Main(string[] args)
{
double f = 3.1415;
double* p = &f;
Console.WriteLine("データの内容は: {0} ", f);
Console.WriteLine("データのメモリアドレスは: {0}", (int)p);
Console.ReadKey();
}
}
}
操作の結果は次のようになります。
データの内容は:
3.1415データのメモリアドレスは:
11530344
ヒント: 上記のコードをコンパイルするときは、コンパイル コマンドに-unsafe
を追加する必要があります ( csc -unsafe demo.cs
など)。
ポインタを引数として関数に渡します
次の例に示すように、ポインター変数をパラメーターとして関数に渡すことができます。
use System;
namespace it-kiso.com
{
class Demo
{
public unsafe void swap(int* p, int *q)
{
int temp = *p;
*p = *q;
*q = temp;
}
public unsafe static void Main()
{
Demo p = new Demo();
int var1 = 10;
int var2 = 20;
int* x = &var1;
int* y = &var2;
Console.WriteLine("Swap 関数呼び出し前: var1:{0}, var2: {1}", var1, var2);
p.swap(x, y);
Console.WriteLine("Swap 関数呼び出し後: var1:{0}, var2: {1}", var1, var2);
Console.ReadKey();
}
}
}
操作の結果は次のようになります。
Swap 関数呼び出し前:
var1:10, var2: 20Swap 関数呼び出し後:
var1:20, var2: 10
ポインタを使用して配列要素にアクセスする
C# では、配列と、配列と同じ名前の配列を指すポインターは、異なる種類のデータです。たとえば、 int* p
とint[] p
は、異なる種類のデータです。ポインタ変数 p の値はメモリ内に固定されていないためインクリメントできますが、配列アドレスはメモリ内に固定されているため、配列 p の値をインクリメントすることはできません。配列データにアクセスするためにポインター変数を使用する必要がある場合は、C または C++ で行うのと同じように、fixed キーワードを使用してポインターを固定できます。例を示してみましょう:
using System;
namespace it-kiso.com
{
class Demo
{
public unsafe static void Main()
{
int[] list = { 10, 100, 200 };
fixed(int *ptr = list)
/* ポインター中の配列のアドレスを表示する */
for (int i = 0; i < 3; i++)
{
Console.WriteLine("list[{0}] のメモリーアドレスは:{1}", i, (int)(ptr + i));
Console.WriteLine("list[{0}] の値は:{1}", i, *(ptr + i));
}
Console.ReadKey();
}
}
}
操作の結果は次のようになります。
list[0] のメモリーアドレスは:
51981272
list[0] の値は:
10
list[1] のメモリーアドレスは:
51981276
list[1] の値は:
100
list[2] のメモリーアドレスは:
51981280
list[2] の値は:
200
安全でないコードをコンパイルするには、コンパイル時にunsafe
コマンドを使用する必要があります。たとえば、安全ではないコードを含む demo.cs プログラムをコンパイルするコマンドは次のとおりです。
csc /unsafe demo.cs
或
csc -unsafe demo.cs
Visual Studio を使用している場合は、プロジェクトのプロパティで安全でないコードを有効にする必要があります。具体的な手順は次のとおりです。
- ソリューション エクスプローラーでプロパティ ノードをダブルクリックして、プロジェクトのプロパティを開きます。
- 「ビルド」タブをクリックします。
- 「安全でないコードを許可する」オプションを選択します。