Jegyzet
Az oldalhoz való hozzáférés engedélyezést igényel. Próbálhatod be jelentkezni vagy könyvtárat váltani.
Az oldalhoz való hozzáférés engedélyezést igényel. Megpróbálhatod a könyvtár váltását.
A mutató operátorai lehetővé teszik a változók címét (&), a mutató elhalasztását (*), a mutatóértékek összehasonlítását, valamint a mutatók és egész számok hozzáadását vagy kivonását.
A C# nyelv referenciadokumentuma a C# nyelv legújabb kiadású verzióját ismerteti. Emellett a közelgő nyelvi kiadás nyilvános előzetes verziójú funkcióinak kezdeti dokumentációját is tartalmazza.
A dokumentáció azonosítja azokat a funkciókat, amelyeket először a nyelv utolsó három verziójában vagy az aktuális nyilvános előzetes verziókban vezetnek be.
Jótanács
Ha meg szeretné tudni, hogy mikor jelent meg először egy funkció a C#-ban, tekintse meg a C# nyelvi verzióelőzményeiről szóló cikket.
A következő operátorokkal dolgozhat a mutatókkal:
- Unary
&(address-of) operátor: egy változó címének lekéréséhez - Unary
*(pointer indirection) operátor: a változó mutatóval való rámutatásához - A
->(taghozzáférés) és[](elemhozzáférés) operátorok - Számtani operátorok
+,-,++és-- - Összehasonlító operátorok
==,!=,<,>,<=és>=
A mutatótípusokról további információt a Mutatótípusok című témakörben talál.
Feljegyzés
A mutatókkal végzett műveletekhez nem biztonságos környezet szükséges. A nem biztonságos blokkokat tartalmazó kódot az AllowUnsafeBlocks fordítóbeállítással kell lefordítania.
Operátor címe >
A unary & operátor az operandus címét adja vissza:
unsafe
{
int number = 27;
int* pointerToNumber = &number;
Console.WriteLine($"Value of the variable: {number}");
Console.WriteLine($"Address of the variable: {(long)pointerToNumber:X}");
}
// Output is similar to:
// Value of the variable: 27
// Address of the variable: 6C1457DBD4
Az operátor operandusának & rögzített változónak kell lennie.
A rögzített változók olyan változók, amelyek olyan tárolóhelyeken találhatók, amelyekre a szemétgyűjtő nincs hatással. Az előző példában a helyi változó number rögzített változó, mert a veremen található. A szemétgyűjtő által befolyásolható (például áthelyezési) tárolási helyeken található változókat mozgatható változóknak nevezzük. Az objektummezők és a tömbelemek ingó változókra mutatnak példákat. Egy ingó változó címét egy utasítássalfixed lekérheti, ha "kijavítja", vagy "kitűzi". A kapott cím csak az utasításblokkon fixed belül érvényes. Az alábbi példa egy utasítás és az fixed operátor használatát & mutatja be:
unsafe
{
byte[] bytes = { 1, 2, 3 };
fixed (byte* pointerToFirst = &bytes[0])
{
// The address stored in pointerToFirst
// is valid only inside this fixed statement block.
}
}
Állandó vagy érték címét nem lehet lekérni.
A rögzített és mozgatható változókkal kapcsolatos további információkért lásd a C# nyelvspecifikáció Rögzített és mozgatható változók szakaszát.
A bináris & operátor kiszámítja a logikai és logikai operandusok és a bitenkénti logikai ÉS az integrál operandusok logikai ÉS logikai számításait.
Mutató indirekt operátora *
A nem mutató indirekt operátor * hozzáfér ahhoz a változóhoz, amelyhez az operandusa rámutat. Dereference operátornak is nevezik. Az operátor operandusának * mutató típusúnak kell lennie.
unsafe
{
char letter = 'A';
char* pointerToLetter = &letter;
Console.WriteLine($"Value of the `letter` variable: {letter}");
Console.WriteLine($"Address of the `letter` variable: {(long)pointerToLetter:X}");
*pointerToLetter = 'Z';
Console.WriteLine($"Value of the `letter` variable after update: {letter}");
}
// Output is similar to:
// Value of the `letter` variable: A
// Address of the `letter` variable: DCB977DDF4
// Value of the `letter` variable after update: Z
Az operátor nem alkalmazható * típuskifejezésre void*.
A bináris * operátor kiszámítja a numerikus operandusok szorzatát .
Mutatótag-hozzáférési operátor ->
Az -> operátor egyesíti a mutató indirekt ésa tagok hozzáférését. Ha x egy mutató típusú T* , és y a típus Takadálymentes tagja, az űrlap kifejezése
x->y
egyenértékű a
(*x).y
Az alábbi példa az operátor használatát -> mutatja be:
public struct Coords
{
public int X;
public int Y;
public override string ToString() => $"({X}, {Y})";
}
public class PointerMemberAccessExample
{
public static unsafe void Main()
{
Coords coords;
Coords* p = &coords;
p->X = 3;
p->Y = 4;
Console.WriteLine(p->ToString()); // output: (3, 4)
}
}
Az operátor nem használható -> típuskifejezésen void*.
Mutatóelem-hozzáférési operátor []
Egy mutató típusú kifejezés p esetében az űrlap p[n] mutatóelem-hozzáférése a következőképpen lesz kiértékelve *(p + n). Az értéknek n implicit módon átalakíthatónak intkell lennie , uintvagy longulong. A mutatókkal rendelkező operátor viselkedésével + kapcsolatos információkért tekintse meg az integrálértékek összeadását vagy kivonását egy mutatószakaszba vagy abból.
Az alábbi példa bemutatja, hogyan érheti el a tömbelemeket egy mutató és egy [] operátor használatával:
unsafe
{
char* pointerToChars = stackalloc char[123];
for (int i = 65; i < 123; i++)
{
pointerToChars[i] = (char)i;
}
Console.Write("Uppercase letters: ");
for (int i = 65; i < 91; i++)
{
Console.Write(pointerToChars[i]);
}
}
// Output:
// Uppercase letters: ABCDEFGHIJKLMNOPQRSTUVWXYZ
Az előző példában egy stackalloc kifejezés lefoglal egy memóriablokkot a veremen.
Feljegyzés
A mutatóelem hozzáférési operátora nem ellenőrzi a határtalan hibákat.
Nem használható [] mutatóelem-hozzáféréshez típuskifejezéssel void*.
Az operátort [] tömbelemhez vagy indexelőhöz is használhatja.
Mutató aritmetikai operátorai
A következő aritmetikai műveleteket hajthatja végre mutatókkal:
- Integrálérték hozzáadása vagy kivonása mutatóhoz vagy mutatóból
- Két mutató kivonása
- Mutató növelése vagy csökkentése
Ezeket a műveleteket nem lehet ilyen típusú void*mutatókkal végrehajtani.
A numerikus típusokkal végzett támogatott aritmetikai műveletekről az Aritmetikai operátorok című témakörben olvashat bővebben.
Integrálérték hozzáadása vagy kivonása mutatóhoz vagy mutatóból
Egy típusmutató pT* és egy implicit módon átalakítható inttípus kifejezése n esetén az uintlongulongalábbiak szerint lehet összeadási és kivonási munkát végezni:
- Mindkettőt
p + n, ésn + padjon meg egy ilyen típusúT*mutatót. Ezt a mutatót úgy érheti el, hogy hozzáadjan * sizeof(T)azt a címet, amelypa mutatóra mutat. - A
p - nkifejezés típusmutatótT*ad. Ezt a mutatót úgy érheti el, hogypkivonja a mutatótn * sizeof(T)a címből.
Az sizeof operátor bájtban kapja meg a típus méretét.
Az alábbi példa bemutatja, hogyan használhatja az + operátort mutatóval:
unsafe
{
const int Count = 3;
int[] numbers = new int[Count] { 10, 20, 30 };
fixed (int* pointerToFirst = &numbers[0])
{
int* pointerToLast = pointerToFirst + (Count - 1);
Console.WriteLine($"Value {*pointerToFirst} at address {(long)pointerToFirst}");
Console.WriteLine($"Value {*pointerToLast} at address {(long)pointerToLast}");
}
}
// Output is similar to:
// Value 10 at address 1818345918136
// Value 30 at address 1818345918144
Mutató kivonása
Két mutató és típus esetén a kifejezés p1 - p2 megadja a különbséget azoknak a címeknek a között, amelyekre p1p2 mutat, osztva a következővelsizeof(T): .T*p2p1 Az eredmény típusa .long Más szóval a p1 - p2 számítás a ((long)(p1) - (long)(p2)) / sizeof(T)következőképpen történik: .
Az alábbi példa a mutató kivonását mutatja be:
unsafe
{
int* numbers = stackalloc int[] { 0, 1, 2, 3, 4, 5 };
int* p1 = &numbers[1];
int* p2 = &numbers[5];
Console.WriteLine(p2 - p1); // output: 4
}
Mutató növekménye és csökkentése
A ++ növekmény operátor 1-et ad hozzá a mutató operandusához. A -- decrement operátor kivon 1-et a mutató operandusából.
Mindkét operátor két űrlapot támogat: postfix (p++ és p--) és előtag (++p és --p). A művelet eredménye p++ és p-- értéke p. A művelet eredménye ++p és --p értéke p.
Az alábbi példa a postfix és az előtag növekményes operátorainak viselkedését mutatja be:
unsafe
{
int* numbers = stackalloc int[] { 0, 1, 2 };
int* p1 = &numbers[0];
int* p2 = p1;
Console.WriteLine($"Before operation: p1 - {(long)p1}, p2 - {(long)p2}");
Console.WriteLine($"Postfix increment of p1: {(long)(p1++)}");
Console.WriteLine($"Prefix increment of p2: {(long)(++p2)}");
Console.WriteLine($"After operation: p1 - {(long)p1}, p2 - {(long)p2}");
}
// Output is similar to
// Before operation: p1 - 816489946512, p2 - 816489946512
// Postfix increment of p1: 816489946512
// Prefix increment of p2: 816489946516
// After operation: p1 - 816489946516, p2 - 816489946516
Mutató-összehasonlító operátorok
A ==, , !=, <><=, és >= operátorokkal bármilyen mutatótípusú operandusokat összehasonlíthat, beleértve a elemet is.void* Ezek az operátorok úgy hasonlítják össze a két operandus által megadott címeket, mintha aláíratlan egész számok lennének.
Az operátorok más típusú operandusok viselkedéséről az Egyenlőség operátorok és az Összehasonlító operátorok című cikkekben olvashat bővebben.
Operátorok műveleti sorrendje
Az alábbi lista a mutatóval kapcsolatos operátorokat a legmagasabb prioritástól a legalacsonyabbig rendeli:
- A postfix növekményes
x++és decrementx--operátorai, valamint az és->az[]operátorok - Az előtag növekményes
++xés decrement--xoperátorai, valamint az és&az*operátorok - Additív
+és-operátorok - Összehasonlítás
<,>,<=és>=operátorok - Egyenlőség
==és!=operátorok
Zárójelek ()használatával módosíthatja az operátorok elsőbbsége által előírt kiértékelési sorrendet.
A C#-operátorok elsőbbségi szint szerint rendezett teljes listájáért tekintse meg a C# operátorok cikkének Operátorok elsőbbsége című szakaszát.
Operátorok túlterhelése
Nem terhelheti túl a mutatóval kapcsolatos operátorokat&, *->és [] nem terhelheti túl a felhasználó által definiált típusokat.
C# nyelvspecifikáció
További információt a C# nyelvspecifikációjának alábbi szakaszaiban talál:
- Rögzített és áthelyezhető változók
- Az operátor címe
- Mutató indirekt
- Mutatótag-hozzáférés
- Mutatóelem-hozzáférés
- Mutató aritmetikai
- Mutató növekménye és csökkentése
- Mutató összehasonlítása