ポインタは、別の変数のメモリ アドレスを含む変数として定義されます。 C# のポインターは、安全でないステートメントがあり、安全でないキーワードでマークされている場合に使用されます。これらのタイプのステートメントはガベージ コレクターの制御下になく、ポインター変数を使用します。
構文: ポインターは
として宣言できます。type *var name; int* a;
ここで * は逆参照演算子と呼ばれ、a は int 型のアドレスを含む変数です。
例
int *p = & x; // where &x is the memory address of x Console.WriteLine((int)p) // displaying memory address Console.WriteLine(*p) // displaying value at memory address
以下は、C# でどのように機能するかを示す例です。
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Pointers { class Demo { public void Method() { unsafe { int a = 40; int b = 20; int* ptr1 = &a; int* ptr2 = &b; Console.WriteLine(*ptr1); // displaying the value Console.WriteLine(*ptr2); // displaying the value Console.WriteLine((int)ptr1); // displaying the address Console.WriteLine((int)ptr2); // displaying the address } } } class Example { // main method public static void Main() { Demo d = new Demo(); d.Method(); } } }
モディファイアやコンストラクターなど、ステートメントを安全でないとして実行するにはさまざまな方法があります。上記の例では、ステートメントのグループが安全でないとしてマークされています。上記のコードには、それぞれ値 40 と 20 を持つ 2 つの変数 a と b があり、ポインタにはそれらのアドレスが含まれています。 Console.WriteLine() は、変数の値とアドレスを表示するために使用されます。
出力:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Pointers { class Demo { public unsafe void Method() { int a = 50; int b = 20; int* ptr1 = &a; int* ptr2 = &b; Console.WriteLine(*ptr1); // displaying the value Console.WriteLine(*ptr2); // displaying the value Console.WriteLine((int)ptr1); // displaying the address Console.WriteLine((int)ptr2); // displaying the address } } class Example { // main method public static void Main() { Demo d = new Demo(); d.Method(); } } }
上記の例では、値がそれぞれ 50 と 20 である 2 つの変数 a と b を持つメソッドで unsafe が使用されています。ポインタ *ptr1 と *ptr2 はメモリ アドレスを指します。
出力:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Pointers { class Demo { public unsafe static void Main() { int[] array = { 10, 20, 30, 40, 50 }; // declaring array fixed (int* ptr = array) // fixed for pinning the object /* let us have array address in pointer */ for (int i = 0; i < 5; i++) { Console.WriteLine("Value of array[{0}]={1}", i, *(ptr + i)); Console.WriteLine("Address of array[{0}]={1}", i, (int)(ptr + i)); Console.ReadKey(); } } } }
上記のコードでは、5 つの要素からなる配列が定義されており、Console.WriteLine() を使用して配列要素の値と配列要素のアドレスを表示しています。 C# には、オブジェクトのピン留めとして知られる概念があります。上記のコードでは、ガベージ コレクターがオブジェクトを移動して「固定」しないように、オブジェクトの固定に固定ステートメントが使用されています。実行時の効率に影響を与える可能性があります。
出力:
using System; namespace Pointers { // Struct employee struct Employee { // members // employee id and salary public int empid; public double salary; // Constructor to initialize values public Employee(int e, double s) { empid = e; salary = s; } }; // end of struct class Program { // Main Method static void Main(string[] args) { // unsafe so as to use pointers unsafe { // Declaring two employee Variables Employee E1 = new Employee(798, 30000); Employee E2 = new Employee(799, 31000); // Declaring two employee pointers // and initializing them with addresses // of E1 and E2 Employee* E1_ptr = &E1; Employee* E2_ptr = &E2; // Displaying details of employees using pointers // Using the arrow ( -> ) operator Console.WriteLine("Details of Employee 1"); Console.WriteLine("Employee Id: {0} Salary: {1}", E1_ptr->empid, E1_ptr->salary); Console.WriteLine("Details of Employee 2"); Console.WriteLine("Employee Id: {0} Salary: {1}", E2_ptr->empid, E2_ptr->salary); } // end unsafe } // end main } // end class }
上記の例では、メンバーの従業員 ID と給与を含む従業員構造体を作成し、コンストラクターをパラメーター化して値を初期化します。ポインタは、参照型を含む構造体ではなく、プリミティブ値型を含む構造体を指します。 main メソッドには、アドレス E1 と E2 で初期化される 2 つの従業員変数と従業員ポインターがあります。 Console.WriteLine() は、ポインターを使用して従業員の詳細を表示するために使用されます。
出力:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Pointers { class Demo { public static void Main() { unsafe { int* arr = stackalloc int[6]; // declaring array arr[0] = 10; arr[1] = 20; arr[2] = 30; arr[3] = 40; arr[4] = 50; arr[5] = 60; for (int i = 0; i < 6; i++) { Console.WriteLine($"Value at {i}: {arr[i]}"); Console.ReadKey(); } } } } }
上記のコードでは、スタックにメモリを割り当てる stackalloc キーワードが使用されています。スタックのブロック上で実行されるメモリは、メソッドの実行中に作成されます。 stackalloc はパフォーマンスが優れており、配列を固定する必要がありません。メソッドが返されるときに自動的に解放されるため、解放する必要がないため、ヒープに割り当てられた配列よりも優れています。
出力:
ポインターでは、変換は暗黙的および明示的な型になります。暗黙的な型の変換は、 void* 型へのポインター型や、任意のポインター型への null と似ています。明示的な型では、byte、sbyte、ushort、short、uint、int、ulong、long から任意のポインター型への変換、またはその逆、および 1 つのポインターから別のポインターへの変換が行われます。
そのため、ポインタはメモリ アドレスを指し、安全でないステートメント コードで実行するために使用されます。これは管理されていない環境でのみ使用され、ガベージ コレクターによって追跡されません。ポインタはスタック、キューなどで使用されます。
以上がC# のポインターの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。