C#nedir?com
 
YAZAR HAKKINDA
Çiğdem Çavdaroğlu
Çiğdem Çavdaroğlu
http://www.csharpnedir.com/
İletişme geçmek için tıklayın.
28 Makalesi yayınlanmakta.
Yazar hakkında detaylı bilgi için tıklayın.
Yayınlanan diğer makaleleri için tıklayın.
İlgili etiketler: adresini bellekte degeri eleman elemani elemanina iliskin isimli karakter kaydin listede listedeki listenin listeye record C / Sys Prog. Çiğdem Çavdaroğlu
 
YAZI HAKKINDA
Türü : Makale
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
Seviyesi : Orta
Kategori : C / Sys Prog.
Yayınlanma Tarihi : 25.4.2005
Okunma Sayısı : 17804
Yorum Sayısı : 0     yorum yaz
Site İçi AramaSİTE İÇİ ARAMA
Üye Girişini AçÜye GİRİŞİ
Üye girişi için tıklayın.
Kullanıcı Adı
Şifre
 
Beni her zaman hatırla
Bir hafta boyunca kullanıcı bilgilerinizi kullanıcı çıkışı yapana kadar hatırlar. (Paylaşılan bilgisayarlarda önerilmez.)
 
Şifremi / Kullanıcı Adımı unuttum.
 
.net TV RSS Serbest KÖŞE (?)
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
emre TAŞ
XML - Deniz Kılınç
emre TAŞ
yazının devamı >
emre TAŞ
Decompiling and Reverse Engineering .Net Radyo
emre TAŞ
yazının devamı >
emre TAŞ
Masaüstü mü ? İnternet Mi? .Net Radyo
emre TAŞ
yazının devamı >
emre TAŞ
.Net Kavramları - .Net Radyo
emre TAŞ
yazının devamı >
emre TAŞ
Yeni Başlayanlar için - .Net Radyo
emre TAŞ
yazının devamı >
Makale Gönder Bende Yazmak İstiyorum
.net TV RSSBlogroll
Turhal Temizer 'in Blogu
Conda install environment.yml Package 31.3.2020
Turhal Temizer 'in Blogu
Mac OS/X Removing CUDA 31.3.2020
Burak Selim Şenyurt
Sekiz Saatlik Sonsuz Döngü 31.3.2020
Burak Selim Şenyurt
Switch Case Kullanmadan Kod Yazılabilir mi? 31.3.2020
  Diğer Herşey
Sponsorlar
BT Akademi
Medya Portakal
Video Hosting Sponsoru
Csharpnedir.com bir Ineta üyesidir
Uzman Abi
Her Yönüyle C# - Sefer Algan
Karakter Katarları Üzerinde İşlemler ve Bağlı Liste Uygulaması - 1
 
Kapat
Sayfayı Yazdır Sık Kullanılanlara Ekle Arkadaşıma Gönder MySpace Del.Ico.Us Digg Facebook Google Mixx Reddit StumbleUpon


Bu yazı dizisinde, C dilinde karakter katarlarına (string) ilişkin çeşitli işlemlerin nasıl yapıldığını inceleyeceğiz. İlk olarak, karakter katarlarına ilişkin genel bir bilgi vereceğiz. Ardından öğrencilere ilişkin notların tutulmasında kullanacağımız bir bağlı liste yapısı oluşturacağız. Daha sonra arama, sıralama, ekleme, silme gibi işlemleri yapacak bir takım fonksiyonlar yazacağız. Bu fonksiyonları, oluşturduğumuz bağlı listeye uygulayacağız. Uygulama bittiğinde elimizde, öğrencilere ilişkin notları tutabildiğimiz, arama işlemleri yapabildiğimiz, sıralayabildiğimiz bir programımız olacak. Yapı içerisinde küçük değişiklikler yaparak, kendi programınızda kullanabileceğiniz bir hale getirebileceksiniz.

