Bölüm 6 Veri Türleri ISBN 0-321-49362-1
Bölüm 6 Konular Giriş İlkel Veri Türleri Karakter Dizisi Türleri Kullanıcı Tanımlı Sıra Türleri Dizi Türleri İlişkili Diziler
Giriş Bir veri türü veri nesnelerinin bütününü ve bu nesneler üzerindeki önceden tanımlanmış işlemleri tanımlar Bir tanımlayıcı, bir değişkenin niteliklerinin bütünüdür Bir nesne kullanıcı tanımlı (soyut veri) türün bir örneğini sunar
İlkel Veri Türleri Hemen hemen tüm programlama dilleri bir ilkel veri türleri kümesi sağlar İlkel veri türleri: diğer veri türleri cinsinden tanımlanamayan veri türleridir Bazı ilkel veri türleri sadece donanımın bir yansımasıdır İlkel olmayan türler donanım dışı destek gerektirir
İlkel Veri Türleri: Tamsayı Bir çok dil tamsayı veri türlerine sahiptir Bir dilde sekiz farklı tamsayı türü olabilir (C# gibi) Java nın işaretli tamsayı türleri: byte, short, int, long
İlkel Veri Türleri: Kayan Noktalı Sayı Reel sayıları modeller; fakat yalnızca yaklaşım olarak Bilimsel amaçlı kullanılan diller en az iki kayan nokta türünü destekler (ör:float ve double; kimi zaman daha da fazlası) Genelde donanım ile uygulanır; bazen uygulama yardımı gerekir IEEE 754 Kayan Nokta Standardı
İlkel Veri Türleri: Karmaşık Bazı programlama dilleri karmaşık sayı türlerini de destekler Fortran ve Python gibi Karmaşık sayılar, kayan noktalı sayıların sıralanmış biçimi olarak gösterilir Bazı dillerde sayının sanal kısmı yardımcı bir karakterle gösterilir Ör: Phyton da j veya J karakteri kullanılır. 3+7j gibi.
İlkel Veri Türleri: Ondalık İş Uygulamaları (Parasal) İçin COBOL da çok önemli C# ve F# bir ondalık veri türü sunar Belli sayıda ondalıklı basamağı tutar Ondalık sayılar BCD kodunda bellekte tutulur Avantaj: hassasiyet Dezavantaj: sınırlı aralık, hafızayı boşa harcar
İlkel Veri Türleri: Boolean En basit veri türü Değerlerin aralığı: iki eleman, biri doğru, diğeri yanlış Bit ler olarak uygulanabilir; ama çoğunlukla baytlar olarak uygulanır (bit düzeninde belleğe erişim mümkün olmadığı için) Avantaj: okunabilirlik
İlkel Veri Türleri: Karakter Sayısal kodlar olarak tutulurlar En yaygın kullanılan kodlama: ASCII Bir alternatif, 16 bitlik kodlama: Unicode Doğal dillerden karakterler içerir İlk Java da kullanıldı C# ve JavaScript de Unicode u destekler
Karakter Dizisi (String) Türü Değerler karakter dizileridir Ör: char str[] = "Bilgisayar Mühendisliği"; Tasarım sorunu: Bu bir ilkel veri türü müdür yoksa özel bir tür array (dizi) midir? Dizilerin uzunluğu statik mi olmalı yoksa dinamik mi?
Karakter Dizisi Türünün İşlemleri Tipik İşlemler Atama ve kopyalama Karşılaştırma (=, >, v.s.) Birleştirme Alt dizi referansı Desen eşleştirme
Bazı Dillerdeki Karakter Dizisi Türü C ve C++ İlkel değil char dizileri ve işlemleri sağlayan fonksiyonların kümesini kullanır SNOBOL4 (bir dizi işleme dili) İlkel Detaylı doku eşleştirmeyi de içeren pek çok işlem Java String sınıfı aracılığıyla ilkel
Karakter Dizisi Uzunluk Seçenekleri Üç tipte olabilir Statik Uzunluk: COBOL, Java nın String sınıfı, C#, Python Sınırlı Dinamik Uzunluk: C ve C++ C tabanlı dilde, uzunluğa bakmak yerine dizinin karakterlerinin sonunu belirtmek için özel bir karakter kullanılır Dinamik Uzunluk(üst sınır yok): SNOBOL4, Perl, JavaScript Ada bu üç dizi uzunluk seçeneğini de destekler
Karakter Dizi Türünün Değerlendirilmesi Yazılabilirliğe yardım Statik uzunlukta ilkel bir veri türü olarak maliyeti düşük Dinamik uzunluk çok işlevsel ancak maliyeti yüksek
Karakter Dizisi Uygulaması Statik uzunluk: Compile-time (derlenme zamanı) tanımlayıcısı Sınırlı dinamik uzunluk: Uzunluk için bir run-time (çalışma zamanı) tanımlayıcıya gereksinim duyabilir (fakat C ve C++ da ihtiyaç duyulmaz) Dinamik uzunluk: Run-time tanımlayıcıya ihtiyaç var; hafızada alan tahsis etme ve serbest bırakma en büyük uygulama problemi
Compile ve Run-Time Tanımlayıcılar Statik diziler için compile- diziler için runtime tanımlayıcı Sınırlı Dinamik time tanımlayıcı
Kullanıcı Tanımlı Sıra Türleri Bir sıra türü, muhtemel değerlerin aralığının kolayca pozitif tamsayılar kümesiyle ilişkilendirilebildiği türdür Java daki ilkel sıra türlerine örnekler: integer char boolean Genellikle diller iki sıra türü sunarlar: enum ve subrange
Sayma Türleri Sabitler denen tüm muhtemel değerler tanımda verilir C# örneği enum days {mon, tue, wed, thu, fri, sat, sun};
Sayma Türlerinin Değerlendirilmesi Okunabilirliğe yardım, ör., bir rengi sayı olarak kodlamaya gerek yok Güvenilirliğe yardım, ör., derleyici aşağıdakileri kontrol edebilir: İşlemler (renklerin toplanmasına izin vermez) Hiçbir sayma değişkeni tanımlı olduğu aralığın dışındaki bir değere atanamaz Ada, C# ve Java,sayma için C++ dan daha iyi destek sağlıyor; çünkü bu dillerdeki sayma değişkenleri tamsayı türüne zorlanmamış
Alt Aralık (subrange) Türleri Sıra türünün sıralı bitişik bir alt dizisidir Pascal ve Ada da uygulanmıştır Örnek: 12..18 tamsayı türünün bir alt aralığıdır Ada nın tasarımı type Days is (mon, tue, wed, thu, fri, sat, sun); subtype Weekdays is Days range mon..fri; subtype Index is Integer range 1..100; Day1: Days; Day2: Weekday; Day2 := Day1;
Alt Aralığın Değerlendirilmesi Okunabilirliğe yardım Okuyuculara alt aralıkların değişkenlerinin sadece belli aralıktaki değerleri tutabildiğini belli etmek Güvenilirlik Bir alt aralık değişkenine belirlenen aralığın dışında bir değer atamak hata olarak algılanır
Kullanıcı Tanımlı Sıra Türlerinin Uygulaması Sayma türleri tamsayı olarak uygulanırlar Alt aralık türleri, derleyici tarafından alt aralık değişkenlerine atamayı engellemek için girilen kodları olan ebeveyn türleri gibi uygulanırlar
Dizi Türü Dizi, içinde yer alan her bir elemanın yığın içindeki ilk elemana göre olan pozisyonlarıyla tanımlandığı homojen veri elemanları yığınıdır
Dizi Tasarım Sorunları Hangi türler alt indis için uygundur? Eleman referanslarındaki alt indis ifadeleri aralık kontrollü mü? Alt indis aralıkları ne zaman sınırlı? Hafızada yer tahsis etme ne zaman olur? En fazla alt indis sayısı nedir? Dizi nesneleri ilklendirilebilir mi? Herhangi bir şekilde bölmek mümkün mü?
Dizi Oluşturma (İndeksleme) İndeksleme (veya alt indis oluşturma) indislerden elemanlara bir eşleştirmedir dizi_adı(altindis) İndeks Sözdizimi dizi_elemanı FORTRAN, PL/I, Ada normal parantez kullanır Ada parantezleri dizi referansları ve fonksiyon çağırmalar arasındaki benzerliği (çünkü her ikisi de eşleştirmedir-mapping) göstermek için parantezleri kullanır Diğer pek çok dil köşeli parantez kullanır
Dizilerin İndis Türleri FORTRAN, C: sadece tamsayı Pascal: herhangi bir sıra türü (tamsayı, Boolean, char, sayma-enumeration) Ada: tamsayı ya da sayma (Boolean ve char ı da içerir) Java: sadece tamsayı türleri C, C++, Perl ve FORTRAN aralık kontrolünü belirtmez Java, ML, C# aralık kontrolünü belirtir
İndis Bağlama ve Dizi Kategorileri İndis aralıklarına ve depo tahsisinin yapıldığı zamana bağlı olarak beş farklı kategori vardır
İndis Bağlama ve Dizi Kategorileri Statik: indis aralıkları, statik olarak sınırlıdır ve depo tahsisi statiktir (run-time dan önce) Avantaj: verimlilik (dinamik yer tahsisi yok) Dezavantaj: tüm çalışma zamanı boyunca bellek meşgul Sabit yığıt-dinamik: indis aralıkları statik olarak sınırlı;ama yer tahsisi tanımlama ayrıntılama ile yükleme zamanında yapılır Avantaj: yer verimliliği Dezavantaj: tahsis ve serbest bırakma zamanı
İndis Bağlama ve Dizi Kategorileri (devam) Yığıt (stack)-dinamik: indis aralıkları dinamik olarak sınırlı ve yer tahsisi dinamik (run-time da yapılıyor) Avantaj: esneklik (dizinin boyutunun dizi kullanılana kadar bilinmesi lazım) Sabit yığın(heap)-dinamik: sabit yığıtdinamik e benzer: depo bağlama dinamiktir; fakat yer tahsisinden sonra sabitlenir (bağlama, istendiği zaman ve depo yığıttan değil yığından tahsis edildiğinde yapılır)
İndis Bağlama ve Dizi Kategorileri (devam) Yığın-dinamik: indis aralıklarının ve depo tahsisinin bağlanması dinamiktir ve birkaç kere değişebilir Avantaj: esneklik (diziler programın çalışması sırasında büyüyebilirler, küçülebilirler)
İndis Bağlama ve Dizi Kategorileri (devam) static değiştirici içeren C ve C++ dizileri statiktir static değiştirici içermeyen C ve C++ dizileri sabit yığıt-dinamiktir Ada dizileri yığıt-dinamik olabilir C ve C++ sabit yığın-dinamik diziler sunabilir (kütüphanedeki malloc ve free ile) C# sabit yığın-dinamik sağlayan ArrayList ikinci bir dizi sınıfını içerir Perl ve JavaScript yığın-dinamik dizileri destekler
Dizi İlklendirme Bazı diller ilklendirmeye depo tahsisi zamanında izin verirler C, C++, Java, C# örneği int list [] = {4, 5, 7, 83} C ve C++ daki karakter dizileri char name [] = freddie ; C ve C++ da karakter dizilerinin dizisi char names [] = { Bob, Jake, Joe ]; String[] names = { Bob, Jake, Joe };
Dizi İşlemleri APL, birli işlemler, vektörler ve matrisler için en güçlü dizi işlemleri sunar Ada dizi atamasına ve birleştirmeye de izin verir Python ve Ruby, karşılaştırma (==) gibi basit işlemler sunar Fortran dizi çiftleri arasındaki basit işlemleri sunar Örneğin, iki dizi arasındaki + operatörü, iki dizinin eleman çiftlerinin toplamından oluşan bir diziyle sonuçlanır
Dikdörtgen ve Düzensiz Diziler Bir dikdörtgen dizi, tüm satırlarının ve sütunlarının aynı sayıda elemana sahip olduğu çok boyutlu dizilerdir Düzensiz matrislerin değişken sayıda elemanlı satırları vardır Çok boyutlu dizilerin, dizilerin dizisi olarak görüldüğü zamanlarda olabilir
Dilimler Bir dilim, dizinin bazı alt yapılarıdır Dilimler yalnızca dizi operasyonları olan dillerde kullanışlıdır Python ve Fortran dilimleme desteği sunar
Dilim Örnekleri Fortran 95 Integer, Dimension (10) :: Vector Integer, Dimension (3, 3) :: Mat Integer, Dimension (3, 3) :: Cube Vector (3:6) dört elemanlı bir dizidir
Fortran 95 te Dilim Örnekleri
Dizilerin Uygulaması Erişim fonksiyonu indis ifadelerini dizideki adrese eşler Tek boyutlu diziler için erişim fonksiyonu: address(list[k]) = address (list[lower_bound]) + ((k-lower_bound) * element_size)
Çok Boyutlu Dizilere Erişim İki yaygın yol: Satır esaslı sıra (satırlarla) pek çok dilde kullanılıyor Sütun esaslı sıra (sütunlarla) Fortran da kullanılıyor
Çok Boyutlu Bir Diziye Bir Eleman Yerleştirme location(a[i, j]) = address of a[0, 0] + (((i * n) + j) * element_size)
Compile-Time Tanımlayıcılar Tek boyutlu dizi Çok boyutlu dizi
İlişkili Diziler İlişkili dizi, anahtarlar denen eşit sayıda değerle indekslenen sırasız veri elemanları topluluğudur Kullanıcı tanımlı anahtarlar depolanmalı Tasarım sorunları: elemanlara yapılan referansın formu ne?
Perl de İlişkili Diziler İsimler % ile başlar; sayılar parantezlerle sınırlanmıştır %hi_temps = ("Mon" => 77, "Tue" => 79, Wed => 65, ); İndisleme kıvırcık parantezler ve anahtarlarla yapılıyor $hi_temps{"wed"} = 83; Elemanlar delete ile silinebilir delete $hi_temps{"tue"};s
İşaretçi ve Referans Türleri İşaretçi türünde bir değişkenin hafıza adresleri ve özel bir karakter, nil, içeren değer aralığı vardır Dolaylı adresleme gücü verir Dinamik hafızayı yönetmek için bir yol sağlar Bir işaretçi deponun dinamik olarak oluşturulduğu alandaki (genelde yığın denir) yerlere erişmek için kullanılabilir
İşaretçi İşlemleri İki temel işlem: atama ve referanstan ayırma Atama, işaretçi değişkeninin değerini kullanışlı bir adrese vermek için kullanılır Referanstan ayırma, işaretçinin değeriyle gösterilen yerde tutulan değeri getirir Referanstan ayırma açık ya da kapalı olabilir C++ * aracılığıyla açık işlem kullanır j = *ptr ptr de bulunan değeri j ye atar
İşaretçi Ataması Gösterimi j = *ptr atama işlemi