SET

(Küme)

 

PASCAL’da bazı öğelerin topluluğu, matematikte olduğu gibi bir küme olarak tanımlanabilir ve bunun öğeleriyle ve alt kümeleriyle, kümeler cebirindeki işlemler yapılabilir. Küme tanımı, programın (ya da blokun) bildirge bölümünde yapılır. Bildiri için sözdizimi şöyledir:

Type

     Küme_adı    = SET OF veri_türü;

Var

     Küme_değişkeni          : küme_adı;

Veri_türü ordinal bir tür olmalıdır. Dolayısıyla, integer, char ya da programcının daha önce tanımladığı numaralanmış bir veri türü olabilir. Ama, real tür olamaz; çünkü ordinal bir tür değildir. Ayrıca, kümenin öğe sayısı sınırlıdır. Örneğin, Turbo Pascal’da bir küme en çok 256 öğeye sahip olabilir.

Örnek

Type

     Buyuk_harfler          = SET OF ‘A’..’Z’;

Var

     Bharf1, bharf2, bharf3   : buyuk_harfler;

bildirimi, buyuk_harfler adlı bir küme ile bu kümenin alt kümelerini temsil edecek bharf1, bharf2, bharf3 adlı üç değişken tanımlamaktadır. Dolayısyla, bharf1, bharf2 ve bharf3 değişkenleri boş küme olabilir, bazı büyük harfleri  ya da hepsini içeren birer alt küme olabilirler. Bu nedenle, bu değişkenler arasında kümeler cebirindeki birleşim, arakesit ve fark işlemleri yapılabilir. Kümeler arasında eşitlik ve kapsama bağıntılarının olup olmadığını belirten mantıksal deyimler geçerli olur. Bunları, aşağıdaki örnekler üzerinde görebiliriz.

Küme değişkenlerine atama işlemi,

               Bharf1 := [‘A’ , ’C’ , ’D’ , ’F’ , ’G’];

biçiminde öğeleri belirterek ya da

               Bharf2 := ‘C’ .. ‘F’;

biçiminde, bir alt bölge belirterek yapılabilir.

Turbo Pascal’da

               Bharf3 := [ succ(‘K’), pred(‘V’), ‘L’]; 

biçimindeki tanımlar geçerlidir. Ama standart Pascal, küme tanımı içinde deyimleri kabul etmez. Öte yandan,

               Bharf3 := ‘R’ ;

geçersiz bir deyimdir; çünkü  ‘R’ bir küme değil bir öğedir. Bu tamım,

               Bharf3 := [‘R’];

biçiminde yapılmalıdır.

 Birleşim, arakesit ve fark işlemleri, yukarıda atanan değerlere göre,

Birleşim işlemi (È)                              bharf1 + bharf2 = [‘A’, ‘C’, ‘D’, ‘E’, ‘F’, ‘G’];

Arakesit İşlemi (Ç)                              bharf1 * bharf2 = [‘C’, ‘D’, ‘F’];

Fark İşlemi (\)                              bharf1 – bharf2 = [‘A’, ‘G’];

biçiminde tanımlanır. Yukarıda söylenen nedenle,

               Bharf3 := bharf1 + ‘R’ ;

deyimi geçersizdir. Bunun yerine

               Bharf3 := bharf1 +  [ ‘R’ ] ;

yazılmalıdır.

Ayrıca kümeler cebirindeki eşitlik ve  kapsama bağıntıları da tanımlıdır:

Eşitlik (=)                              bharf1 = bharf2;

Eşit Değil                               bharf1<<bharf2;

Kesin Kapsama (É)                              bharf1 > bharf2;

Kesin Kapsanma (Ì)                              bharf1 < bharf2

Kapsama (Ê)                              bharf1 >= bharf2;

Kapsanma (Í)                              bharf1 <= bharf2;

Tabii, yukarıdaki değerlere göre, bu dört mantıksal ifade de yanlıştır.

IN Operatörü

