Göstergeler
- Parametre türleri yalnızca
int
olduğunda işlevemain()
içindeki değişkenlerin kopyalarının gönderildiklerini biliyorsunuz.main()
içindeki değişkenlerin referanslarını edinmenin bir yolu, parametreleriref 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 işaretlenmiş olarak gösteriyorum:
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); }
- Hem
Düğüm
hem deListe
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ındakiint
'leriT
ile değiştirmektir. Değişen yerlerini işaretlenmiş olarak gösteriyorum: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ıkint
'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))
- 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))