Forum: Ders Arası RSS
dilimler
dilimlerin ana diziyi etkilemesi hakkında
Avatar
mert #1
Üye Ara 2010 tarihinden beri · 194 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: dilimler
Merhabalar;

D dilini Ali Hocamın D programlama dili adlı çalışmasından öğreniyorum. 19 numaralı konu başlında anlatılanlara göre şöyle bir program tasarladım:
import std.stdio;
 
void main()
{
    writeln(": DILIMLER: ");
    writeln();
    writeln("Var olan bir dizinin belirli bir bolumune erisim saglayacak olan yapiya dilim denir.");
    writeln("Dilim sayesinde var olan baska bir dizinin, elemanlarinin bir bolumunu,");
    writeln("sanki daha kucuk ayri bir diziymis gibi kullanabiliriz. ");
    writeln("Ornek olarak ayGunleri dizisini dorde dilimleyerek birbiriden ayri dort ");
    writeln("ceyrek diziymis gibi soyle kullanabiliriz. ");
    writeln();
 
    int ayGunleri[12] = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ];
    int ilkCeyrek[]      = ayGunleri[0..3];
    int ikinciCeyrek[]   = ayGunleri[3..6];
    int ucuncuCeyrek[]   = ayGunleri[6..9];
    int dorduncuCeyrek[] = ayGunleri[9..12];
    writeln("ilk ceyrek dilimimiz: ", ilkCeyrek);
    writeln("Dilimler ayri birer dizi degildirler. Bunlar asil dizinin elemanlarina erisim ");
    writeln("saglarlar.Dilimlerin elemanlarina yapilan her mudahale diziye de yansir."); 
    writeln("ilkCeyrek dilimine bir eleman ekleyelim ");
    writeln();
    ilkCeyrek ~= 40;
    writeln("ilkCeyrek dizimizin hali: ", ilkCeyrek);
    writeln("ayGunleri dizimiz ise: ", ayGunleri);
    writeln("Himm. dilimlere deger ekledik ama bu eklememiz ana diziye yansimadi -");
    writeln("cunku ana dizimiz sabit uzunluklu- ancak bakalim degisiklik yapilabiliyor mu? ");
    writeln();
    ilkCeyrek[] = 1;
    ikinciCeyrek[]=2;
    ucuncuCeyrek[]=3;
    dorduncuCeyrek[]=4;
    writeln("ilkCeyrek dizimiz : ", ilkCeyrek);
    writeln("ana dizimiz ayGunleri ", ayGunleri);
}
 
çıktı:  ilkCeyrek dizimiz : [1, 1, 1, 1]
ana dizimiz ayGunleri [31, 28, 31, 2, 2, 2, 3, 3, 3, 4, 4, 4]

Açıklamam:
"ayGunleri dizisi sabit uzunluklu bir dizi. Onu dilimledigimizde ise dilimlerimiz dinamik dizi haline geliyor. Biz biliyoruz ki dinamik dizi halindeki diziler eleman alabilirler. Oysa kitapta dizi dilimlerine erisilip onlarda degisiklik yapildiginda dizinin kendisi de bundan etkileniyor diye belirtilmişti. O halde ilkCeyrek dizisine ekledigimiz 40 degerindeki bir eleman dizi yapısını degistirecek mi diye bakmak istedim. Degistirmedi. Dizi sabit uzunluklu oldugundan oyle olması bana mantıksız gelmedi. Ancak hem ilkCeyrek dilimi hem de diger ceyreklerin degerlerini kitaptaki örnege gore degistirdigimde icerigine 40 degerli eleman ekledigim ilkCeyrek dilimi haric diger dilimlerde degisiklikler olurken ve bu ana dizimize yansirken ilk Ceyregin temsil ettigi  dilim  ana dizimizdeki eski halini korudu. "

Sorum: Peki ilkCeyrek diliminin veya ana dizimiz olan ayGunleri dizimizin bu davranisi normal midir_?
Teşekkürlerimle

Mert.
mert
Bu mesaj 6 defa değişti; son değiştiren: mert; zaman: 2011-01-27, 13:16.
canalpay (Moderatör) #2
Kullanıcı başlığı: Can Alpay Çiftçi
Üye Tem 2009 tarihinden beri · 1133 mesaj · Konum: İzmir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
İlk önce hoşgeldiniz!