Kümeler cebirindeki  (Î) öğesi ve (Ï) öğesi değil operatörleri PASCAL’da da geçerlidir. (a Î A) yerine (a in A) ve (b Ï A) yerine (not (b in A)) deyimleri kullanılır. Örneğin

               ‘C’ in bharf1;

mantıksal ifadesi doğrudur ama

               ‘B’ in harf1;

yanlıştır. Benzer şekilde,

not (‘B’ in harf2);

mantıksal ifadesi doğrudur, ama

               not ( ‘C’ in harf2 );

mantıksal ifadesi yanlıştır.


Örnek

program set01;

uses wincrt;

type

    Koltuk_kume =  SET OF 1..18;

    var

       dolu_koltuk   :  koltuk_kume;

       koltuk_No      :  Integer;

Begin

dolu_koltuk := [];

writeln('Geçerli koltuk numaraları 1.18 dir. ');

writeln('Programı durdurmak için geçersiz bir nuara giriniz.');

writeln; writeln;

writeln('Koltuk numarasını giriniz : ');

Readln(koltuk_No);

while koltuk_No IN [1..18] DO

   Begin

     dolu_koltuk := dolu_koltuk + [koltuk_No];

     write('Koltuk numarasını giriniz : ');

     Readln(koltuk_No);

   End;

 

writeln('Dolu koltuklar : ');

FOR koltuk_No := 1 to 18 DO

  IF koltuk_No IN dolu_koltuk

    THEN

      writeln(koltuk_No: 2 );

End.

 

 

Write ya da writeln komutu ile bir küme doğrudan yazılamaz. Kümenin öğeleri tek tek yazılmalıdır.

Uygulamalar

1.                H := [ ‘A’ ] ;  ataması yapılmışsa, aşağıdakilerden hangisi doğrudur?

a)     H  = ‘A’,

b)     H  in ‘A’ ;

c)     H  in [ ‘A’] ;

d)     A  in  H ;

e)     ‘A’  in  H;

f)     [‘A’] in H;

 

2.                +, - , *  simgelerinin aritmetik işlemlerdeki anlamları ile kümeler cebirindeki anlamlarını karşılaştırınız.

3.                Öğeleri 0 dan 9 a kadar rakamlar olan bir küme ve onun alt kümelerini temsil edecek iki değişken tanımlayınız. Değişkenlere çeşitli değerler vererek birleşim, arakesit ve fark işlemleri yapınız.

4.                Yukarıda yaptığınız her örnek için, kümeler arasında eşitlik, eşitsizlik, kapsama ve kapsanma bağıntıları kurunuz. Doğruluk değerlerini belirtiniz.

5.               Son iki soruda yaptıklarınızı denetleyecek birer Pascal programı yazınız.

6.               Aşağıdaki geçerli bir bildirim midir? Neden?

Type      Rakam_Tip = [‘0’..’9’];

7.            Aşağıdaki deyimlerin geçerli olup olmadığını, nedenleriyle söyleyiniz

a)         ‘1’ in Rakamlar;

b)         [‘X’,’Y’,’Z’] >= [‘N’..’Y’];

c)         Rakamlar/ [‘1’];

d)         Rakamlar * [‘1’;

e)         [‘1’] + [‘2’] + [‘3’] = [‘1’..’3’];

f)          [‘1’..’9’] >= [‘0’..’9’] – [‘3’..’7’];

g)         in Rakamlar;

 

8.               Type

Set Type = SET OF ‘0’..’9’;

Var

            Rakamlar, Tekler, Ciftler : Set Type;

            Rakamlar := [‘0’..’9’];

            Tekler      := [‘1’,’3’,’5’,’7’,’9’];

            Ciftler      := [‘2’,’4’,’6’,’8’];

Bildirimleri yapılıyor. Aşağıdakileri hesaplayınız.

Rakamlar + [‘1’];

Rakamlar * [‘1’];

 

9.                        Type

         notalar     = (do, re, mi,fa, sol, la, si);