C dilinde karakter katarları için özel bir tür tanımlanmamıştır. Bilindiği gibi bir tamsayı değeri int türünden bir değişkende, ondalıklı sayı değeri double ya da float türünden bir değişkende, karakter türünden bir değer char türünden bir değişkende saklanmaktadır. Karakter katarları, karakterlerden oluşan diziler olarak tanımlanabilir. C dilinde karakter katarlarını tutmak için de zaten karakter dizileri kullanılmaktadır. Nesne yönelimli programlama dillerinin pek çoğunda karakter katarları genellikle "string" olarak isimlendirilen sınıflarda tutulmaktadır. C dilinde karakter katarlarını tutmak ve çeşitli işlemleri yapabilmek için kendi kütüphanelerimizi oluşturup işleri kolaylaştırabiliriz. Karakter katarları çift tırnak içerisinde yazılırlar. C derleyicileri, çift tırnak içerisinde gördükleri her ifadeye, karakter katarı muamelesi yaparlar. Karakter katarını alarak sonuna null karakter (’\0’) ekler, bellekte güvenilir bir bölgeye yerleştirir ve (char *) türünden adres üretir. Karakter katarı tanımlamalarına bir göz atalım :

char *str = "C programlama dili";

Bu tanımlama ile derleyici, "C programlama dili" katarı için derleme zamanında bellekte bir yer belirler ve str isimli göstericiye bu yerin adres değerini atar. Karakter katarları, belleğin salt okunur kısmında tutulduğu için, değiştirilmeleri tanımsız davranışa yol açar. Çift tırnak içerisinde yazılmış bir ifadeyi, char türünden bir diziye de atayabiliriz :

char str[30] = "C programlama dili" ;

Bu durumda artık çift tırnak içerisindeki ifade bir adres belirtmez. Karakter katarının her bir karakteri str isimli dizinin elemanlarına atanır. Karakter katarları, global değişkenler olduğu gibi statik ömre sahiptirler. Programın yüklenmesi ile bellekte yer alırlar ve program sonlanana kadar bellekte kalırlar. (Bu nedenle çok programda çok fazla karakter katarı kullanmak belleğe yük bindirecektir.)

Uygulamamız için oluşturacağımız liste, öğrencinin adını ve öğrenciye ilişkin not değerini tutacak. Bu nedenle yapımızın öğrenci adını tutacak (char *) türünden bir veri elemanı ve notu tutacak tamsayı türünden bir veri elemanı olacak. Bir liste yapısı oluşturacağımız için, listedeki bir sonraki elemana ulaşmamızı sağlayacak bir de gösterici veri elemanımız olacak. Yapımızı oluşturmaya başlayabiliriz. Öncelikle bir kayda ilişkin bilgileri tutacağımız "record" isminde bir yapı tanımlayalım :

typedef struct _record {
     char *rName;
     int rNumber;
     struct _record *rNext;
}record;

Yapıyı tanımlarken typedef bildirimini de yapıyoruz, bundan sonra bu yapının ismini "record" olarak kullanabileceğiz. Yapının elemanlarını inceleyelim : (char *) türündeki rName isimli veri elemanı kaydı yapılmakta olan öğrencinin adını tutacak. Tamsayı türündeki rNumber isimli veri elemanı öğrencinin notunu tutacak. (struct _record *) türündeki rNext isimli gösterici veri elemanı ise liste içerisinde bu öğrenciden sonra gelen kaydın adresini tutacak. Liste içerisinde dolaşabilmek için bu veri elemanını eklememiz gereklidir. Çünkü listede sadece ilk kayda ilişkin adres değerini tutacağız. Listedeki diğer kayıtlara bu gösterici aracılığıyla erişeceğiz. Şimdi de liste yapımızı tanımlayalım :

typedef struct _recordList {
     record *start;
     int size;
}*recordList;

Bu yapının typedef bildirimini de tanımlama sırasında yaptık. Ancak bu bildirim öncekinden biraz daha farklı. İsmin önünde (*) içerik operatörü yer alıyor. "recordList" türünden bir nesne tanımladığımızda artık bu nesnenin türü (struct _recordList *) olacak. Yapının elemanlarını inceleyelim : (record *) türündeki start isimli veri elemanı listede bulunan ilk öğrenci kaydının adresini tutacak. Tamsayı türündeki size isimli eleman ise listedeki eleman sayısını tutacak. Burada, sadece ilk öğrenci kaydının adresini tutmanın yeterli olduğuna dikkat edin. Her kaydın içinde bir sonraki kaydın adresi de saklandığına göre diğer kayıtlara record yapısındaki veri elemanı yoluyla ulaşacağız. Oluşturduğumuz yapıyı bir şema ile gösterelim :



