Eki122009

Fonksiyonlara Parametre Geçirmek

Yazan : Admin    12.10.2009 | C Notları

C dilinde fonksiyonlar, ana programın yaptığı işleri paylaşan alt programlar olarak düşünülebilir. Bu sebeple C dilinde fonksiyonlar çok önemli değere sahiptir. Fonksiyonlar yaptıkları işe bağlı olarak bazen ihtiyaç duyduğu bir takım bilgileri de çağrıcıdan talep ederler. Böyle durumlarda çağrıcı bu fonksiyonlara ihtiyacı olan bilgileri parametreler yardımıyla iletirler.

Fonksiyonların ihtiyaç duyduğu bu bilgileri iletmenin iki farklı yöntemi vardır. Bu yöntemlerden birincisine değer ile geçirme, ikincisine ise referans ile geçirme adı verilir. Bu iki yöntemi izah ederken gelin bir örnek üzerinde bu yöntemleri anlamaya çalışalım.

Öncelikle son zamanlarda karşılaştığım bir bilgiden bahsedeyim. “Yerinde Servis” denen bu uygulama ile aldığınız ürün arıza yapınca bu ürünü teknik servise götürmek yerine teknik servise haber veriyorsunuz ve teknik arkadaşlar gelip sorunu ürünün bulunduğu yerde çözmeye çalışıyorlar. Bu yöntem müşteri olarak benim çok hoşuma gitti. Ne kadar kullanılıyor bilmiyorum ama güzel bir gelişme olduğunu söylemeliyim.

Konumuza geri dönersek, şimdi sizin bilgisayarınızın arızalandığını düşünelim. Sizde doğal olarak teknik servisi arıyorsunuz ve arızayı bildiriyorsunuz. Onlarda bilgisayarı servisimize getirin ve tamiratını yapalım diyorlar. (Bu her zaman bu kadar kolay olmaz tabi J) Bunun üzerine sizde bilgisayarınızı koltuğunuzun altına alıp servisin yolunu tutuyorsunuz. Gerekli tamirat yapılıyor ve teslim alıp eve geri dönüyorsunuz.

Gelin şimdi bu senaryoyu bir bilgisayar programı olarak modelleyelim. Siz evinizde oturuyorsunuz yani ana program bellekte oturuyor ve bir ihtiyaç çıkıyor. (Bilgisayar tamiri) Siz bunun için teknik servisi aradınız ama programın böyle bir şansı yok tabi ama o da bir fonksiyona çağrıda bulunabilir ve o da öyle yapıyor. Siz arızayı bildirdiniz onlarda size bilgisayarı oraya götürmenizi söyledi. Dolayısıyla fonksiyonumuzda ana programdan bilgisayarı istemeli, o vakit fonksiyonumuz şöyle olmalı

Bilgisayar TeknikServis(Bilgisayar nesne);

Burada fonksiyonumuz çağrıcıdan Bilgisayar tipinde bir nesne istiyor. Yani bilgisayar nesnesini kendi bulunduğu konuma göndermesini istiyor. Teknik servisin sizden istediği gibi, tamir yapılıyor ve bilgisayar geri alınıyor. İşte bu şekilde fonksiyonun istediği bilginin fonksiyona gönderilmek suretiyle fonksiyonun işletilmesine değer ile çağırma diyoruz.

Şimdi ise bu senaryomuzu yukarıdaki “Yerinde Servis” bilgisinden faydalanarak tekrar düzenlemeye çalışalım. Siz yine arıza için teknik servisi aradınız, bilgisayarı götürmek istemiyorsunuz ve çok meşgulsünüz, bu sefer diyorsunuz ki ben yerinde servis istiyorum. Bu sefer teknik servis yetkilileri sizden bilgisayarı değil bilgisayarın bulunduğu adresi isteyeceklerdir. Bu durumda teknik servis yetilileri sizin adresinize gelecek ve arızayı düzelteceklerdir. Bunun gibi ana program da fonksiyonu çağırdığında fonksiyon ondan Bilgisayar nesnesi değil, onun bulunduğu adresi isteyecektir. Buna göre yazılmış temsili fonksiyonda şöyle olmalı

void TeknikServis(Bilgisayar * nesne);

Burada “*” işaretiyle fonksiyona bir bilgisayar değil bir bilgisayarın bulunduğu konumun adresini gönderdiğimizi belirtiyoruz. Ardından fonksiyon bu adrese ulaşarak gerekli işlemleri yerine getiriyor. İşte bu şekilde fonksiyona istediği bilginin adresini göndermek suretiyle fonksiyonun işletilmesine referans ile çağırma diyoruz.

Tabi gerçek hayat senaryomuzla bilgisayar sistemi birebir örtüşmüyor. Yani siz bilgisayarın kendisini alıp götürürken, ana programın gönderdiği nesnenin bir kopyası oluşturuluyor ve fonksiyon bunun üzerinde çalışıyor, bundan dolayı ana programdaki nesnede bir değişiklik olmuyor. Diğer taraftan referansla çağırma örneğimizdeki durum birebir geçerlidir.

Şimdi size bana bu iki çağırma yöntemi arasındaki farkı açıkça ortaya koyan güzel bir örnekten bahsetmek istiyorum. 10 MB büyüklüğündeki renkli resim dosyanızı bir resim programı ile siyah-beyaza çevirmek istediğinizi düşünelim. Bunun için program içindi resim dosyanızı açtıktan sonra (yeni belleğe yükledikten sonra) program içinde siyah-beyaza çevir komutu verdiniz. Bu esnada ana programın bu işlem için siyahbeyaza_cevir isminde bir fonksiyona çağrıda bulunduğunu düşünelim. Eğer bu fonksiyonu değere göre çağırırsak doğal olarak bu fonksiyon bizden çevireceği resim dosyasını isteyecektir. Fonksiyon resim dosyasının bir kopyası ile çalışacağı için resim dosyasının bir kopyası oluşturulacak ve bellekte 10 MB asıl + 10 MB kopya olmaz üzere 20 MB alan bu dosya için tahsis edilecektir. Oysa referansa göre çağırmış olsaydık fonksiyona sadece resim dosyasının adresini geçirmek yeterli olacaktı.

Referansa göre geçirme özellikle büyük boyutlu dosyalarla çalışırken kullanılabilecek oldukça etkili bir tekniktir. Programcı olarak bizlerin bilmesi gereken bu teknikleri doğru yerde ve doğru zamanda kullanarak etkili programlar geliştirmektir. Programlama sanatında ortaya güzel eserler çıkarmak isteyenler için bu detaylar vazgeçilmez öneme sahiptir.

 

 



[KickIt] [Dzone] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Etiketler: ,

E-mail | Permalink | Trackback | Post RSSRSS comment feed 0 Yorum

Ağu242009

Sıralı Bağlı Liste (Öncelik Kuyruğu)

Yazan : Zafer    24.08.2009 | C Notları

Bağlı listelere elemanları baştan veya sondan ekleyebilirsiniz. Bu sizin tasarladığınız liste ile ilgilidir. Ancak bu listede aramak yapmak veya listeyi sıralamak istediğiniz zaman işler biraz karışır çünkü bağlı listelerde doğrusal hareket edersiniz. Bundan dolayı her defasında bağlı listenin bir sonraki düğümüne ilerlersiniz.

Böyle bir duruma ilk baştan bir çözüm bulmak isterseniz imdadınıza Öncelik Kuyruğu (Priority queue) adı verilen teknik yetişir. Bu teknikte amaç, listeye elemanları eklerken listenin sıralı düzenini bozmadan bu eklemeyi yapmaktır. Böylece listeye tüm elemanları eklediğinizde elinizde sıralı bir liste olacaktır. Bununla ilgili örnek bir uygulamaya ait kodları aşağıya ekliyorum. Bu kodda rastgele 0-100 arasında oluşturulan 25 sayı bir bağlı listeye sıralı bir şekilde ekleniyor ve sonra bu sıralı liste ekrana yazdırılıyor. Sorularınız olursa yardımcı olmaya çalışırım. Tüm okuyucularıma sağlık ve mutluluk dilerim.

 

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

struct yiginDugumu {
    int                 data;
    struct yiginDugumu* sonraki;
};

void ListeyeEkle(struct yiginDugumu** ilkDugum, int data);

int main()
{
    struct yiginDugumu* basDugum = NULL;
    struct yiginDugumu* say;
    int i;

    srand(time(NULL));

    for (i=0; i<25; i++){
        ListeyeEkle(&basDugum, rand() % 99 +1);
    }

    for (i=0, say=basDugum; say != NULL; i++, say = say->sonraki) {
        printf("%d-> %d\n", i, say->data);
    }

    return 0;
}

void ListeyeEkle(struct yiginDugumu** ilkDugum, int data)
{
    struct yiginDugumu* gecerliDugum = *ilkDugum;
    struct yiginDugumu* yeniDugum;
    struct yiginDugumu* oncekiDugum = NULL;

    yeniDugum = malloc(sizeof(struct yiginDugumu));
    yeniDugum->data = data;
    yeniDugum->sonraki = NULL;

    while (gecerliDugum != NULL && gecerliDugum->data < data) {
        oncekiDugum = gecerliDugum;
        gecerliDugum = gecerliDugum->sonraki;
    }

    if (oncekiDugum == NULL) {
        *ilkDugum = yeniDugum;
    }
    else {
        oncekiDugum->sonraki = yeniDugum;
    }

    yeniDugum->sonraki = gecerliDugum;
}



[KickIt] [Dzone] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Etiketler: , , ,

E-mail | Permalink | Trackback | Post RSSRSS comment feed 0 Yorum

Ağu212009

Bağlı Listeler (Linked List)

Yazan : Zafer    21.08.2009 | C Notları

C dilinde birden fazla değer atamak ve bu değerlerle çalışmak için dizileri kullanırız. Buna rağmen programımız gelişmeye başladıkça dizilerin bizim için yetersiz kaldığınıda görmekteyiz. Bu durumda yeni yapılara ihtiyaç olmaktadır. Bu yapılardan birisi bağlı listelerdir. (linked list)

Bağlı listeler kendine dönüşlü yapılardan (struct) faydalanarak elde eldilen ve içeriklerinde bulunan bir bağ elemanı sayesinde birbirlerine bağlanan yapı öbeğidir. Bu tanım çok açık gibi gözükmüyor, isterseniz alttaki resim üzerinde tanımlarımıza devam edelim, sanıyorum bu daha anlaşılır olacak.

Bagli Liste


Yukarıdaki şekilde de göründüğü gibi her bir yapının bağ elemanı bir sonraki yapının adresini gösteriyor. Bu yapılara bağlı liste üzerindeki düğümler deniliyor. Bu sayede ilk düğümden başlayıp tüm bu listeyi bağ elemanlarının yardımıyla dolaşma yeteneğine sahip oluyoruz. Bunun yanında çalışma zamanında yeni düğümler oluşturup bunlarıda listeye ekleyerek listemizi genişletebilir veya düğüm silerek listemizi küçültebiliriz.

Tüm bunlardan sonra basit bir bağlı liste kod örneği ile yazımızı sonlandıralım. Kodlamada amacım listeye odaklanmak oldugu için bazı bellek kontrollerini ihmal ettim. Gerçek programlarda ise bu tür kontrolleri mutlaka yapmalıyız. Tüm okuyucularıma sağlık ve mutluluk dilerim.

 

#include <stdio.h>
#include <stdlib.h>

struct dugum {
    int veri;
    struct dugum* sonraki;
};

int main() {
    struct dugum * basDugum = NULL;
    struct dugum * geciciDugum;
    int i;

    /* basDugum icin bellekte yer ayir ve adresini ver */
    basDugum = (struct dugum *) malloc(sizeof(struct dugum));
    /* basDugumu geciciDugume al (basDugumu kaybetmeyi istemeyiz.) */
    geciciDugum = basDugum;

    for(i=0; i<10; i++) {
        geciciDugum->veri = i * 10;

        /* geciciDugum bag elemani icin bellekten yeni bir yer ayir ve adresi bag elemanina ata */
        geciciDugum->sonraki = (struct dugum *) malloc(sizeof(struct dugum));

        /* geciciDugumu bir sonraki dugume (yeni dugume) ilerlet */
        geciciDugum = geciciDugum->sonraki;
    }

    /* gecicidDugum (son dugum) bag elemanina NULL ata */
    geciciDugum->sonraki = NULL;

    printf("Bagli liste dokumu : \n");

    /* geciciDugum'e basDugum adresi ata (listenin ilk dugumune donduk.) */
    geciciDugum = basDugum;

    /* dugumun bag elemanı NULL oluncaya kadar degerleri yaz ve sonraki dugume gec */
    while (geciciDugum->sonraki != NULL) {
        printf("-> %d\n",geciciDugum->veri);
        geciciDugum=geciciDugum->sonraki;
    }

    return 0;
}



[KickIt] [Dzone] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Etiketler: , ,

E-mail | Permalink | Trackback | Post RSSRSS comment feed 0 Yorum

May262009

Mevduat faizi hesaplama

Yazan : Zafer    26.05.2009 | C Notları

C ile yaptığım çalışmalar esnasında ortaya çıkan bazı güzel programları burada daha önce de paylaşmıştım. Şimdi işinize yarayabileceğini düşündüğüm, mevduat faizi nasıl hesaplanır sorusundan yola çıkıp bu hale getirdiğim projemi sizlerle paylaşmak istiyorum. Kodlarin içine yaterince açıklama eklemeye çalıştım ama anlmadığınız nokta olursa bana sorabilirsiniz. Sizlere yardımcı olmaya çalışırım. İlgilenenler için kodlar ve çalışan dosyayı aşağıda veriyorum.

 

CodeBlocks Proje Dosyası : MyFinans.rar (274,86 kb)
C Kod Dosyası : MyFinans_c.rar (2,03 kb)
Çalışan Dosya : MyFinans_exe.rar (93,83 kb)



[KickIt] [Dzone] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Etiketler: , ,

E-mail | Permalink | Trackback | Post RSSRSS comment feed 0 Yorum

Şub282009

C dilinde string ifadeler, iki yana yasla

Yazan : Zafer    28.02.2009 | C Notları

Karekter dizileri ile olan çalışmalarıma devam ediyorum. Bu çerçevede bu gün siz değerli okurlarımla "ayarla_project" isimli projemi paylaşmak istiyorum. Bu projenin konusuna gelince, hepimizin bildiği gibi bir çok kelime işlem programında "iki yana yasla" olarak adlandırılan bir işlem vardır. Bu işlem paragraftaki kelimelerin arasına boşluk ekleyerek sağdan ve soldan aynı hizada olmalarını sağlar. Bu şekilde paragraf daha güzel bir görüntüye sahip olur.

Bu konudan hareketle bende C dilinde bu işlemi gerçekleştirmeyi düşündüm ve orataya "ayarla_project" projesi çıktı. Kodları kısaca özetlemek gerekirse. Öncelikle paragraftan belirlediğimiz kadar karekteri okuyoruz. Bu bizim için bir satırı temsil ediyor, burada şöyle bir sorun olabilir, okuma işlemini bitirdiğimizde bir kelime sonlanmamış olabilir. Örneğin okunan son kelimenin tamamı "zafer" olsun ancak biz karekter sınırımızdan dolayı sadece "zaf" kısmını okumuş olalım bu durumda bu kelime okunan içerikten tamamen kaldırılıp sonraki satırda işleme alınmalı. Program bu durumu kontrol edip düzelttikten sonra ise oluşturduğumuz satır uzunlugu ve olması gereken uzunluktan faydalanarak satıra kaç tane boşluk ekleyeceğimizi hesaplıyoruz. Son olarak ise boşlukları ekleyip satırı ekrana yazıyoruz.

Kodların içinde yaptıkları işlerle ilgili açıklamalar bulacaksınız ancak bunlar yeterli olmazsa ilgilenen okurlarım için küçük çaplı bir dökümanda hazırladım. PDF formantındaki doküman, kullanılan kütüphaneler, sabitler ve fonksiyonlar hakkında bilgi içeriyor. Bu döküman proje klasörü içinde "doc" isimli klasörde bulunuyor. Tüm bu açıklamalardan sonra hala kafanıza takılan sorular varsa bana her zaman sitedeki iletişim bölümünden veya e-posta adresimden ulaşabilirsiniz. Tüm okuyucularıma sağlık ve mutluluk dilerim.

       CodeBlocks Proje Dosyası : ayarla_project.rar (377,56 kb)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define SATIR_UZUNLUGU 79
#define BOSLUK ' '

void IkiYanaYasla(const char *str);
void SatiriDuzenle(char birSatir[], int boslukAdet);
void SatirUzunluguAyarla(const char *str, char birSatir[], int baslangicKonumu);
int SonBoslukBul(char birSatir[]);

int main()
{
    char *string = "Tarim Bakanligi iki onemli programla kucuk olcekli girisimcilere ve yatirimlarini buyutmek isteyen "
                   "KOBI'lere destek veriyor. Bunlardan ilki olan Koy Bazli Yatirim Programi dahilinde, belirlenen 16 ildeki "
                   "her bir tarimsal urun isleme tesislerine minimum 35 bin dolarlik hibe kaynak kullandirilacak. Diger "
                   "program olan Tarimsal Kalkinma Programi bunyesinde ise toplam 250 milyon YTL tutarinda kaynak, "
                   "yatirimci bekliyor. Bu yil icinde baslatilan her iki program da 2006-2010 yillari arasinda.";

    IkiYanaYasla(string);

    return 0;
}

void IkiYanaYasla(const char *str)
{
    char birSatir[SATIR_UZUNLUGU];
    int index = 0;
    int basla = 0;

    while (basla < strlen(str))
    {
        basla += index;

        /* Metinden, belirledigimiz boyutta bir satir elde ediyoruz. Basindaki ve sonundaki girintileri ekleyerek. */
        SatirUzunluguAyarla(str, birSatir, basla);

        /* Eğer elde ettiğimiz satirin son karekteri boşluk değilse, yani bir kelimeyi bölmek durumunda kalmış isek
           bu kelimeyi bir alt satıra gönderip başındaki boşluğa kadar alıyoruz */
        if (birSatir[SATIR_UZUNLUGU - 3] != BOSLUK)
            index = SonBoslukBul(birSatir);

        /* başı, sonu ve uzunluğu düzenlenmiş satirimizi uzunluga sigdirip iki yana yaslıyoruz. */
        SatiriDuzenle(birSatir, SATIR_UZUNLUGU - index - 3);

        /* gerisi ekranda */
        printf("%s\n", birSatir);
    }
}

void SatiriDuzenle(char birSatir[], int boslukAdet)
{
    char temp[SATIR_UZUNLUGU];
    int okuIndex = 0;
    int yazIndex = 0;

    while (yazIndex < SATIR_UZUNLUGU)
    {
        /* Satir basindaki ve sonundaki girintileri bozmamak icin bunlari atliyoruz. */
        if ((okuIndex == 0) || (okuIndex == 1) || (yazIndex == SATIR_UZUNLUGU - 1) || (yazIndex == SATIR_UZUNLUGU - 2))
        {
            temp[yazIndex++] =  birSatir[okuIndex++];
            continue;
        }

        if (birSatir[okuIndex] == BOSLUK)
        {
            temp[yazIndex++] = birSatir[okuIndex++];

            if ((birSatir[okuIndex] != BOSLUK) && (boslukAdet > 0))
            {
                temp[yazIndex++] = BOSLUK;
                boslukAdet--;
            }
        }
        else
            temp[yazIndex++] = birSatir[okuIndex++];

        if ((yazIndex == SATIR_UZUNLUGU - 1) && (boslukAdet > 0))
        {
            okuIndex = 0;
            yazIndex = 0;
            temp[yazIndex] = '\0';
            strcpy(birSatir, temp);
        }

    }

    temp[yazIndex] = '\0';
    strcpy(birSatir, temp);
}

void SatirUzunluguAyarla(const char *str, char birSatir[], int baslangicKonumu)
{
    int i;

    for (i=0; i<SATIR_UZUNLUGU; i++)
    {
        if ((i == 0) || (i == 1) || (i == SATIR_UZUNLUGU - 1) || (i == SATIR_UZUNLUGU - 2))
        {
            birSatir[i] = ' ';
        }
        else
        {
            if (baslangicKonumu < strlen(str))
                birSatir[i] = str[baslangicKonumu++];
            else
                birSatir[i] = ' ';
        }
    }

   birSatir[i] = '\0';
}

int SonBoslukBul(char birSatir[])
{
    int i;

    for (i=(SATIR_UZUNLUGU - 3); i>0; i--)
    {
        if (birSatir[i] == BOSLUK)
            return i-1;
        else
            birSatir[i] = '\0';
    }
    return 0;
}



[KickIt] [Dzone] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Etiketler: , ,

E-mail | Permalink | Trackback | Post RSSRSS comment feed 3 Yorum

Şub162009

C dilinde string ifadeler, harf adeti bulmak

Yazan : Zafer    16.02.2009 | C Notları

Merhaba, C ile metinler üzerinde farklı işlemler yapmak isteyebilirsiniz.  Eğer daha öncesinde yüksek seviyeli bil dilde program geliştirdiyseniz büyük ihtimalle öncelikle metinleri depolamak için arayacağınız veri tipi string veri tipi olacaktır. Ancak C size burada küçük bir süpriz hazırladı, hazır olun C dilinde string veri tipi bulunmuyor. Tabi ki bu string işlemleri yapamayacağımız anlamına gelmiyor. Her dilin kullanımı için gereken enstrümanları var, C dilindede string işlemleri için geliştirilen enstrümanlar mevcut mühim olan bunları ustalıkla kullanabilmeyi öğrenmek sonrasında şaşırtıcı bir esneklikle, neler yapılabildiğini göreceksiniz.

C üzerinde string işlemleri ile uğraşmaya başlayanlar için ilk örneklerden birisi metin içinde geçen harflerin toplam adetini bulmayı amaçlayan programların geliştirilmesidir. Basit bir program olmakla birlikte bazı püf noktaları gözden kaçırmamak gerekir.

Benim bu konudaki çalışmama ait kodları yazının altında bulabilirsiniz kısaca özetlemek gerekirse; öncelikle metnimdeki boslukları nokta ile doldurarak boşluklardan kurtuluyorum. Sonra herbir harfi tek tek alıp dizideki tüm harflerle karşılaştırıyorum, her bulduğum harf için harfToplam sayacımın degerini bir arttırıyorum. Döngü tamamlandığında harfToplam sayacımdaki sayı bana metinde geçen ilgili harfin toplam adedini veriyor. Ben harfleri ve degerlerini saklamak için char ve int tipinde iki tek boyutlu dizi kullandım ama bunun yerine iki boyutlu bir dizide olur düşüncesindeyim, belki bunu siz denersiniz! (olur ya denerseniz lüfen sonucu banada iletin.) Bu işlem esnasında benim istediğim harfler ve kullanım adetleri dizilerdeki yerlerine yerleşiyor.

Ancak burada bir nüans var. Örneğin a harfi metnin bir kaç yerinde geçiyor. İlk işlemde kaç tane a harfi olduğunu bulduk, string içinde ilerlerken karşımıza tekrar a harfi çıkacaktır ama biz bunu saymıştık peki bu sorunu nasıl çözebiliriz? Benim çözümün test ettiğim her harfin yerine nokta işareti yerleştirmek oldu. Belki bu nokta değilde başka bir karekterde olabilirdi ama ben bunu kullandım. Böylece sayılan harfleri otomatikman devre dışı bırakarak string içerisinde sadece sayılmayan harflerin kalmasını sağladım.Sonrasında char ve int tipindeki iki tek boyutlu dizinin yardımıyla içerdikleri değerleri ekrana yazarak sonucu kullanıcıya iletiyoruz. Ben çıktıyı biraz daha süslemek amacıyla yıldızlardan oluşan basit bir grafik gösterimide yaptım. Sonra çıktı gözüme çok karışık geldi birde onu sıraladım. (Bubble Sort)


Mühim olan yaptığınız işten keyif almaktır. Eğer işinizi severek yapıyorsanız siz istemesenizde beyniniz sizi daha güzele doğru sürükleyecek ve her işinizde daha da iyisini aramaya odaklanacaksınız Tüm okuyanlara sağlıklı ve mutlu günler dilerim.

 



       CodeBlocks Proje Dosyası : harf_say_project.rar (11,65 kb)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BOYUT 123

void BoslukDoldur(char str[]);
void HarflerriHesapla(char str[], char harf[], int deger[]);
void SonucuYaz(char harf[], int deger[]);
void DegerleriSirala(char harf[], int deger[]);

int main()
{
    char string[BOYUT] = "matematikte eratosthenes elegi belirli bir tamsayiya kadar yer alan asal sayilarin bulunmasi icin kullanilan bir yontemdir";
    char harf[BOYUT] = "\0";
    int deger[BOYUT] = {0};

    BoslukDoldur(string);
    HarflerriHesapla(string, harf, deger);
    SonucuYaz(harf, deger);
    DegerleriSirala(harf, deger);
    SonucuYaz(harf, deger);

    return 0;
}

void DegerleriSirala(char harf[], int deger[])
{
    char tmp;
    int i, j, temp;

    for (i=0; i<strlen(harf); i++)
    {
        for (j=1; j<strlen(harf); j++)
        {
            if (deger[j-1] > deger[j])
            {
                temp = deger[j-1];
                deger[j-1] = deger[j];
                deger[j] = temp;

                tmp = harf[j-1];
                harf[j-1] = harf[j];
                harf[j] = tmp;
            }
        }
    }
}

void HarflerriHesapla(char str[], char harf[], int deger[])
{
    int birHarf = '\0';
    int harfToplam = 0;
    int i, j, k=0;

    for (i=0; i<strlen(str); i++)
    {
        birHarf = str[i];
        harfToplam = 0;

        for (j=i; j<strlen(str); j++)
        {
            if ((birHarf == str[j]) && (birHarf != '.'))
            {
                str[j] = '.';
                harfToplam++;
            }
        }

        if (harfToplam > 0)
        {
            harf[k] = birHarf;
            deger[k] = harfToplam;
            k++;
        }

        str[i] = '.';
    }
}

void BoslukDoldur(char str[])
{
    int i = 0;

    for (i=0; i<strlen(str); i++)
    {
        if (str[i] == ' ')
            str[i] = '.';
    }
}

void SonucuYaz(char harf[], int deger[])
{
    int i, j;

    puts("\nMetindeki toplam harf sayisi ve grafik gosterim :\n");
    for (i=0; i<strlen(harf); i++)
    {
        if (deger[i] > 0)
            printf("  %c -> %2d ", harf[i], deger[i]);

        for (j=0; j<deger[i]; j++)
            putchar('*');

        printf("\n");
    }
}
 


[KickIt] [Dzone] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Etiketler: , ,

E-mail | Permalink | Trackback | Post RSSRSS comment feed 1 Yorum

Oca192009

Eratosthenes(Eratosten) Eleği

Yazan : Zafer    19.01.2009 | C Notları

Matematikte, Eratosthenes(Eratosten) Eleği belirli bir tamsayıya kadar yer alan asal sayıların bulunması için kullanılan bir yöntemdir. Daha hızlı ve karmaşık olan Atkin kalburunun atası sayılır. Eski Yunan'da Eratosten tarafından geliştirilmiştir.

Eratosthenes Alexandria da ve bir müddet Atina da öğrenim görmüştür. İ.Ö.236 da Ptolemy III Euergetes I tarafından Alexandria Kütüphanesine, o koltuktaki ilk kütüphaneci Zenodotos'un ardından, kütüphaneci olarak atanmıştır. Matematik ve doğal bilimlere katkılarda bulunmuştur. İ.Ö.195 de kör olmuştur ve bir yıl sonra kasıtlı olarak kendini aç bırakarak ölmüştür.

Elegin işleyişi :

   1. Önce bir dizelgeye 2'den başlayarak, istediğiniz en büyük tam sayıya kadar olan tüm tamsayıları yazın. Bu dizelgenin adı A olsun.
   2. Bir diğer dizelgeye A'daki ilk asal sayı olan 2'den başlayarak bulduğunuz asal sayıları yazın. Bu dizelgenin adı B olsun.
   3. A'dan 2'yi ve 2'nin tüm katlarını silin.
   4. A'da kalan ilk tek sayı asaldır. Bu sayıyı B'ye ekleyin
   5. Bu sayıyı ve tüm katlarını A'dan silin. Daha küçük katları zaten silindiğinden, silme safhası bu sayının karesinden başlayabilir.
   6. A dizelgesinde herhangi bir sayı kalmayıncaya kadar 4. ve 5. adımları tekrarlayın

 

Merhaba,

Bu makalemizde C dilinde Eratosten eleğini kodlayarak iki tamsayı arasında bulunan asal sayıları bulacağız. İnternette araştırırsanız farklı kodlanmış elek kodlarına rastlayabilirsiniz. Yukarıdaki örnek animasyonda eleğin nasıl çalıştığı görülmekte.

Eratosten eleğini kaynak kodlarını aşağıda görebilirsiniz veya CodeBlock proje dosyasını bilgisayarınıza indirip inceleyebilirsiniz. Sorularınız için bana yazabilirsiniz. Bir başka makalede buluşmak dilegiyle.

 

        CodeBlocks Proje Dosyası : Eratosten_elek_project.rar (10,61 kb)

/*============================================================*/
/* Program  : Eratosten Elegi                                                                                                */
/* Yazan    : Zafer ÇELENK                                                                                                  */
/* Tarih    : 19.01.2009                                                                                                        */
/* E-Posta  : zafercelenk@gmail.com                                                                                     */
/*                                                                                                                                       */
/* Aciklama : Asal sayıları bulmak için kullanılan Eratosten eleginin C dilinde kodlanması           */
/*                                                                                                                                      */
/*============================================================*/

#include <stdio.h>
#include <stdlib.h>

#define SIZE 120

void InitializeSieve(int aSieve[], int aSize);
void RunSieve(int aSieve[]);
void PrintSieve(int aSieve[]);

int main()
{
    int sieve[SIZE];    /* Tüm sayıları tutan dizimiz */

    InitializeSieve(sieve, SIZE);
    RunSieve(sieve);
    PrintSieve(sieve);

    return 0;
}

void RunSieve(int aSieve[])
{
    int multiple = 0;   /* ilgilendigiimiz sayıların katlarını belitren degikenimiz */
    int result = 0;     /* sayı * kat sonucunda elde edecegimiz sonuc, yani elekten elenecek sayı */
    int i;

    for (i=2; i<=SIZE; i++)
    {
        multiple = i; /* Carpanını ilgilendigimiz sayının katlarını verecek sekilde ayarlıyoruz */
        while (result < SIZE)
        {
            result = multiple * i;
            /* printf("i: %d, mutiple: %d, result: %d\n", i, multiple, result); */

            if (result <= SIZE)     /* Eger sayının katı ilgilendigimiz aralıktaysa islem yapıyoruz */
                aSieve[result] = 0;
            multiple++;
        }
        result = 0;
    }
}

void PrintSieve(int aSieve[])
{
    int i;

    printf("\n\nElek dizimiz (1-%d) :\n\n", SIZE);
    for (i=1; i<=SIZE; i++)
        printf("%3d%c", aSieve[i], (i % 10 == 0) ? '\n' : ' ');

    printf("\n\nBelirtilen (1-%d) sayi araligindaki asal sayilar:\n\n", SIZE);

    for (i=2; i<=SIZE; i++)
    {
        if (aSieve[i] > 0)
            printf("%d, ", aSieve[i]);
    }
    printf("\n\n");
}

void InitializeSieve(int aSieve[], int aSize)
{
    int i;

    for (i=1; i<=aSize; i++)
        aSieve[i] = i;
}


[KickIt] [Dzone] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Etiketler: ,

E-mail | Permalink | Trackback | Post RSSRSS comment feed 0 Yorum

Oca152009

Palindrom: Özyinelemeli çözüm

Yazan : Zafer    15.01.2009 | C Notları