Muzik   = SET OF notalar;

bildirimi yapılıyor. Aşağıdaki kümelerin öğelerini yazınız.

a)      [re..la]               e)               [do..fa] – [la..re]

b)     [do..fa] + [re..la]               f)               [re, fa, sol] – [re..la]

c)     [do..fa] – [re..la]               g)               [re, fa, sol] * []

d)     [do..fa] * [ re..la]               h)               [do, re, mi] + [re]

 

10.          Type       notalar       = (do, re, mi,fa, sol, la, si);

sarki        = SET OF notalar;

      Var

            Turku, disko : sarki;

            Ezgi      : notalar;

bildirimi  yapılıyor. Aşağıdaki atamaların sonucunu söyleyiniz.

a)               turku                := [do..fa] * [re..fa];

b)               disco                := [do..fa] – [mi];

c)               ezgi               := si;


RECORD

 

Türleri birbirlerinden farklı olan verileri bir araya getirip tek bir tip olarak işlemeyi sağlamak için, programcının tanımladığı bir türdür. Bunu, kağıda yazılı formlar gibi düşünebiliriz. Örneğin, bir nüfus cüzdanı sureti, bir sürücü ehliyeti, bir başvuru formu, farklı türden birden çok veriyi, bir bütün olarak bir arada tutarlar. PASCAL’da bu verileri bir arada tutacak bir yapı oluşturulabilir ve bunun adına record denilir.

Her tür için olduğu gibi, record, programın (ya da blokun) bildirge bölümünde tanımlanır. Programcının tanımladığı her türde olduğu gibi, ya doğrudan değişken olarak tanımlanabilir; ya da dolaylı olarak bir tip olarak tanımlanabilir.

 

Direk Bildirim

 

Var

Kimlik      :      RECORD

                   Sicil_No    : integer;

                   Ad               :  string[20];

                         Soyad            :  string[20];

                   ucret          : real

  END;

Dolaylı Bildirim

 

Type

Kimlik_tipi =      RECORD

                   Sicil_No    : integer;

              Ad               :  string[20];

                   Soyad        :  string[20];

                   ucret          : real

 END;

Var

Kimlik1, kimlik2      :      kimlik_tipi;

 

Dolaylı ve dolaysız bildirimler aynı işi görürler. Ancak, büyük bir programda, aynı biçimdeki record’u farklı bloklarda ve farklı değişken adlarıyla kullanmak gerekiyorsa, dolaylı bildirim seçilmelidir.

Record ... End arasına yazılan değişkenlerin her birisine bir bileşen ya da bir veri alanı (field) denilir. Bunların bildirimi değişken bildirimi gibidir. Herbirine bir ad verilir ve karşısına (:) dan sonra türü yazılır. Record içinde tanımlanan alanlar için tür ya da sayı kısıtlaması yoktur. Ancak, record içinde bildirilen her türün derleyici tarafından biliniyor olması gerekir. Bu demektir ki, ya derleyicide var olan temel türlerden birisi olmalıdır, ya da programcının önceden tanımladığı bir tip olmalıdır.

İç içe record tanımlanabilir.

 

Record Bileşenlerine Erişim

Record bileşenlerine değer atamak ya da atanmış bir değeri okumak için iki yol izlenebilir.

 

Record  Adını ve Bileşeni Yazarak

Bileşeni bir değişken olarak görmek için; record değişkeninin adı ve bileşenin adı yazılır; aralarına  (.) konulur. Örneğin,

 

Kimlik.Sicil_No := 1234;

 

deyimi, kimlik adlı record değişkeninin Sicil_no adlı bileşenine 1234 değerini atar. Kimlik._Sicil_No integer türünden bir değişkendir; dolayısıyla kendi türünden değişkenlerle yapılabilen her işi yapar.

 

Yalnızca Bileşen Adını Yazarak

