İşaretçiyle ilgili işleçler - değişkenlerin adresini alır, depolama konumlarını geri alır ve bellek konumlarına erişin

İşaretçi işleçleri bir değişkenin adresini (& ) almanıza, bir işaretçiye başvurmamanıza (* ), işaretçi değerlerini karşılaştırmanıza ve işaretçilerle tamsayıları eklemenize veya çıkarmanıza olanak tanır.

İşaretçilerle çalışmak için aşağıdaki işleçleri kullanırsınız:

İşaretçi türleri hakkında bilgi için bkz . İşaretçi türleri.

Not

İşaretçileri olan herhangi bir işlem güvenli olmayan bir bağlam gerektirir. Güvenli olmayan bloklar içeren kod AllowUnsafeBlocks derleyici seçeneğiyle derlenmelidir.

İşlecin adresi &

Birli & işleç işleneninin adresini döndürür:

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

İşlecin işleneni & sabit bir değişken olmalıdır. Sabit değişkenler, atık toplayıcının işleminden etkilenmeyen depolama konumlarında bulunan değişkenlerdir. Yukarıdaki örnekte, yerel değişken number yığında bulunduğundan sabit bir değişkendir. Çöp toplayıcıdan etkilenebilen depolama konumlarında bulunan değişkenlere (örneğin, yeniden konumlandırılmış) taşınabilir değişkenler denir. Nesne alanları ve dizi öğeleri taşınabilir değişkenlere örnektir. Bir deyimiyle fixed"düzeltir" veya "sabitlerseniz" taşınabilir değişkenin adresini alabilirsiniz. Alınan adres yalnızca bir fixed deyiminin bloğu içinde geçerlidir. Aşağıdaki örnekte deyimi fixed ve işlecinin nasıl kullanılacağı gösterilmektedir & :

unsafe
{
    byte[] bytes = { 1, 2, 3 };
    fixed (byte* pointerToFirst = &bytes[0])
    {
        // The address stored in pointerToFirst
        // is valid only inside this fixed statement block.
    }
}

Bir sabitin veya değerin adresini alamazsınız.

Sabit ve taşınabilir değişkenler hakkında daha fazla bilgi için C# dil belirtiminin Sabit ve taşınabilir değişkenler bölümüne bakın.

İkili & işleç, Boole işlenenlerinin mantıksal AND'sini veya integral işlenenlerinin bit düzeyinde mantıksal AND'sini hesaplar.

İşaretçi dolaylı işleci *

Birli işaretçi dolaylı işleci * , işlenen noktalarının bulunduğu değişkeni alır. Başvuru kaldırma işleci olarak da bilinir. İşlecin işleneni * işaretçi türünde olmalıdır.

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

işlecini * türünde void*bir ifadeye uygulayamazsınız.

İkili * işleç, sayısal işlenenlerinin çarpımını hesaplar.

İşaretçi üyesi erişim işleci ->

işleci, -> işaretçi dolaylı veüye erişimini birleştirir. Yani, türün işaretçisiyse ve y türünün T*Terişilebilir bir üyesiysex, formun bir ifadesidir

x->y

eşdeğerdir

(*x).y

Aşağıdaki örnekte işlecin kullanımı gösterilmektedir -> :

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)
    }
}

işlecini -> türünde void*bir ifadeye uygulayamazsınız.

İşaretçi öğesi erişim işleci []

İşaretçi türündeki bir ifade p için, formun p[n] işaretçi öğesi erişimi olarak *(p + n)değerlendirilir; burada n , , uintlongveya ulongiçin intörtük olarak dönüştürülebilir bir tür olmalıdır. İşlecin işaretçilerle davranışı + hakkında bilgi için, işaretçiye veya işaretçiden integral değeri ekleme veya çıkarma bölümüne bakın.

Aşağıdaki örnek, bir işaretçi ve işleç ile dizi öğelerine nasıl erişeceklerini [] gösterir:

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

Yukarıdaki örnekte, bir stackalloc ifade yığında bir bellek bloğu ayırır.

Not

İşaretçi öğesi erişim işleci, sınır dışı hataları denetlemez.

türünde void*bir ifadeyle işaretçi öğesi erişimi için kullanamazsınız[].