Bağlı listemize ilişkin fonksiyonları yazmaya geçebiliriz. İlk olarak liste için bellekte yer ayıracak bir fonksiyon yazmalıyız. Bağlı liste yapımız kendi içerisinde bir yapı daha içerdiği için bu yapıya ilişkin bir başlangıç fonksiyonu da yazmalıyız. Önce buradan başlayalım :

record *CreateRecord(void);    /*Prototip bildirimi*/

record *CreateRecord(void)
{
    record *rH;
    rH = (record *)malloc(sizeof(record));  /*rH nesnesi için bellekte dinamik olarak yer ayrılıyor */

    if (rH == NULL)                                /*Yapılan dinamik bellek ayırma işleminin başarısı kontrol ediliyor */
    {
        printf("Bellek Yetersiz\n");
        exit(EXIT_FAILURE);
    }
    return rH;
}


CreateRecord isimli fonksiyonda, record türünden bir gösterici tanımlanıyor. Bu gösterici için dinamik olarak, record nesnesinin bellekte kapladığı yer kadar (sizeof(record)) yer ayrılıyor. Yer ayırma işleminin başarısı kontrol ediliyor. Eğer işlem başarısız olmuşsa (exit) fonksiyonu ile program sonlandırılıyor. İşlem başarılı olmuşsa rH nesnesi döndürülüyor. Listemizin başlangıç fonksiyonunda bu fonksiyonu kullanacağız. Şimdi listemizin başlangıç fonksiyonunu yazalım :

recordList CreateList(void);        /*Prototip bildirimi */

recordList CreateList(void)
{
      recordList pRL = (recordList)malloc(sizeof(*pRL));    /*pRL nesnesi için dinamik olarak yer ayrılıyor */

      if (pRL == NULL)                                                /*Yapılan dinamik bellek ayırma işleminin başarısı kontrol ediliyor */
      {
          printf("Bellek Yetersiz\n");
          exit(EXIT_FAILURE);
      }

      pRL->start = NULL;
      pRL->size = 0;
      return pRL;
}


CreateList isimli fonksiyonda, recordList türünden bir gösterici tanımlanıyor. Bu gösterici için dinamik olarak, recordList nesnesinin bellekte kapladığı yer kadar (sizeof(*recordList)) yer ayrılıyor. Yer ayırma işleminin başarısı kontrol ediliyor. Eğer işlem başarısız olmuşsa (exit) fonksiyonu ile program sonlandırılıyor. İşlem başarılı olmuşsa pRL göstericisinin gösterdiği nesnenin veri elemanlarına ilk değerleri atanıyor. Göstericinin gösterdiği nesnenin start isimli veri elemanına NULL değeri atanıyor. start veri elemanı listedeki ilk elemanın adresini tutacak. NULL değer atanmasının sebebi, liste yeni oluşturulduğu için listede henüz hiç eleman olmamasıdır. Aynı sebepten ötürü, listedeki eleman sayısını tutacak olan size isimli veri elemanına da sıfır değeri atanıyor. Listeye eleman ekledikçe size elemanının değeri bir artırılacaktır, start elemanına ise listeye eklenen elemanın adresi atanacaktır. Şimdi listemize eleman ekleyeceğimizi görelim. Listeye bir eleman eklenirken, eklenecek değerler ile record türünden bir nesne oluşturulmalıdır. Bunun için öncelikle bu işi yapacak bir fonksiyon yazmalıyız :

void SetRecord   (record *pRecord, char *name, int number); /* Prototip bildirimi */

void SetRecord  (record *pRecord, char *name, int number)
{
    /* Parametre olarak gelen değerler nesneye atanıyor. */
    pRecord->rName = name;
    pRecord->rNumber = number;
    pRecord->rNext = NULL;
}


