Zeiger werden als Variable definiert, die die Speicheradresse einer anderen Variablen enthält. Zeiger in C# werden immer dann verwendet, wenn eine Anweisung unsicher ist und mit dem Schlüsselwort „unsafe“ gekennzeichnet ist. Diese Arten von Anweisungen unterliegen nicht der Kontrolle von Garbage Collectors und verwenden Zeigervariablen.
Syntax: Zeiger können als
deklariert werdentype *var name; int* a;
Hier wird * als Dereferenzierungsoperator bezeichnet und a ist die Variable, die die Adresse vom Typ int enthält.
Beispiel
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
Im Folgenden finden Sie Beispiele, die zeigen, wie es in C# funktioniert.
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(); } } }
Es gibt verschiedene Möglichkeiten, Anweisungen als unsicher auszuführen, z. B. einen Modifikator, einen Konstruktor usw. Im obigen Beispiel wird eine Gruppe von Anweisungen als unsicher markiert. Im obigen Code gibt es zwei Variablen a und b mit den Werten 40 bzw. 20 und Zeiger enthalten ihre Adressen. Console.WriteLine() wird verwendet, um die Werte und Adressen der Variablen anzuzeigen.
Ausgabe:
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(); } } }
Im obigen Beispiel wird unsicher mit der Methode verwendet, die zwei Variablen a und b mit den Werten 50 bzw. 20 hat. Die Zeiger *ptr1 und *ptr2 zeigen auf ihre Speicheradressen.
Ausgabe:
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(); } } } }
Im obigen Code wird ein Array definiert, das aus fünf Elementen besteht, und Console.WriteLine() wird verwendet, um den Wert von Array-Elementen und die Adresse der Array-Elemente anzuzeigen. In C# gibt es ein Konzept, das als „Pinning eines Objekts“ bezeichnet wird. Im obigen Code wird eine feste Anweisung zum Anheften von Objekten verwendet, damit der Garbage Collector das Objekt nicht verschieben und „anheften“ kann. Dies kann die Laufzeiteffizienz beeinträchtigen.
Ausgabe:
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 }
Im obigen Beispiel ist die Mitarbeiterstruktur mit den Mitgliedern Mitarbeiter-ID und Gehalt versehen und der Konstruktor parametrisiert, um die Werte zu initialisieren. Zeiger verweisen auf Strukturen, die einen primitiven Werttyp enthalten, anstatt auf Strukturen, die einen Referenztyp enthalten. In der Hauptmethode gibt es zwei Mitarbeitervariablen und Mitarbeiterzeiger, die mit den Adressen E1 und E2 initialisiert werden. Console.WriteLine() wird verwendet, um die Details des Mitarbeiters mithilfe von Zeigern anzuzeigen.
Ausgabe:
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(); } } } } }
Im obigen Code wird das Schlüsselwort stackalloc verwendet, mit dem Speicher auf dem Stapel zugewiesen wird. Der auf dem Stapelblock ausgeführte Speicher wird während der Methodenausführung erstellt. stackalloc bietet eine bessere Leistung und es ist nicht erforderlich, das Array anzuheften. Es ist besser als das Heap-zugewiesene Array, da es nicht freigegeben werden muss, da es automatisch freigegeben wird, wenn die Methode zurückkehrt.
Ausgabe:
In Zeigern sind Konvertierungen impliziter und expliziter Art. Ein impliziter Konvertierungstyp ist wie jeder Zeigertyp in den Typ void* und null in einen beliebigen Zeigertyp. Im expliziten Typ erfolgt die Konvertierung von Byte, Sbyte, Ushort, Short, Uint, Int, Ulong, Long in einen beliebigen Zeigertyp oder umgekehrt und von einem Zeiger auf einen anderen Zeiger.
Daher werden Zeiger verwendet, um auf Speicheradressen zu verweisen und sie mit einem unsicheren Code von Anweisungen auszuführen. Es wird nur in einer nicht verwalteten Umgebung verwendet und vom Garbage Collector nicht verfolgt. Zeiger werden in einem Stapel, einer Warteschlange usw. verwendet.
Das obige ist der detaillierte Inhalt vonZeiger in C#. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!