Dizi öğesi veya dizin oluşturucu erişimi için işlecini de kullanabilirsiniz[].

İşaretçi aritmetik işleçleri

İşaretçilerle aşağıdaki aritmetik işlemleri gerçekleştirebilirsiniz:

  • İşaretçiye tamsayı değeri ekleme veya işaretçiden çıkarma
  • İki işaretçiyi çıkarma
  • İşaretçiyi artırma veya azaltma

Türünde işaretçilerle void*bu işlemleri gerçekleştiremezsiniz.

Sayısal türlerle desteklenen aritmetik işlemler hakkında bilgi için bkz . Aritmetik işleçler.

İşaretçiye veya işaretçiden integral değeri ekleme veya çıkarma

Türün işaretçisi p ve örtük olarak , , longveya ulong, uinttoplama ve çıkarma için intörtük olarak dönüştürülebilir bir tür ifadesi n için aşağıdaki gibi T* tanımlanır:

  • Hem hem n + p de p + n ifadeleri, tarafından pverilen adrese eklenmesinden n * sizeof(T) kaynaklanan bir tür T* işaretçisi oluşturur.
  • ifadesip - n, tarafından pverilen adresten çıkarılarak n * sizeof(T) elde edilen türde T* bir işaretçi oluşturur.

işleci sizeof bir türün boyutunu bayt cinsinden alır.

Aşağıdaki örnekte bir işaretçi ile işleç kullanımı gösterilmektedir + :

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

İşaretçi çıkarması

İki işaretçi p1 ve p2 türünde T*ifade p1 - p2 , tarafından p1 verilen ve p2 ile ile bölünen sizeof(T)adresler arasındaki farkı üretir. Sonucun türü şeklindedir long. Yani, p1 - p2 olarak ((long)(p1) - (long)(p2)) / sizeof(T)hesaplanır.

Aşağıdaki örnek, işaretçi çıkarma işlemini gösterir:

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
}

İşaretçi artırma ve azaltma

++ Artım işleci işaretçi işlenenine 1 ekler. -- Azaltma işleci, işaretçi işleneninden 1 çıkarır.

her iki işleç de iki biçimde desteklenir: sonek (p++ ve p--) ve ön ek (++p ve --p). ve sonucu, işlemden önceki değerinin değeridirp.p++p-- ve sonucu, işlemden sonraki değerinin değeridirp.++p--p

Aşağıdaki örnekte hem sonek hem de ön ek artım işleçlerinin davranışı gösterilmektedir:

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

İşaretçi karşılaştırma işleçleri

dahil olmak üzere void*herhangi bir işaretçi türünün işlenenlerini karşılaştırmak için , <>!=, , , <=, ve >= işleçlerini kullanabilirsiniz==. Bu işleçler, iki işlenen tarafından verilen adresleri, imzalanmamış tamsayılar gibi karşılaştırır.

Diğer türlerin işlenenleri için bu işleçlerin davranışı hakkında bilgi için, Eşitlik işleçleri ve Karşılaştırma işleçleri makalelerine bakın.

İşleç önceliği

Aşağıdaki liste, işaretçiyle ilgili işleçleri en yüksek önceliğe en düşükten başlayarak sıralar:

  • Sonek artırma x++ ve azaltma x-- işleçleri ile -> ve [] işleçleri
  • Önek artırma ++x ve azaltma --x işleçleri ile & ve * işleçleri
  • Ekleme + ve - işleçler
  • Karşılaştırma <, >, <=ve >= işleçleri
  • Eşitlik == ve != işleçler

İşleç önceliği tarafından uygulanan değerlendirme sırasını değiştirmek için parantezleri ()kullanın.

Öncelik düzeyine göre sıralanmış C# işleçlerinin tam listesi için C# işleçleri makalesinin İşleç önceliği bölümüne bakın.

İşleç aşırı yüklenebilirliği

Kullanıcı tanımlı bir tür, işaretçiyle ilgili işleçleri , , *->ve []aşırı &yükleyemez.

C# dili belirtimi

Daha fazla bilgi için C# dil belirtiminin aşağıdaki bölümlerine bakın:

Ayrıca bkz.