Fonksiyonumuz, parametre olarak geçilen name ve number isimli değişkenlerin değerlerini pRecord göstericisinin gösterdiği nesneye atıyor. Bu fonksiyonun çağrılmasıyla artık elimize ilk değerleri atanmış bir record nesnesi olacaktır. Bu nesneyi listemize eklemeliyiz. Bunu da şöyle bir fonksiyon ile yapabiliriz :

void AddRecordStart (recordList rList, char *name, int number);      /* Prototip bildirimi */

void AddRecordStart (recordList rList, char *name, int number)
{
    record *addRecord = CreateRecord();
    SetRecord(addRecord,name,number); /* record türünden nesnemize değerler atanıyor */

    addRecord->rNext = rList->start; /*record türünden nesnemiz, listeye ekleniyor */
    rList->start = addRecord;
    rList->size++;
}


Fonksiyonumuz parametre olarak oluşturulacak listenin adresini tutan bir gösterici, öğrencinin adını tutacak name isimli (char *) türünden bir gösterici ve öğrencinin notunu tutacak number isimli int türünden bir nesne alarak, kaydı listenin başına eklemektedir. Fonksiyonun başlangıcında öncelikle record türünden bir gösterici tanımlanarak, malloc fonksiyonu ile dinamik olarak bellekte yer ayrılıyor. Daha sonra az önce yazmış olduğumuz SetRecord isimli fonksiyon çağrılıyor. Fonksiyona parametre olarak, record türünden göstericimiz ve kayda ilişkin değerleri tutan name göstericimiz ve number nesnemiz geçiliyor. Şimdi, oluşturduğumuz bu kaydı listenin başına eklememiz gerekli. Şu haliyle listenin başında bulunan kayıt ise yeni ekleyeceğimiz kayıttan bir sonraki konumda yer alacaktır. Bu nedenle ekleyeceğimiz kaydın rNext isimli veri elemanına şu anda listenin başında bulunan kaydın adresini atıyoruz. Listemizin start isimli veri elemanına ise yeni oluşturduğumuz kaydın adresini atıyoruz. Kayıt eklenmeden önce listede bir eleman olduğunu farz ederek kayıt ekleme işlemini şema ile gösterelim :



Kayıt listeye eklendikten sonra listenin eleman sayısını tutan size isimli değişkenin değerini de bir artırıyoruz. Şimdi de listemizin sonuna bir kayıt ekleyecek fonksiyonumuzu yazalım. Bu fonksiyonun kodu, aşağı yukarı AddRecordStart isimli fonksiyonun kodu ile aynı olacak. Fark, kaydın listeye eklenmesi sırasında ortaya çıkacak. Ekleyeceğimiz kaydın, rNext isimli veri elemanına NULL değeri atanacak. Çünkü kayıt, listenin sonunda yer alıyor. Ancak, kayıt eklenmeden önce listenin sonunda bulunan kaydın rNext isimli veri elemanına da, yeni ekleyeceğimiz kaydın adresi atanmalı. Ancak listemizde son kaydı tutan bir veri elemanımız yok. O halde öncelikle listedeki son elemanı bulacak bir fonksiyon yazmalıyız :

record *GetLastRecord(recordList list); /* Prototip bildirimi */

record *GetLastRecord(recordList list)
{
    if (list->size == 0)
       return NULL;

    record *tmpRecord = list->start;

    while (tmpRecord->rNext != NULL)
         tmpRecord = tmpRecord->rNext;

    return tmpRecord;
}


Listedeki son kaydı bulacak fonksiyonumuzda, listedeki kayıtları dolaşırken kullanacağımız (record *) türünden geçici bir gösterici tanımlıyoruz. Eğer listede hiçbir eleman yoksa fonksiyon NULL değere geri dönecektir. Bu durumu fonksiyonun başında kontrol ediyoruz. tmpRecord isimli göstericiye listenin ilk başındaki kaydın adresini atıyoruz. While döngüsü, geçici tmpRecord göstericisinin rNext isimli veri elamanının değeri NULL değer olmadığı sürece dönecek. Eğer rNext isimli veri elemanının değeri NULL değer ise listenin sonuna ulaşılmış demektir. Döngüden çıkıldığı noktada tmpRecord göstericisinde listedeki son eleman kayıtlı durumdadır. Şimdi kaydı liste sonuna ekleyecek fonksiyonumuza geçelim :