Ali bey burada açıklamış: http://ddili.org/forum/thread/411

Kısaca dilimler asıl dizilere ulaşan bir referans türüdür. Ancak dilimlere yeni bir eleman eklendiğinde asıl dizi ile bağını koparır ve onun elemanlarını kendine kopyalar ayrıca birde yeni eleman eklenir.

Ali Bey şöyle özetlemiş:

D'nin dilimlerinin garip tarafı, aynı elemanlara erişim sağlayan birden fazla dilim bulunduğunda ortaya çıkabiliyor: dilimlerden birisinin uzunluğu arttığında artık aynı elemanlara erişim sağlamaz hale geliyorlar. Uzunluk artınca elemanlar kopyalanıyor ve uzunluğu artan dilim bu yeni elemanlara erişim sağlamaya başlıyor. Dilimler o zamana kadar aynı elemanlara erişim sağlıyorlarken, uzunluğun artmasından sonra artık farklı elemanlara erişim sağlıyorlar.
Avatar
mert #3
Üye Ara 2010 tarihinden beri · 194 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Merhaba Can. Hoşbulduk.
Orayı gözden kaçırmışım. Hemen yöneliyorum.
İlgin için teşekkür ederim.
Mert
mert
canalpay (Moderatör) #4
Kullanıcı başlığı: Can Alpay Çiftçi
Üye Tem 2009 tarihinden beri · 1133 mesaj · Konum: İzmir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #2
Biraz daha açıklayıcı olması için programın işleyişinide ayrıca anlatmak istedim. Buyrun:

Sorum: Peki ilkCeyrek diliminin veya ana dizimiz olan ayGunleri dizimizin bu davranisi normal midir_?
Teşekkürlerimle


Evet. Daha önceki mesajımdan yola çıkarak programın işleyişine bakalım:
 
    int ayGunleri[12] = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ];
    int ilkCeyrek[]      = ayGunleri[0..3];
    int ikinciCeyrek[]   = ayGunleri[3..6];
    int ucuncuCeyrek[]   = ayGunleri[6..9];
    int dorduncuCeyrek[] = ayGunleri[9..12];

Buraya kadar her şey beklendiği gibi. dizimizi oluşturuyoruz ve hemen ardından dilimlerimizi oluşturuyoruz.

    ilkCeyrek ~= 40;

Bu işi bozuyor. Şimdiye kadar ilkCeyrek hep ayGunleri dizisinin belirli bir bölümünü gösterdi. Ancak ilkCeyreğe başka bir eleman eklendi. D'ciler yeni eleman eklendiğinde dilimin artık ilkCeyreği göstermesin ayrı bir dizi olsun demişler. Şimdiye kadar gösterdiği elemanlarıda kendine kopyalasın ondan sonra o dizi ile hiç bir bağı kalmasın demişler. Siz yeni bir eleman eklediğinizde yada çıkardığınızda gereken elemanları asıl diziden kendisine kopyalıyor ve artık kendine buyruk dizimiz yaşamına devam ediyor.

Yani artık ilkCeyrek dizimiz ayGunlerinin dilimi değil kendi elemanı olan bağımsız bir dizi oluyor. Ancak diğer ikinciCeyrek, ucuncuCeyrek .... dilimlerine birşey olmadı.


Ve son olarakta:

    ilkCeyrek[] = 1;
    ikinciCeyrek[]=2;
    ucuncuCeyrek[]=3;
    dorduncuCeyrek[]=4;

ilkCeyrek ayrı bir dizi olarak yoluna devam ediyor ve bütün elemanlarını 1 yapıyoruz. Diğerleri dilimler dilimlerin elemanını değiştirince asıl değişkenin elemanıda değişmiş oluyor.
Bu mesaj canalpay tarafından değiştirildi; zaman: 2011-01-27, 13:29.
acehreli (Moderatör) #5
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #3
Mert, umarım böyle sıkıntılar hevesini kırmıyordur. Ayrıca titizliğin için çok teşekkürler. O konuyu düzelteceğim.

Can, arşiv gibi adamsın! :) Beni aynı açıklamayı yapmaktan (ve belki de kendimle çelişmekten :p) kurtardın.

