# 安全でないコードの紹介
C# では、unsafe
でマークされている場合、コード ブロックの関数でポインター変数を使用できます。 修飾子。アンセーフ コードまたはアンマネージ コードは、ポインター変数を使用するコード ブロックです。
ポインタは、値が別の変数のアドレス、つまりメモリ位置の直接アドレスである変数です。変数や定数と同様に、変数アドレスを格納するために使用する前に、ポインターを宣言する必要があります。
ポインター宣言の一般的な形式は次のとおりです。
type *var-name;
以下は有効なポインタ宣言です:
int *ip; /* pointer to an integer */
double *dp; /* pointer to a double */
float *fp; /* pointer to a float */
char *ch /* pointer to a character */
次の例は、unsafe 修飾子を使用して、C# でポインターを使用する方法を示しています。
using System;
namespace UnsafeCodeApplication
{
class Program
{
static unsafe void Main(string[] args)
{
int var = 20;
int* p = &var;
Console.WriteLine("Data is: {0} ", var);
Console.WriteLine("Address is: {0}", (int)p);
Console.ReadKey();
}
}
}
上記のコードをコンパイルして実行すると、次の結果が生成されます:
Data is: 20
Address is: 99215364
メソッド全体を安全でないと宣言する代わりに、コードの一部を安全でないと宣言することもできます:
// safe code
unsafe
{
// you can use pointers here
}
// safe code
# ポインターを使用して配列要素にアクセスする
C# では、配列名と配列データと同じデータ型へのポインターは、同じ変数型ではありません。例:int *p
と int[] p
、同じタイプではありません。ポインター変数 p
をインクリメントできます メモリ内で固定されていませんが、配列アドレスはメモリ内で固定されており、それをインクリメントすることはできません.
したがって、ポインタ変数を使用して配列データにアクセスする必要がある場合は、C または C++ で伝統的に行っているように、fixed キーワードを使用してポインタを修正する必要があります。
次の例はこれを示しています:
using System;
namespace UnsafeCodeApplication
{
class TestPointer
{
public unsafe static void Main()
{
int[] list = {10, 100, 200};
fixed(int *ptr = list)
/* let us have array address in pointer */
for ( int i = 0; i < 3; i++)
{
Console.WriteLine("Address of list[{0}]={1}",i,(int)(ptr + i));
Console.WriteLine("Value of list[{0}]={1}", i, *(ptr + i));
}
Console.ReadKey();
}
}
}
上記のコードをコンパイルして実行すると、次の結果が生成されます:
Address of list[0] = 31627168
Value of list[0] = 10
Address of list[1] = 31627172
Value of list[1] = 100
Address of list[2] = 31627176
Value of list[2] = 200
# 安全でないコードのコンパイル
安全でないコードをコンパイルするには、 /unsafe
を指定する必要があります コマンドライン コンパイラによるコマンドライン スイッチ。
たとえば、安全でないコードを含む prog1.cs という名前のプログラムをコンパイルするには、コマンド ラインから次のコマンドを実行します。
csc /unsafe prog1.cs
Visual Studio IDE を使用している場合は、プロジェクト プロパティでアンセーフ コードの使用を有効にする必要があります。
これを行うには:
# ポインターを使用したデータ値の取得
ToString() メソッドを使用して、ポインタ変数によって参照される場所に格納されているデータを取得できます。次の例はこれを示しています:
using System;
namespace UnsafeCodeApplication
{
class Program
{
public static void Main()
{
unsafe
{
int var = 20;
int* p = &var;
Console.WriteLine("Data is: {0} " , var);
Console.WriteLine("Data is: {0} " , p->ToString());
Console.WriteLine("Address is: {0} " , (int)p);
}
Console.ReadKey();
}
}
}
上記のコードをコンパイルして実行すると、次の結果が生成されます:
Data is: 20
Data is: 20
Address is: 77128984
# ポインターをパラメーターとしてメソッドに渡す
ポインター変数をパラメーターとしてメソッドに渡すことができます。次の例はこれを示しています:
using System;
namespace UnsafeCodeApplication
{
class TestPointer
{
public unsafe void swap(int* p, int *q)
{
int temp = *p;
*p = *q;
*q = temp;
}
public unsafe static void Main()
{
TestPointer p = new TestPointer();
int var1 = 10;
int var2 = 20;
int* x = &var1;
int* y = &var2;
Console.WriteLine("Before Swap: var1:{0}, var2: {1}", var1, var2);
p.swap(x, y);
Console.WriteLine("After Swap: var1:{0}, var2: {1}", var1, var2);
Console.ReadKey();
}
}
}
上記のコードをコンパイルして実行すると、次の結果が生成されます:
Before Swap: var1: 10, var2: 20
After Swap: var1: 20, var2: 10