Çok sayıda bileşenle işlemler yaparken, her deyimde record adını tekrarlamaktan sakınmak için, PASCAL bir kolaylık getirmiştir.

 

      WITH kimlik DO

            Begin

                  Sicil_No      := 1234;

                  Ad          := ‘DERYA’ ;

                  Soyad       := ‘ERDEM’ ;

                  Ucret       := 1225000

            End;

 

Deyimi, tek tek yapılan

 

                       Kimlik.Sicil_No      := 1234;

                  Kimlik.Ad         := ‘DERYA’ ;

                  Kimlik.Soyad            := ‘ERDEM’ ;

                  Kimlik.Ucret            := 1225000;

 

atamalaların yaptığı işi yapar.

program tarih;

uses wincrt;

type

   tarih   =             record

                             gun,ay,yil : integer;

                           end;

var

   bugun, yarin :            tarih;

Begin

   Writeln(‘Bu gün ayın kaçıdır ? ‘)

   bugun.gun             :=  12;

   bugun.ay              :=  4;

   bugun.yil             :=  2000;

   writeln('Bu günün tarihi : ');

   writeln(bugun.gun,'/',bugun.ay,'/',bugun.yil);

End.

 

Record bileşenleri, aynı türden başka değişkenlerden veri alabşlşr ya da onlara veri verebilir. Dolayısıyla, iki recordun aynı türden bileşenleri arasında veri alış verişi yapılabilir. Yukarıdaki programı biraz değiştirerek, bunun nasıl yapıldığını görebiliriz.

 

program yarin;

uses wincrt;

type

   tarih       = record

               gun,ay,yil : integer;

         end;

var

   bugun, yarin : tarih;

Begin

writeln('Bu gün ayın kaçıdır? ');

readln(bugun.gun);

writeln('Bu ay kaçıncı aydır? ');

readln(bugun.ay);

writeln('Bu yıl kaçıncı yıldır? ');

readln(bugun.yil);

 

   yarin.gun := bugun.gun + 1;

   yarin.ay  := bugun.ay;

   yarin.yil := bugun.yil;

   writeln('Yarının tarihi : ');

writeln(yarin.gun,'/',yarin.ay,'/',yarin.yil);

End.

 

Not: Bu programda, bugun değişkeni yerine ayın son günü girilirse, program yarının tarihini yanlış verecektir. Neden? Programda, bunu doğru verecek düzeltmeyi yapınız.

 

program record06;

uses wincrt;

type

   tarih_rec        =record

                 gun,ay,yil : integer;

               end;

   tarih_arr   = ARRAY[1..12] OF integer;

PROCEDURE Guncelle(var yarin : tarih_rec; gunler_arr : tarih_arr);

Begin

   yarin.gun := yarin.gun+1;

   if yarin.gun > gunler_arr[yarin.ay] then

           begin

               yarin.gun := 1;

               yarin.ay  := yarin.ay +1;

               if yarin.ay > 12 then

                       begin

                    yarin.ay := 1;

                    yarin.yil := yarin.yil + 1;

                         end

        end

End;

Var

   bugun_tarih : tarih_rec;

   gunler      : tarih_arr;

Begin

   gunler[1]:=31; gunler[2] :=28; gunler[3]:=31;  gunler[4] :=30;

   gunler[5]:=31; gunler[6] :=30; gunler[7]:=31;  gunler[8] :=31;

   gunler[9]:=30; gunler[10]:=31;gunler[11]:=30;  gunler[12]:=31;

 

writeln('Bu gün ayın kaçıdır? ');

readln(bugun_tarih.gun);

writeln('Bu ay kaçıncı aydır? ');

readln(bugun_tarih.ay);

writeln('Bu yıl kaçıncı yıldır? ');

readln(bugun_tarih.yil);

Guncelle(bugun_tarih,gunler);

writeln('Yarının Tarihi : ');

writeln(bugun_tarih.gun,'/',bugun_tarih.ay,'/',bugun_tarih.yil);

End.

 

 