Ali
Avatar
mert #6
Üye Ara 2010 tarihinden beri · 194 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Merhaba hocam,
Bu türden tuhaflıkları ben de merak ettiğimden kurcalamadan duramıyorum maalesef. Okudum, anladım, geçtim türü bir öğrenim modelini bir türlü benimseyemedim hâlâ. İşte Can beyin belirttiği örneği yani ilkCeyrek dizisinin yaşamını kontrol edip etmeme konusunda neler yapabileceğimi düşünürken mesajın gelmesi hoş oldu. Sanırım bir kaç dakika sonra oraya da kendiliğimden erişip "aaa böyle oluyormuş yahu" diyecekmişim olasılıkla. Konu pekişmiş oldu böylelikle. Ayrıca varlığından haberimin olmadığı makaleye de Can bey işaret etmiş. Kaynak bol olduktan sonra sorun yaşanacağını sanmıyorum ben.
keyifli bir süreç aslında. Tartışma alanlarını daha çok kurcalamalıyım. :-)

İlginiz için ayrıca teşekkür ederim.

mert
mert
canalpay (Moderatör) #7
Kullanıcı başlığı: Can Alpay Çiftçi
Üye Tem 2009 tarihinden beri · 1133 mesaj · Konum: İzmir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Bu türden tuhaflıkları ben de merak ettiğimden kurcalamadan duramıyorum maalesef.

Benim tam zıttım :-p Aslında böyle sorular çok yararlı. Bende sizin sayenizde dilimleri pekiştirmiş oldum. Bu yüzden böyle sorular sormaya devam etmelisiniz bence.


keyifli bir süreç aslında. Tartışma alanlarını daha çok kurcalamalıyım. :-)

Kesinlikle. Hem eğlenmek hem de öğrenmek için.
acehreli (Moderatör) #8
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Dilimler dersi içler acısı bir durumdaymış. "Başka Dizi Olanakları" olarak baştan yazıyorum:

$, .dup, dilimler, dilimin boyunun uzamasının paylaşımı sonlandırması (Mert'in başlattığı konu), bütün diziyi etkileyen işlemler (dizi[] = 1 gibi), vs.

Ali
acehreli (Moderatör) #9
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
acehreli on 2011-01-28, 10:00:
Dilimler dersi içler acısı bir durumdaymış. "Başka Dizi Olanakları" olarak baştan yazıyorum

Tamam, yazdım; ama siteye koymadan önce bir kaç kere daha gözden geçireceğim. Yazarken dikkatimi çeken ve derse eklediğim önemli bir konu oldu.

Kendiliğinden bilinecek bir şey değil ama iştahınızı kabartmak için önce burada göstereyim:

import std.stdio;
 
void main()
{
    double[] dilim1 = [ 1, 1, 1 ];
    double[] dilim2 = [ 2, 2, 2 ];
    double[] dilim3 = [ 3, 3, 3 ];
 
    dilim2 = dilim1;              // (1)
    dilim3[] = dilim1;            // (2)
 
    writeln("dilim1: ", dilim1);
    writeln("dilim2: ", dilim2);
    writeln("dilim3: ", dilim3);
}

(1) ve (2) numaralı satırlar arasında önemli bir fark var. Nedir? :)

İşin kötüsü, o iki satır arasındaki anlamsal farkın programda hemen farkedilemiyor olması: programda belki de aylar sonra yapılan ufak bir değişiklik dilim2 ve dilim3 arasındaki fark nedeniyle beklenmeyen sonuçlar doğurabilir. Nedir? :)

Ali
Bu mesaj acehreli tarafından değiştirildi; zaman: 2011-02-01, 23:35.
canalpay (Moderatör) #10
Kullanıcı başlığı: Can Alpay Çiftçi
Üye Tem 2009 tarihinden beri · 1133 mesaj · Konum: İzmir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yazarken dikkatimi çeken ve derse eklediğim önemli bir konu oldu.

Kendiliğinden bilinecek bir şey değil ama iştahınızı kabartmak için önce burada göstereyim:


Teşekkürler bende unutmuştum. Yanıtını belki başkalarıda merak eder diye ve heyecanlansınlar diye vermiyorum :-p

