D.ershane Çözümleri Ddili.org

Göstergeler

  1. Parametre türleri yalnızca int olduğunda işleve main() içindeki değişkenlerin kopyalarının gönderildiklerini biliyorsunuz. main() içindeki değişkenlerin referanslarını edinmenin bir yolu, parametreleri ref int olarak tanımlamaktır.

    Diğer bir yol, o değişkenlere erişim sağlayan göstergeler göndermektir. Programın değişen yerlerini sarı ile işaretliyorum:

    void değişTokuş(int * birinci, int * ikinci) {
        int geçici = *birinci;
        *birinci = *ikinci;
        *ikinci = geçici;
    }
    
    void main() {
        int i = 1;
        int j = 2;
    
        değişTokuş(&i, &j);
    
        assert(i == 2);
        assert(j == 1);
    }
    
  2. Hem Düğüm hem de Liste int türüne bağlı olarak yazılmışlardı. Bu iki yapıyı şablona dönüştürmenin yolu, tanımlanırken isimlerinden sonra (T) eklemek ve tanımlarındaki int'leri T ile değiştirmektir. Değişen yerlerini sarıyla işaretliyorum:
    struct Düğüm(T) {
        T eleman;
        Düğüm * sonraki;
    
        string toString() const {
            string sonuç = to!string(eleman);
    
            if (sonraki) {
                sonuç ~= " -> " ~ to!string(*sonraki);
            }
    
            return sonuç;
        }
    }
    
    struct Liste(T) {
        Düğüm!T * baş;
    
        void başınaEkle(T eleman) {
            baş = new Düğüm!T(eleman, baş);
        }
    
        string toString() const {
            return format("(%s)", baş ? to!string(*baş) : "");
        }
    }
    

    Liste'yi artık int'ten başka türlerle de deneyebiliriz:

    import std.stdio;
    import std.conv;
    import std.string;
    
    // ...
    
    struct Nokta {
        double x;
        double y;
    
        string toString() const {
            return format("(%s,%s)", x, y);
        }
    }
    
    void main() {
        Liste!Nokta noktalar;
    
        noktalar.başınaEkle(Nokta(1.1, 2.2));
        noktalar.başınaEkle(Nokta(3.3, 4.4));
        noktalar.başınaEkle(Nokta(5.5, 6.6));
    
        writeln(noktalar);
    }
    

    Çıktısı:

    ((5.5,6.6) -> (3.3,4.4) -> (1.1,2.2))
    
  3. Bu durumda sondaki düğümü gösteren bir üyeye daha ihtiyacımız olacak. Açıklamaları programın içine yerleştirdim:
    struct Liste(T) {
        Düğüm!T * baş;
        Düğüm!T * son;
    
        void sonunaEkle(T eleman) {
            /* Sona eklenen elemandan sonra düğüm bulunmadığından
             * 'sonraki' düğüm olarak 'null' gönderiyoruz. */
            auto yeniDüğüm = new Düğüm!T(eleman, null);
    
            if (!baş) {
                /* Liste boşmuş. Şimdi 'baş' bu düğümdür. */
                baş = yeniDüğüm;
            }
    
            if (son) {
                /* Şu andaki 'son'dan sonraya bu düğümü
                 * yerleştiriyoruz. */
                son.sonraki = yeniDüğüm;
            }
    
            /* Bu düğüm yeni 'son' oluyor. */
            son = yeniDüğüm;
        }
    
        void başınaEkle(T eleman) {
            auto yeniDüğüm = new Düğüm!T(eleman, baş);
    
            /* Bu düğüm yeni 'baş' oluyor. */
            baş = yeniDüğüm;
    
            if (!son) {
                /* Liste boşmuş. Şimdi 'son' bu düğümdür. */
                son = yeniDüğüm;
            }
        }
    
        string toString() const {
            return format("(%s)", baş ? to!string(*baş) : "");
        }
    }
    

    başınaEkle() işlevi aslında daha kısa olarak da yazılabilir:

        void başınaEkle(T eleman) {
            baş = new Düğüm!T(eleman, baş);
    
            if (!son) {
                son = baş;
            }
        }
    

    Yukarıdaki Nokta nesnelerinin tek değerli olanlarını başa, çift değerli olanlarını sona ekleyen bir deneme:

    void main() {
        Liste!Nokta noktalar;
    
        foreach (i; 1 .. 7) {
            if (i % 2) {
                noktalar.başınaEkle(Nokta(i, i));
    
            } else {
                noktalar.sonunaEkle(Nokta(i, i));
            }
        }
    
        writeln(noktalar);
    }
    

    Çıktısı:

    ((5,5) -> (3,3) -> (1,1) -> (2,2) -> (4,4) -> (6,6))