Aynı türden iki record değişkeninin bileşenleri arasında, teker teker aktarma işlemleri yapılabildiği gibi, toplu aktarma da yapılabilir. Örneğin, aşağıdaki programda, zaman := bugun deyimi, bugun adlı recordun bütün bileşenlerinin değerlerini, aynı türden olan zaman recordunun bileşenlerine doğrudan aktarmaktadır.

program record05;

uses wincrt;

type

   tarih       =         record

                       gun,ay,yil : integer;

               end;

var

   bugun,zaman : tarih;

Begin

writeln('Bu gün ayın kaçıdır? ');

readln(bugun.gun);

writeln('Bu ay kaçıncı aydır? ');

readln(bugun.ay);

writeln('Bu yıl kaçıncı yıldır? ');

readln(bugun.yil);

   zaman           := bugun; 

   writeln('Zaman : ', zaman.gun,'/',zaman.ay,'/',zaman.yil);

End.

 

Record’lar bir procedure içinde parametre olarak kullanılabilir. Aşağıdaki örnek bunu göstermektedir.

 

program record07;

uses wincrt;

type

   zaman       = record

               saniye,dakika, saat : integer;

         end;

Var

   gecerli, next : zaman;

 

 

PROCEDURE Zaman_Guncelle(var simdi : zaman);

var

   yeni_zaman  :        zaman;

 

Begin

   yeni_zaman := simdi;

writeln('Verilen zaman : ‘);

writeln(yeni_zaman.saat,':',yeni_zaman.dakika,':',yeni_zaman.saniye);

yeni_zaman.saniye        := yeni_zaman.saniye + 1;

   if yeni_zaman.saniye >= 60 then

     begin

           yeni_zaman.saniye := 0;

           yeni_zaman.dakika       := yeni_zaman.dakika + 1;

     end;

        if yeni_zaman.dakika >= 60 then

          begin

                    yeni_zaman.dakika := 0;

              yeni_zaman.saat   := yeni_zaman.saat + 1;

          end;

        if yeni_zaman.saat >= 24 then

              yeni_zaman.saat := 0;

writeln;

   writeln('Yenizaman : ');

writeln(yeni_zaman.saat,':',yeni_zaman.dakika,':', yeni_zaman.saniye)

End;

 

BEGIN

writeln('Saat açtır? ');

readln(gecerli.saat);

writeln('dakika kaçtır? ');

readln(gecerli.dakika);

writeln('Saniye kaçtır? ');

readln(gecerli.saniye);

Zaman_Guncelle(gecerli);

End.

 

Record’lardan oluşan arrayler tanımlanabilir:

 

Type

    Tarih               :               RECORD

                                  Gun, ay, yil : integer

                                 END;

Var

    Dogum_Gunu : ARRAY[1..10] OF tarih;

 

bildirimi, recordlardan oluşan bir array tanımlar. Bunun bileşenlerine

 

Dogum_Gunu[1] .gun                := 24;

Dogum_Gunu[1] .ay                := 24;

Dogum_Gunu[1] .yil               := 24;

 

biçimindeki deyimlerle erişilebilir.

 

Record bileşenleri  array olabilir:

 

Type

    Ay_adi               =               PACKED ARRAY[1..4] OF char;

    Ay               =               RECORD

                                 Gunler : integer;

                                 Ad       : ay_adi;

                                 END;

Var

    Bu_ay               : ay;

 

Bildiriminden sonra,

 

               Bu_ay.gun := 30;

               Bu_ay.ad[1] := ‘N’;

               Bu_ay.ad[2] := ‘I’ ;

               Bu_ay.ad[3] := ‘S’ ;

Bu_ay.ad[4] := ‘A’ ;

Bu_ay.ad[5] := ‘N’ ;

 

atamaları geçerlidir.

 

İç-içe record tanımlanabilir:

 

Type

    Tarih               :               RECORD

                                  Gun, ay, yil : integer

                                             END;

 

Zaman    =               RECORD

                              Dogum_gunu       : tarih;

                              Kayit_Gunu         :