Bunun yanıtı forumda var. Hatta Ali Bey hakkında diziler üzerinde tartışıyorken bunla ilgili kullanımın ne olduğunu tam bilmeden örnek vermiştim. Bu kullanımı ilk ve tek andreinin kitabında( pandoranın kutusunda der gibi :-p ) görmüştüm.

Şimdi bu kadar havalandım birde tahmin ettiğim şey çıkmazsa kendimi camdan aşağıya atarım :-)

İp ucu: Bu olanak dizilerde döngü kullanıp elemanlarıyla işlem yapmamızı gereksizleştiriyor. Ali beyin verdiği örnekte farkını göremeyiz. :-)
acehreli (Moderatör) #11
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
canalpay:
Bunun yanıtı forumda var

Hatırladım. :) C (ve C++) dizilerini her taraflarıyla bilen birisi olarak D'nin dizilerine (ve dilimlerine) tedirginlikle yaklaşıyorum. Daha tam kavradığımdan emin değilim. Her taşın altından bir dizi olanağı çıkacak diye korkuyorum. :-p

Bu olanak dizilerde döngü kullanıp elemanlarıyla işlem yapmamızı gereksizleştiriyor. Ali beyin verdiği örnekte farkını göremeyiz. :-)

Senin yerine ben bitirmekte olduğum yazıdan bir örnek koyayım:

import std.stdio;
 
void main()
{
    double[3] a = [ 10, 20, 30 ];
    double[3] b = [  234 ];
 
    double[3] sonuç = a[] + b[];
 
    writeln(sonuç);
}

Çok yararlı gibi görünüyor, değil mi. Çıktısı şöyle:

[12, 23, 34]


Ali
canalpay (Moderatör) #12
Kullanıcı başlığı: Can Alpay Çiftçi
Üye Tem 2009 tarihinden beri · 1133 mesaj · Konum: İzmir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Sizde söylediğinize göre konunun bağlantısını vereyim: http://ddili.org/forum/thread/36

Benden çok basit ancak bence çok kullanılacak bir örnek:

import std.stdio;
 
void main() {
   double[] c;
   c.length=2;
   //c = 4.5; // dizi uzunluğu iki olan ilklenmemiş dizimizin
   //2 elemanınında 4.5 olmasını bekleyebiliriz.
   //Ancak o iki elemanlı bir diziyi tek elemanlı bir değişkene atamaya çalışır ki doğru olan budur.
   //Dolasıyla hata verir.
   c[]=4.5;//dersek bütün elemanlarının 4.5 olması gerektiğini derleyiciye anlatmış oluruz.
    
   writeln(c);
 
}

Bu arada hiç aralıkla ilgili bir örnek vermedik. Aralıkla da kullanılabildiğini belirtmek gerekiyor:



 
import std.stdio;
 
void main() {
   double[] c;
   c.length=5;
   c[]=1;
   c[1..3] = 13;
   writeln(c);
 
}


Kesinlikle yararlı. Foreach ile aynı şey ancak daha anlaşılır oluyor.

Ancak normal kullanımda:

    dilim2 = dilim1;              // (1)
    dilim3[] = dilim1;            // (2)
    writeln(dilim2);
    writeln(dilim1[]);

bunların farkları yok değil mi?
acehreli (Moderatör) #13
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Teşekkürler Can! Güzel örnekler...

canalpay:
Ancak normal kullanımda:

    dilim2 = dilim1;              // (1)
    dilim3[] = dilim1;            // (2)
    writeln(dilim2);
    writeln(dilim1[]);

bunların farkları yok değil mi?

Yok gibi görünüyor ama var. Benim tehlikeli bulduğum da zaten o:

(1)'in anlamı: dilim2, dilim1'in erişim sağladığı elemanlara erişim sağlamaya başlar. Yani birisi yoluyla yapılan eleman değişiklikleri diğerinde de görülür.

(2)'nin anlamı: dilim3'ün elemanlarının değerlerini dilim1'in elemanlarının değerlerinin aynısı yap.

Yeni ders hazır:

  http://ddili.org/ders/d/dilimler.html

Orada "Bütün elemanlar üzerindeki işlemler" başlığının sonunda geçiyor.

Ali
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Forum: Ders Arası RSS
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2017-11-18, 17:27:01 (UTC -08:00)