void AddRecordEnd (recordList, char *name, int number);       /* Prototip bildirimi */

void AddRecordEnd(recordList rList, char *name, int number)
{
    record *lastRecord;
    record *addRecord = CreateRecord();
    SetRecord(addRecord,name,number);

    lastRecord = GetLastRecord(rList);
    srList->size++;
    addRecord->rNext = NULL;

    if (lastRecord == NULL)
    {
       rList->start = addRecord;
       return;
    }

     lastRecord->rNext = addRecord;
}

(record *) türünden addRecord isimli göstericinin gösterdiği nesneye, listeye eklenecek kayda ilişkin verileri atadık. Önceki fonksiyona ilaveten, burada son kayda da ihtiyacımız olacak. Bu nedenle (record *) türünden lastRecord isimli bir gösterici tanımladık ve bu göstericiye GetLastRecord isimli fonksiyondan dönen değeri atadık. Ancak eğer listede hiç eleman yoksa, fonksiyon NULL adrese dönüyordu. Bu durumu da kontrol etmeliyiz. Eğer listede hiç eleman yoksa, sona eklediğimiz bu eleman listenin hem başındaki hem de sonundaki eleman olacaktır. Bu durumu sağlamak için listenin start isimli veri elemanına yeni eklediğimiz kaydın adresini atadık. Kaydın rNext isimli veri elemanına da NULL adres değerini atadık. Listede kayıt var ise, son kaydın rNext isimli veri elemanına, yeni eklediğimiz kaydın adresini atadık. Yeni eklediğimiz kaydın rNext isimli veri elemanına yine NULL değer atadık.

Şimdi de listemizdeki kayıtları ekrana yazdıracak bir fonksiyon yazalım :

void DisplayList(recordList rList); /* Prototip bildirimi */

void DisplayList (recordList rList)
{
    record *rs;

    for (rs = rList->start; rs != NULL; rs = rs->rNext)
    {
         printf("Adi : ");
         puts(rs->rName);
         printf("Numarasi : %d\n",rs->rNumber);
    }
}

Fonksiyonun başında, listedeki kayıtları dolaşırken kullanacağımız (record *) türünden rd isimli geçici bir gösterici tanımladık. rs göstericisine ilk değer olarak listenin en başındaki elemanın adresini atadık. for döngüsünün her adımında, rd göstericisinin değerinin NULL adres olup olmadığı kontrol ediliyor. Eğer rs göstericisi NULL adrese işaret ediliyorsa listenin sonuna gelinmiş demektir. Döngünün her adımında, rs göstericisine, rs göstericisinin gösterdiği nesnenin rNext isimli veri elemanının değerini atadık. Bu değer, liste içerisinde, rs göstericisinin gösterdiği nesneden bir sonra gelen kaydın adresidir. Bu şekilde tüm liste dolaşılarak kayıtlara ilişkin bilgiler ekrana yazdırılır.

Bir sonraki makalemizde bağlı liste yapımıza yeni fonksiyonlar ekleyeceğiz. Makaleye ilişkin uygulamayı indirmek için tıklayınız.

Mutlu ve huzurlu günler...

 

Makale:
Karakter Katarları Üzerinde İşlemler ve Bağlı Liste Uygulaması - 1 C ve Sistem Programlama Çiğdem Çavdaroğlu
  • Yazılan Yorumlar
  • Yorum Yaz
Bu konu hakkında yayınlanan yorum bulunmamaktadır.
"Yorum Yaz" tabını kullanarak sizde yorumlarınızı yazabilirsiniz.
Yorum yazabilmek için üye girişi yapmalısınız. Üye girişi için tıklayın.
Üye değilseniz Üyel Ol linkine tıklayarak üyeliğinizi hemen başlatabilirisniz.
 
  • Bu Konuda Son 10
  • Eklenen Son 10
  • Bu Konuda Geçmiş 10
Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor