D.ershane D Programlama Dili Dersleri

aralık: [range], topluluk elemanlarının bir bölümü
dilim: [slice], başka bir dizinin bir bölümüne erişim sağlayan yapı
dizi: [array], elemanları yan yana duran ve indeksle erişilen topluluk
... bütün sözlük

Bölümler
İngilizce Kaynaklar
Diğer



Dilimler ve Aralıklar

Var olan bir dizinin belirli bir bölümüne erişim sağlayan yapıya dilim denir. Dilim sayesinde, var olan başka bir dizinin elemanlarının bir bölümünü, sanki daha küçük ayrı bir diziymiş gibi kullanabiliriz.

Örnek olarak daha önce diziler dersinde gördüğümüz ayGünleri dizisini dörde dilimleyerek birbirinden ayrı dört çeyrek diziymiş gibi şöyle kullanabiliriz:

    int ayGünleri[12] =
        [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ];

    int ilkÇeyrek[]    = ayGünleri[0..3];
    int ikinciÇeyrek[] = ayGünleri[3..6];
    int üçüncüÇeyrek[] = ayGünleri[6..9];
    int sonÇeyrek[]    = ayGünleri[9..12];

O kodda sol taraftaki yapılar dilimdirler ve asıl dizinin dört değişik bölgesine erişim sağlarlar. Burada önemli olan, dilimlerin ayrı diziler olmadıklarıdır; asıl dizinin elemanlarına erişim sağlarlar. Dilimlerin elemanlarında yapılan değişiklikler, asıl diziyi etkiler. Bunu görmek için dört çeyreğe dört farklı değer verebilir ve asıl diziyi yazdırabiliriz:

    ilkÇeyrek[] =    1;
    ikinciÇeyrek[] = 2;
    üçüncüÇeyrek[] = 3;
    sonÇeyrek[] =    4;

    writeln(ayGünleri);
1 1 1 2 2 2 3 3 3 4 4 4

Görüldüğü gibi; dilimde yapılan değişiklik, asıl diziyi değiştirmektedir.

Aralıklar

Aralıklar, topluluk elemanlarını bir başlangıç noktasından bir bitiş noktasına kadar belirlemek için kullanılır. Yan yana iki tane noktanın etrafına yazılan iki değer bir aralık belirler. Aralıkların söz dizimi şöyledir:

  aralığın_başı..aralığın_sonundan_bir_sonrası

Yani .. karakterlerinden önce yazılan değer aralığa dahildir; ama sonra yazılan değer aralığın dışındadır:

... = ayGünleri[0..3];  // 0, 1, ve 2 dahil; 3 hariç
... = ayGünleri[3..6];  // 3, 4, ve 5 dahil; 6 hariç

Aralıkları yazarken bir kolaylık olarak, dizinin .length niteliğini dizi ismi olmadan da yazabilirsiniz. Hatta bunun için $ karakteri bile kullanılabilir:

    int ilkYarısı[] = sayılar[0..sayılar.length/2];
    int ilkYarısı[] = sayılar[0..length/2];
    int ilkYarısı[] = sayılar[0..$/2];

O tanımların üçü de birbirinin eşdeğeridir, ve sayılar dizisinin ilk yarısını bir dilim olarak tanımlar.

Dizilerin .dup niteliği

Bazı durumlarda bir dizinin elemanlarını gösteren dilim kullanmak yerine, o dizinin veya bir aralığının kopyasını almak isteriz. .dup niteliği, dizinin veya aralığın bir kopyasını alır.

Programınızın bir strateji oyununda bir senaryoyu denemek istediğini düşünün. Program, bir grup askeri bir saldırıda kullanarak nasıl bir sonuç çıkacağını görmek istesin. Eğer askerler programda bir dizi olarak tutuluyorlarsa, asıl asker dizisini kullanmak yerine, onların bir kopyasını kullanmak akıllıca olur. Böylece deneme nasıl sonuçlanırsa sonuçlansın, asıl dizideki askerler oldukları gibi kalırlar.

Bir örnek olarak Şubat'ın 29 gün çektiği senelerdeki ayların gün sayılarını tutan bir dizi oluşturmak isteyelim. Bir yöntem, önce ayGünleri'nin bir kopyasını almak ve sonra Şubat ayının gün sayısını bir arttırmaktır:

import std.stdio;

void main()
{
    int ayGünleri[12] =
        [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ];

    int artıkYıl[] = ayGünleri.dup;
    ++artıkYıl[1];

    writeln("Normal yıl: ", ayGünleri);
    writeln("Artık yıl : ", artıkYıl);
}
Normal yıl: 31 28 31 30 31 30 31 31 30 31 30 31
Artık yıl : 31 29 31 30 31 30 31 31 30 31 30 31

Bütün dizinin kopyasını almak yerine bir aralığının kopyası da alınabilir:

    int ilkYarısınınKopyası[] = artıkYıl[0..6].dup;
    writeln(ilkYarısınınKopyası);
31 29 31 30 31 30
Problem
  • Dilimler konusunu çalışan bir öğrencinin yazdığı bir programa bakıyorsunuz:
  • import std.stdio;
    
    void main()
    {
        int sayılar[10] = [ 1, 1, 1, 1, 1, 2, 2, 2, 2, 2 ];
    
        writeln("Önce:  ", sayılar);
    
        // İkinci yarıyı birinci yarıya kopyalıyorum
        sayılar[0..$/2] = sayılar[$/2..$];
    
        // Birinci yarıyı da ikinci yarıya kopyalıyorum
        sayılar[$/2..$] = sayılar[0..$/2];
    
        writeln("Sonra: ", sayılar);
    }
    

    Öğrenci sonuçta dizinin birinci yarısıyla ikinci yarısını değiştirmek istemiş, ama programın çıktısı yanlış oluyor:

    Önce:  1 1 1 1 1 2 2 2 2 2
    Sonra: 2 2 2 2 2 2 2 2 2 2    ← YANLIŞ
    

    Pogramın doğru olarak çalışmasını sağlayın; çıktısı şöyle olsun:

    Önce:  1 1 1 1 1 2 2 2 2 2
    Sonra: 2 2 2 2 2 1 1 1 1 1    ← Doğru
    
... çözüm