Palindrom; baştan ve sondan okunduğunda değeri değişmeyen sayılardır. Bunların yazılı biçimlerine ise; "Dönüşük Sözcükler" denir.
Dönüşüklük aslında bir tür görsel bakışıklık (simetri) anlamına geliyor. Sözlü dilde dönüşüklüğü sezmek kolay değil. Japon yazısında olduğu gibi, heceleri imlerle anlatan, ya da Arap yazısında olduğu gibi, aynı harfi sözcüğün başında, ortasında ve sonunda başka başka imlerle gösteren, sesli harf gibi kimi harfleri kullanmayan dillerde dönüşüklüğü keşfetmek daha zor, belki de olanaksız. Latin abecesini kullanan dillerde ise bu özelliği görmek görece daha kolay, onun için de taa Romalılar'dan beri bu diller dönüşük sözcükleri bulmuşlar, böylece tümceler kurmuşlar.Örnekler : NASTAS MUM SATSANA, EY EDİP ADANADA PİDE YE, KABAK, KÜÇÜK, EFE, ANISINA, TALAT,ADA, ÜMMÜ, İKİ 

Merhaba, Bu yazımda yukarıda açıklamasınada yer verdiğim palindrom kelimeleri bulan ve bu işlem için özyineleme tekniğini kullanarak geliştirmiş olduğum programın örnek kodlarını inceleceğiz.

Palindrom kelime arama işini isPalindrom() isimli fonksiyon üstlenmekte, bu fonksiyon özyinelemeli olarak tasarlandı. Fonksiyon üç durumu inceleyip buna göre sonuç döndürüyor. Öncelikle kelimede kalan harf sayısı ikiden küçük ise bu kelimemizdeki tüm harflarin taranmış olduğunu gösteriyor ve fonksiyon 1 ile sonlanıyor. Eğer daha test edeceğimiz harf varsa bir sonraki if yapısında, sondaki ve baştaki harflerin eşitliği kıyaslanıyor. Eşit olmadıkları durumda ki bu zaten palindrom durumunun bozulması anlamına geliyor, fonksiyon 0 ile sonlanıyor. Eğer harfler eşitse else kısmı devreye giriyor ve sonraki harfleri kontrol etmek için isPalindrom() fonksiyonunu tekrar çağırıyor. Kodlar aşağıda, ayrıca ekte Codeblocks için proje klasörüde var. Sorularınız olursa bana yazabilirsiniz. Bir sonraki yazıda buluşmak üzere sağlıcakla kalın efem :)

 

        CodeBlocks Proje Dosyası : palindrom_project.rar (9,52 kb)

#include <stdio.h>
#include <stdlib.h>

#define SIZE 20

int isPalindrom(char *str, int length);

int main()
{
    char aString[SIZE];
    int result = 0;

    printf("Palindrom arastirmasi icin bir kelime girin : ");
    scanf("%s", aString);

    result = isPalindrom(aString, strlen(aString));

    if (result == 1)
        puts("Bu bir palindrom.");
    else
        puts("Bu bir palindrom degil.");

    return 0;
}

int isPalindrom(char *str, int length)
{
    if (length < 2)
        return 1;

    if (str[0] != str[length-1])
        return 0;
    else
        return isPalindrom(str+1, length-2);
}


[KickIt] [Dzone] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Etiketler:

E-mail | Permalink | Trackback | Post RSSRSS comment feed 1 Yorum

Ara182008

Bilet satış projesi

Yazan : Zafer    18.12.2008 | C Notları

Merhabalar, bir süredir yeni yazılar ekleyememiştim. Bayram tatili, tatil dönüşü derken zaman geçti gitti. Bir süredir Deitel'in kitabının üzerinden C çalışmalarıma devam ediyorum. Oldukça güzel alıştırma soruları var. Eğer C diline yeni başlamışsanız kitabı alıp incelemenizi veya bir şekilde bu sorulara ulaşıp gözden geçirmenizi salık veririm.

Bu sorulardan biriside bir havayolu şirketine ait bilet satış uygulaması geliştirmek. Şu an soruyu tam hatırlamıyorum ama kısaca uçak iki bölümden oluşuyor, sigara içilen ve içilmeyen bölüm, gelen yolcuya ilgili bölüm seçiminden sonra o bölümden bir koltuk veriliyor. Eğer o bölüm dolmuşsa yolcuya diğer bölümden bilet isteyip istemediği soruluyor ve cevap evet ise diğer bölümden boş bir koltuk veriliyor.

Proje kodları aşağıda ancak CodeBlocks ile çalışanlar için bir ekstra daha var. CodeBlocks proje dosyasınıda ekte yayınlıyorum. Bu sayade sadece CodeBlocks içinden project dosyasını açarak tüm projeye ulaşmış olucaksınız.


        CodeBlocks Proje Dosyası : THY_Project.zip (12,08 kb)

 

#include <stdio.h>
#include <stdlib.h>

#define KOLTUK_SAYISI 10

int KoltukSat(int dizi[], int boyut, int sigara);
int BosKoltukVerSigaraVar(int dizi[], int boyut);
int BosKoltukVerSigaraYok(int dizi[], int boyut);
void DiziYazdir(int dizi[], int boyut);

int main()
{
    int koltuklar[KOLTUK_SAYISI] = {0};
    int sigaraSec, koltukNo;

    while(sigaraSec != 0)
    {
        printf("THY Bilet Satis Bolumu!\n");
        printf("Lutfen sigara opsiyonunu seciniz\n\n");

        printf("1-Sigara icilen bolum\n");
        printf("2-Sigara icilmeyen bolum\n");
        printf("Seciminiz[1/2] : ");
        scanf("%d", &sigaraSec);
        system("CLS");

        if((sigaraSec != 1) && (sigaraSec != 2)) continue;

        koltukNo = KoltukSat(koltuklar, KOLTUK_SAYISI, sigaraSec);

        if(koltukNo == -1)
            printf("\n\nUzgunuz! Istediginiz seferde bos koltuk kalmadi.\n\n");
        else
            printf("\n\nRezervasyonunuz yapildi. Koltuk numaraniz %2d olarak belirlendi.\n\n", koltukNo);

        system("PAUSE");
        system("CLS");

    }

    DiziYazdir(koltuklar, KOLTUK_SAYISI);

    return 0;
}

int BosKoltukVerSigaraYok(int dizi[], int boyut)
{
    int i;

    for(i=(KOLTUK_SAYISI / 2); i<boyut; i++)
    {
        if(dizi[i] == 0)
            return i;
    }

    return -1;
}

int BosKoltukVerSigaraVar(int dizi[], int boyut)
{
    int i;

    for(i=0; i<boyut; i++)
    {
        if(dizi[i] == 0)
            return i;
    }

    return -1;
}

int KoltukSat(int dizi[], int boyut, int sigara)
{
    int bosKoltuk;
    char baskaKoltukBak;

    switch(sigara)
    {
        case 1:
            bosKoltuk = BosKoltukVerSigaraVar(dizi, 5);
            if(bosKoltuk == -1)
            {
                printf("\n\nSigara icilen bolum doldu. Diger bolume bakilsin mi? [E/H]..>");
                scanf(" %c", &baskaKoltukBak);

                if((baskaKoltukBak == 'e') || (baskaKoltukBak == 'E'))
                    bosKoltuk = BosKoltukVerSigaraYok(dizi, boyut);
            }
            if(bosKoltuk != -1) dizi[bosKoltuk] = 1; /* Koltuk satildi isaretle */
            break;
        case 2:
            bosKoltuk = BosKoltukVerSigaraYok(dizi, boyut);
            if(bosKoltuk == -1)
            {
                printf("\n\nSigara icilmeyen bolum doldu. Diger bolume bakilsin mi? [E/H]..>");
                scanf(" %c", &baskaKoltukBak);

                if((baskaKoltukBak == 'e') || (baskaKoltukBak == 'E'))
                    bosKoltuk = BosKoltukVerSigaraVar(dizi, 5);
            }
            if(bosKoltuk != -1) dizi[bosKoltuk] = 1; /* Koltuk satildi isaretle */
            break;
        default:
            printf("Lutfen gecerli bir secim yapiniz!\n\n");
    }

    return bosKoltuk;
}

void DiziYazdir(int dizi[], int boyut)
{
    int satir;

    for(satir=0; satir<boyut; satir++)
    {
        printf("%2d", dizi[satir]);
    }
}


[KickIt] [Dzone] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Etiketler: , ,

E-mail | Permalink | Trackback | Post RSSRSS comment feed 4 Yorum

Ara022008

Başka bir geliştirme ortamı CodeBlocks

Yazan : Zafer    02.12.2008 | C Notları

C/C++ ile çalışmaya başladıysanız öncelikle yazdığınız kodları derleyebilmek için bir derleyiciye sahip olmanız gerekir. Piyasada bulabileceğiniz birçok C/C++ derleyicisi bu konuda size yardımcı olacaktır. Derleyiciler Windows veya Linux ortamında konsoldan bir takım parametreleri alarak çalışırlar. Bu parametreleri derleyicilerin kullanım kılavuzlarından öğrenerek kodlarınızı derleyebilirsiniz.

Ancak biraz daha ilerlediğinizde kodları bir metin dosyasına kaydedip daha sonra konsol üzerinden derleyip çalıştırmak oldukça zaman alan bir iş haline gelir. Bu durumun bir sonucu olarak yazılımcılar için derleme ve diğer işlemleri gerçekleştiren programlar geliştirilmiştir. Bu tür programlara genel olarak tümleşik geliştirme ortamı (IDE) adı verilmektedir.

Bu gün baktığımızda özellikle Microsoft tarafından geliştirilen ve C/C++ yanında başka dillere de destek veren Visual Studio, CodeGear tarafından geliştirilen C++ Builder birçok programcı tarafından tercih edilmektedir. Bunun yanında Linux ortamı için KDeveloper, anjuta gibi geliştirme ortamları da mevcuttur.

Bir IDE genel olarak derleme ve çalıştırma işini tek tuşa indirgeyerek bize oldukça kolaylık sağlamanın yanında, günümüzdeki IDE’ler kod tamamlama, yazım kontrolü, kod biçimlendirme gibi daha birçok özellik sunmaktadır. Bu IDE araçlarından biriside CodeBlocks IDE’sidir.

CodeBlocks IDE hem Linux hem de Windows (cross platform) ortamında çalışabilecek şekilde tasarlanmış ve ücretsiz olarak dağıtılan bir IDE’dir. Bu IDE’yi desteklediği herhangi bir derleyici ile kullanmanız mümkün, desteklediği derleyicilerin listesin kendi sitesinden öğrenebilirsiniz. Kullanımı kolay, sisteme aşırı yüklenmeyen, ücretsiz ve hem Linux hem de Windows ortamında kullanabileceğiniz bir IDE istiyorsanız CodeBlocks tam size göre kesinlikle denemenizi tavsiye ediyorum. Aşağıdaki adresten CodeBlocks’u indirdikten sonra sisteminize kurup deneyebilirsiniz.

CodeBlocks Resmi Sitesi : http://www.codeblocks.org



[KickIt] [Dzone] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Etiketler: , , ,

E-mail | Permalink | Trackback | Post RSSRSS comment feed 1 Yorum