Sabah uyandığımda kendimi yorgun hissediyordum. Günün 24 saatten fazla olması için yalvarıyordum. İş, okul, özel hayat hepsi için yeterli vakit ayırmak imkansızdı. Hayatımı kalabalık hissediyordum. Kendimi mutlu etmek başlığı altında aldığım her şey üstüme geliyordu. Bunu farkettiğim gün mutluluğun penceresini açtığımı hissettim.
Ev o kadar ıvır zıvır ile dolmuştu ki kullanmadığım yüzlerce eşya ve kıyafet bana yük gibi geliyordu. Kendimi mutlu etmek için aldığım yüzlerce eşya beni mutlu etmiyor aksine hayatıma ağırlık katıyordu. Her geçen gün yenisi çıkıyor, onları takip etmekten hayatı kaçırdığımı hissediyordum. Her yenisi çıktığında eskisini çekmeceye kaldırıyordum durum artık sinir bozucu bir hal almaya başlamıştı, ve sonunda bir sabah devrim niteliğinde bir karar almaya karar verdim "Severek Tüket!".
Her insanın mutlu olduğu nokta olan kendi zirvesine tırmanırken onunla beraber gelecek, zirveye tırmanırken ona ağırlık yapacak nesneler sevdiği ve bağ kurduğu nesneler olması gerektiğinin farkına vardım. Kendimi mutlu etmek için özenerek aldığım fakat kullanmaya dahi fırsatım olmayan yüzlerce ürünü satışa çıkardım. Sadece gerçekten bağ kurduğum ruhu olduğuna inandığım bozulsa dahi tamir etmeyi göze aldığım ona sanki bir ruhu varmış gibi yaklaştığım eşyalarımı yanıma aldım insanoğlunun bu zorlu yolcuğunda. Kendimi rahatlamış hissediyordum, hafiflemiş! Artık sadece bağ kurduğum değer verdiğim eşyalar vardı hayatımda yenisi dahi çıksa benim için yeri farklıydı onların. Ömürlerini tamamlayana kadar onlarla olacaktım.
Bu şekilde hayattan daha fazla zevk almaya başladım. Çünkü eşyaları kullanırken kendimi farklı hissediyordum. Yenisi ne zaman çıkacak nerede ne kadara çıkacak diye araştırmalara girmek zorunda kalmadım. Hayatımda daha az ama daha verimli kullandığım eşyalarım oldu ve insanlara ayıracak çok daha fazla vaktim.
Guven Cenan Guvenal | Kisisel Blog
Sitedeki Her Yazı Kendime Aittir. İletişim : guvencenan@gmail.com
26 Ekim 2016 Çarşamba
27 Ekim 2014 Pazartesi
Linux Kernel Modül Derleme
Merhaba arkadaşlar bugün linux kernel modülleri nasıl derlenir nasıl hazırlanır onlardan bahsedeceğim. Öncelikle kernel modül yazmanız için C programlama diline hakim olmanız gerekmektedir. Kullanılan dil bu olmakla beraber az çok Linux komutlarına aşina olmakta fayda var şahsen ben bu konuda biraz acı çektim. Kernel modülleri kernel'ı tekrar derleme ihtiyacı duyulmadan kernel modda çalışan program yazma denebilir. Bunların en büyük örneklerinden biri tabi ki sürücüler.
Bu yazı sadece nasıl derleneceğine ilişkin olduğundan diğer konularla ilgili ayrıntılar başka yazılarımda sizlerle olacak.
Öncelikle nasıl bir kod yazmamız gerekiyor. Bu konuda tabi ki klasik int main yazarak sıradan bir process oluşturmayacağız. Onun yerine linux modülünde en az iki adet fonksiyon mevcut bunlardan biri init_module(void) diğeri ise cleanup_module(void) bu iki fonksiyondan başlangıç (initialization) fonksiyonu init_module olarak adlandırılırken bitiş (cleanup) fonksiyonu ise cleanup_module fonksiyonu olarak adlandırılır.
Ayrıca buraya kod yazarken standart C fonksiyonlarımız yerine linux/kernel.h ve /module.h başlık dosyalarının fonksiyonlarını kullanıyoruz. Standart C fonksiyonları user moda göre yazıldığından kernel modda kullanamıyoruz.
Gelelim kodumuza tabi ki herkez gibi bizde "Hello World" kodu yazacağız.
Kodlar Linux Kernel Module Guide'den alıntıdır.
Bu yazı sadece nasıl derleneceğine ilişkin olduğundan diğer konularla ilgili ayrıntılar başka yazılarımda sizlerle olacak.
Öncelikle nasıl bir kod yazmamız gerekiyor. Bu konuda tabi ki klasik int main yazarak sıradan bir process oluşturmayacağız. Onun yerine linux modülünde en az iki adet fonksiyon mevcut bunlardan biri init_module(void) diğeri ise cleanup_module(void) bu iki fonksiyondan başlangıç (initialization) fonksiyonu init_module olarak adlandırılırken bitiş (cleanup) fonksiyonu ise cleanup_module fonksiyonu olarak adlandırılır.
Ayrıca buraya kod yazarken standart C fonksiyonlarımız yerine linux/kernel.h ve /module.h başlık dosyalarının fonksiyonlarını kullanıyoruz. Standart C fonksiyonları user moda göre yazıldığından kernel modda kullanamıyoruz.
Gelelim kodumuza tabi ki herkez gibi bizde "Hello World" kodu yazacağız.
Kodlar Linux Kernel Module Guide'den alıntıdır.
/* * hello-1.c - The simplest kernel module. */ #include <linux/module.h> /* Needed by all modules */ #include <linux/kernel.h> /* Needed for KERN_INFO */ int init_module(void) { printk(KERN_INFO "Hello world 1.\n"); /* * A non 0 return means init_module failed; module can't be loaded. */ return 0; } void cleanup_module(void) { printk(KERN_INFO "Goodbye world 1.\n"); }Kodu incelersek klasik bir C kodu fakat printf yerine printk kullanılmış. Bu da daha demin dediğimiz gibi stdio fonksiyonları yerine linux'un kernel başlık dosyasındaki fonksiyonları kullanmamızdan kaynaklanıyor. Ayrıca printk log'a yazar KERNEL_INFO ise bu log'un öncelik seviyesini belirler. Aşağıda direk linux kodlarından bu tanımlanan sabitlerin değerlerini görebilirsiniz.
#define KERN_EMERG KERN_SOH "" /* system is unusable */ #define KERN_ALERT KERN_SOH "1" /* action must be taken immediately */ #define KERN_CRIT KERN_SOH "2" /* critical conditions */ #define KERN_ERR KERN_SOH "3" /* error conditions */ #define KERN_WARNING KERN_SOH "4" /* warning conditions */ #define KERN_NOTICE KERN_SOH "5" /* normal but significant condition */ #define KERN_INFO KERN_SOH "6" /* informational */ #define KERN_DEBUG KERN_SOH "7" /* debug-level messages */ #define KERN_DEFAULT KERN_SOH "d" /* the default kernel loglevel */Gel gelelim modülü derlemeye. Öncelikle yeni bir klasör oluşturup kodumuzuda buraya atacağız. mkdir Dosya komutu ile Dosya isimli bir klasör oluşturduk. .c uzantılı dosyamızı bu klasöre atıyoruz. Daha sonra Makefile oluşturacağız. gedit Makefile yazın gedit programı açılacak buraya şunları yazacak ve kayıt edeceksiniz.obj-m += hello-1.o all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) cleanBunları yazıp kaydettikten sonra "make" komutunu giriyoruz. Artık herşey tamam ls komutu ile dizini listelediğinizde bir sürü dosyanın oluştuğunu göreceksiniz. Şimdi insmod hello-1.ko komutu ile modülümüzü çalıştırıyoruz. dmesg komutu ile kernel'da olup bitenden haberdar oluyoruz ve ekrana listelenen yaznının en sonunda Hello World-1 yazısını görürsek işlemi başarıyla yaptığımız anlamına geliyor. Daha sonra ise modülü kaldırmak için rmod hello-1.ko dediğimizde cleanup fonksiyonunun çalıştığını göreceğiz. Tekrar dmesg dediğimizde cleanup fonksiyonundaki printk ifadesinin listede yazılı olduğunu görüyorsak işlem tamam. Bugünlük yazımızında sonuna geldik kernel modül derleme üzerine daha ayrıntılı yazılar ile birlikte olacağız başlangıcı yaptık devamını ve ayrıntılarını inceleyeceğiz. Hepinize kolay gelsin. Güven Cenan Güvenal
25 Eylül 2014 Perşembe
C ve C++'da Önişlemci
Merhaba arkadaşlar bugün yazımızda c programlama dilinde önişlemciyi göreceğiz. Önişlemci program derleyiciden hemen önce çalışan ve kodumuzu # ile başlayan önişlemci komutlarından arındıran programdır. Şimdi bu # ile başlayan komutlar neler ne işe yararlar onlara bakalım.
Önişlemci Komutları :
#include
#define
#ifdef
#ifndef
#
##
#if
#else
#endif
#undef
#line
#include Önişlemci Komutu :
Bu komut basitçe kopyala yapıştır olarak değerlendirilebilir. < > yada " " arasındaki başlık(header) dosyalarınızı yazıdğınız dosyaya dahil eder. .h dosyasının tamamını alarak sayfanıza yapıştırır böylece başlık dosyasındaki fonksiyon protoriplerine, define bildirimlerine erişebilirsiniz.
#define Önişlemci Komutu :
Bu komut basitce bul değiştir işlemini gerçekleştirir. Kullanımı şu şekildedir.
Burada önişlemci program MAX gördüğü yere 100 sabitini yazar. Bu sayede derleyici MAX yazısını yerine 100 sayısını görür. Bu sabitlere sembolik sabit adı verilmektedir. Bir kaç kez kullanılan sabitler bu şekilde kullanılırsa değişiklik kolay olur.
#define önişlemci komutu sadece sabitler için kullanılmak zorunda değildir.
Bu kullanımlar dışında bir çok kullanımı vardır. Makro olarak kullanımı başka bir yazımızda anlatılmıştır.(bkz.) typedef derleyicinin gördüğü bir anahtar sözcüktür.
#define sadece atomları değiştirir örneğin MAX_SIZE 'daki MAX #define edilse dahi 100 ile değiştirilmez.
Anahtar Not : Önişlemci sadece yerdeğiştirme işlemini yapar define içersindeki işlemleri yapmaz!
SIZE yerine 20+30 yazar 50 yazmaz.
# ve ## Önişelmci Operatörleri:
# operatörü genelde makrolarda kullanılır ve unary prefix bir operatördür. Önüne geldiği atomu string olarak yazar. Bir örnekle anlatmak daha rahat olacak.
#define string(a) #a
int main(){ printf(string(guven)); } burada aslında printf("guven"); yazmış olduk yani #a string(a)'daki a 'yı tırnak içinde yazdı.
## operatörü ise atomları birleştirme operatörüdür. Binary infix olarak kullanılır. Soluna ve sağına gelen atomları birleştirir. Örnek üzerinde anlatırsak.
#define birlestir(a,b) a##b
int main(){ birlestir(say,ac)++; } dememiz ile
int main(){ sayac++ } dememiz aynı anlama geliyor artık her ne kadar saçma
bir örnekte olsa mantığını kavradıysak güzel yerlerde bu özelliği kullanabiliriz.
KOŞULLU DERLEME
#if #else #elif #endif Önişlemci Komutları:
Bu komutlar koşullu derlemede kullanılır. Kodun bir kısmının derlenmesi için bir koşul koymak istiyorsanız bu özellik tam sizin için. #if #else #elif zaten programlamadan bildiğimiz if ile else, elseif. Bunlar diğer if else ile aynı mantıkta çalışıyorlar. Fakat #if 'imizin koşul kısmına koyduklarımızda bazı kısıtlamalar mevcut tabi ki. #if 'in koşul kısmına sadece tamsayı ve değişmez ifadeleri kullanabiliyoruz. #define ile tanımladığımız ifadeleri kullanabiliyoruz. Örnekler ile anlatalım.
#if 1
/****buradaki kod çalışır***/
#endif
#if 0
/***buradaki kod derlenmez****/
#endif
Bu if'in nasıl kullanıldığı hakkındaydı. Birde nasıl koşullar koyabilir onlara bakalım. #if'imizin koşul kısmında bitsel operatörler, karşılaştırma operatörleri, aritmetik operatörler kullanılmasında bir sakınca yoktur. Örneğin;
#define MAX 300
#if MAX < 100
/***** Buradaki kod derlenmez***********/
#else if MAX > 200
/*********Burası derlenir************/
#else
/*********Burası derlenmez*******/
#endif
#ifndef #ifdef #undef Komutları:
Bu komutlar define edilip edilmemesine göre derleme yapmaya yarar. Yani bir define işlemi yapılırsa bunu derleme ya da derle olarak kullanırız bu komutları. Bu sarmalama başlık dosyalarının iki kez bildirilmemesi için kullanılır. Örnek bir kullanım yaparsak.
İnclude Guard : Bir başlık dosyasının birden fazla kez include edilmesinde oluşacak hataları engellemek için yapılan çalışma.
#ifndef __STDIO_H
#define __STDIO_H
/****burada eğer ikinci kez bu koda gelirse define işlemi önceden yapıldığından bu koda girmez**/
#endif
#define MAX 100
/***MAX tanımlı**/
#undef MAX
/***Artık MAX kullanılamaz***/
Önişlemci Komutları :
#include
#define
#ifdef
#ifndef
#
##
#if
#else
#endif
#undef
#line
#include Önişlemci Komutu :
Bu komut basitçe kopyala yapıştır olarak değerlendirilebilir. < > yada " " arasındaki başlık(header) dosyalarınızı yazıdğınız dosyaya dahil eder. .h dosyasının tamamını alarak sayfanıza yapıştırır böylece başlık dosyasındaki fonksiyon protoriplerine, define bildirimlerine erişebilirsiniz.
#define Önişlemci Komutu :
Bu komut basitce bul değiştir işlemini gerçekleştirir. Kullanımı şu şekildedir.
#define MAX 100
Burada önişlemci program MAX gördüğü yere 100 sabitini yazar. Bu sayede derleyici MAX yazısını yerine 100 sayısını görür. Bu sabitlere sembolik sabit adı verilmektedir. Bir kaç kez kullanılan sabitler bu şekilde kullanılırsa değişiklik kolay olur.
#define önişlemci komutu sadece sabitler için kullanılmak zorunda değildir.
#define WORD char * //typedef - using(C++11) gibi kullanmak "tercih edilmez!". #define str(x) "x" //Makro gibi kullanmak
Bu kullanımlar dışında bir çok kullanımı vardır. Makro olarak kullanımı başka bir yazımızda anlatılmıştır.(bkz.) typedef derleyicinin gördüğü bir anahtar sözcüktür.
#define sadece atomları değiştirir örneğin MAX_SIZE 'daki MAX #define edilse dahi 100 ile değiştirilmez.
Anahtar Not : Önişlemci sadece yerdeğiştirme işlemini yapar define içersindeki işlemleri yapmaz!
#define SIZE 20+30
SIZE yerine 20+30 yazar 50 yazmaz.
# ve ## Önişelmci Operatörleri:
# operatörü genelde makrolarda kullanılır ve unary prefix bir operatördür. Önüne geldiği atomu string olarak yazar. Bir örnekle anlatmak daha rahat olacak.
#define string(a) #a
int main(){ printf(string(guven)); } burada aslında printf("guven"); yazmış olduk yani #a string(a)'daki a 'yı tırnak içinde yazdı.
## operatörü ise atomları birleştirme operatörüdür. Binary infix olarak kullanılır. Soluna ve sağına gelen atomları birleştirir. Örnek üzerinde anlatırsak.
#define birlestir(a,b) a##b
int main(){ birlestir(say,ac)++; } dememiz ile
int main(){ sayac++ } dememiz aynı anlama geliyor artık her ne kadar saçma
bir örnekte olsa mantığını kavradıysak güzel yerlerde bu özelliği kullanabiliriz.
KOŞULLU DERLEME
#if #else #elif #endif Önişlemci Komutları:
Bu komutlar koşullu derlemede kullanılır. Kodun bir kısmının derlenmesi için bir koşul koymak istiyorsanız bu özellik tam sizin için. #if #else #elif zaten programlamadan bildiğimiz if ile else, elseif. Bunlar diğer if else ile aynı mantıkta çalışıyorlar. Fakat #if 'imizin koşul kısmına koyduklarımızda bazı kısıtlamalar mevcut tabi ki. #if 'in koşul kısmına sadece tamsayı ve değişmez ifadeleri kullanabiliyoruz. #define ile tanımladığımız ifadeleri kullanabiliyoruz. Örnekler ile anlatalım.
#if 1
/****buradaki kod çalışır***/
#endif
#if 0
/***buradaki kod derlenmez****/
#endif
Bu if'in nasıl kullanıldığı hakkındaydı. Birde nasıl koşullar koyabilir onlara bakalım. #if'imizin koşul kısmında bitsel operatörler, karşılaştırma operatörleri, aritmetik operatörler kullanılmasında bir sakınca yoktur. Örneğin;
#define MAX 300
#if MAX < 100
/***** Buradaki kod derlenmez***********/
#else if MAX > 200
/*********Burası derlenir************/
#else
/*********Burası derlenmez*******/
#endif
#ifndef #ifdef #undef Komutları:
Bu komutlar define edilip edilmemesine göre derleme yapmaya yarar. Yani bir define işlemi yapılırsa bunu derleme ya da derle olarak kullanırız bu komutları. Bu sarmalama başlık dosyalarının iki kez bildirilmemesi için kullanılır. Örnek bir kullanım yaparsak.
İnclude Guard : Bir başlık dosyasının birden fazla kez include edilmesinde oluşacak hataları engellemek için yapılan çalışma.
#ifndef __STDIO_H
#define __STDIO_H
/****burada eğer ikinci kez bu koda gelirse define işlemi önceden yapıldığından bu koda girmez**/
#endif
- #undef ise önceden define edilmiş bir ismin tanımlanmasını iptal eder (undefined).
#define MAX 100
/***MAX tanımlı**/
#undef MAX
/***Artık MAX kullanılamaz***/
- Son olarak #error önişlemci komutu ise programı daha derlemeye başlamadan önişlemcide durdurup hata yazdırmasına yarar. Bu şu şekilde kullanılabilir.
#ifndef __STDC__
#error Bu Kod Sadece C derleyicisi İçin Geçerli
#endif
!Burada __STDC__ C derleyicilerinde tanımlı olan bir simgesel değişmezdir. Standart C derleyicisi ise bu değişmez 1 olarak tanımlıdır.
24 Eylül 2014 Çarşamba
Motorsiklet'e Başlamak
Bugünkü yazımda motorsiklete başlayalı çokta uzun süre olmammış biri olarak nasıl ve neden başlamalıyız sorularını sizlere yanıtlayacağım. Motorsiklete başlamadan önce kafada çok fazla düşünce olur örneğin rahat mıdır? güvenli midir? hangi motor ile başlamayalım? gibi gibi uzatabiliriz.
Peki motora nasıl başlamalıyım?
Motora başlarken kafanızda sadece hava atmak varsa benim fikrimce yavaşça uzaklaşın çünkü bu icat hava atayım derken gözünüzü çıkarabilir cinsten. Örneğin başlangıçta yüksek cc'li bir motor size daha havalı gelecek fakat bu alet arabaya benzemez şakası yok daha sonra "bizim bir arkadaş vardı cbr 600rr 'la öldü o cihaz şeytan icadı" dedirtmeyin arkanızdan. Düşük cc'le başlamanın havalı olmadığı aşikar fakat gerek virajlardaki tepkisi gerek gaz kolunun hassasiyeti açısından gerekse kalkışlarda olsun düşük cc motorla sizi daha güvenli şekilde motor hayatınıza alıştıracaktır. Motordan erkenden soğumamak ve hayatınızı tehlikeye atmamak adına bırakın kalın lastikleri düşük cc'de sürüşünüzün keyfini çıkarın.(Hemde daha ucuza.)
Ben bu işi öğrendim problemi.
Motorda diğer bir problem "öğrendim bu keratayı" problemi. İşte bu sizin başınıza büyük belalar açabilir. Çünkü motor gerçekten uçsuz bucaksız bir serüven bu nedenle bu kadar keyif veriyor sürekli yeni şeyler öğreneceksiniz. Tabi ki bu öğrenme olayını bisikletteki gibi düşüp kalkarak öğrenmezseniz çok daha güzel olur bunun için motor eğitimleri var zaten. Eğer eğitime verecek paranız yoksa ki olsa daha iyi olur. Kademe kademe alıştırın derim. Öncelikle bol bol bu konularla ilgili makale okuyun örneğin "ışıklarda nasıl durmalıyım?", "güvenli sürüş teknikleri nedir?", "Güvenli frenleme nasıl yapılır?" bu konular önemli eksiklerinizi gördükçe araştırın motorsiklet forumlarını bol bol okuyun. Daha sonra bunları işlek olmayan yollarda uygulayın canınız yanmasın.
Bugün yazımızı daha fazla uzatmak istemiyorum anlatılacak çok şey mevcut diğer yazılarda tamamlamaya çalışacağım hepinize kazasız belasız yolculuklar.
Peki motora nasıl başlamalıyım?
Motora başlarken kafanızda sadece hava atmak varsa benim fikrimce yavaşça uzaklaşın çünkü bu icat hava atayım derken gözünüzü çıkarabilir cinsten. Örneğin başlangıçta yüksek cc'li bir motor size daha havalı gelecek fakat bu alet arabaya benzemez şakası yok daha sonra "bizim bir arkadaş vardı cbr 600rr 'la öldü o cihaz şeytan icadı" dedirtmeyin arkanızdan. Düşük cc'le başlamanın havalı olmadığı aşikar fakat gerek virajlardaki tepkisi gerek gaz kolunun hassasiyeti açısından gerekse kalkışlarda olsun düşük cc motorla sizi daha güvenli şekilde motor hayatınıza alıştıracaktır. Motordan erkenden soğumamak ve hayatınızı tehlikeye atmamak adına bırakın kalın lastikleri düşük cc'de sürüşünüzün keyfini çıkarın.(Hemde daha ucuza.)
Ben bu işi öğrendim problemi.
Motorda diğer bir problem "öğrendim bu keratayı" problemi. İşte bu sizin başınıza büyük belalar açabilir. Çünkü motor gerçekten uçsuz bucaksız bir serüven bu nedenle bu kadar keyif veriyor sürekli yeni şeyler öğreneceksiniz. Tabi ki bu öğrenme olayını bisikletteki gibi düşüp kalkarak öğrenmezseniz çok daha güzel olur bunun için motor eğitimleri var zaten. Eğer eğitime verecek paranız yoksa ki olsa daha iyi olur. Kademe kademe alıştırın derim. Öncelikle bol bol bu konularla ilgili makale okuyun örneğin "ışıklarda nasıl durmalıyım?", "güvenli sürüş teknikleri nedir?", "Güvenli frenleme nasıl yapılır?" bu konular önemli eksiklerinizi gördükçe araştırın motorsiklet forumlarını bol bol okuyun. Daha sonra bunları işlek olmayan yollarda uygulayın canınız yanmasın.
Bugün yazımızı daha fazla uzatmak istemiyorum anlatılacak çok şey mevcut diğer yazılarda tamamlamaya çalışacağım hepinize kazasız belasız yolculuklar.
2 Şubat 2014 Pazar
Değişken Uzunlukta Argüman Alan Metodlar (Variable-Arity Method) - Java
Merhaba arkadaşlar bu yazımda kaç tane argüman alacağımızı bilmediğimiz metodları yazmayı anlatacağım. Bu metodlar fazlasıyla ihtiyaç duyulan metodlar olup jdk 5 'ten itibaren aramızda olan bir özelliktir. Daha önceleri (o kadar uzun süredir uğraşmıyorum araştırmalarıma göre :) ) dizi ile yapılması tercih ediliyormuş. Yani siz methodunuza bir dizi geleceğini düşünerek işlem yapıyorsunuz. Kullanıcı ise diziyi doldurup size gönderiyor. Tabi ki bu durumda kullanıcı (client) tarafına çok iş düştüğünden java 'da bir güzellik bulmuşlar şimdi ona bir bakalım.
Bu özelliğin kullanımı şu şekildedir.
Bu prototip şunu söylemektedir. Bana int türünden parametre gönder sayısı önemli değil. Olay tamamen bundan ibaret şimdi birde neler yapabiliriz neler yapamayız neler yaparsak hata olur onlara bir bakalım.
Öncelikle fonksiyonumuz birden fazla parametrenin yanında değişken uzunluklu argüman alabilir. Örnek kod ile gösterirsek.
gibi;
Fakat kurallarımızdan birincisi gördüğünüz gibi değişken uzunluklu argüman en sonda olmalı. Bilmemiz gereken bir diğer kural ise sadece bir adet değişken uzunluklu argüman bulunmalı.
Kurallarımız bu kadar bu kurallara uyduk şimdi ise overload mekanizmasını bu fonksiyonlarda nasıl kullanırız onlara bakalım.
Değişken Uzunluklu Argüman Alan Fonksiyonlarda Overloading
Overload mekanizması (bkz. ) aynı isimle farklı parametreli fonksiyonlar yazmak için işimize yarıyordu. Şimdi değişken uzunluklu argüman alan fonksiyonlarda bu olay nasıl oluyor ne gibi sorunlarla karşılaşabiliriz ona bakacağız. Overload mekanizması yine aynı mantıkla çalışmakta imzaları farklı olduğu sürece overload olmaktadır. Örnek ile gösterirsek;
Gördüğünüz gibi overlaod mekanizması hepsi için geçerli fakat tabi bu fonksiyonları overload ederken dikkat etmemiz gereken noktalar var. 1. fonksiyon , 2.-3.-4. overload edilebilir bir sıkıntı çıkarmaz. Fakat 5. ile edilebilmesine rağmen eğer ki fonksiyon foo(1); gibi tek bir int değer ile çağırırsak ambiguity olur. Derleyici hangi fonksiyonu çağıracağını bilemez. Aynı nedenlerden dolayı 3. ile 4. fonksiyonları da bir arada bulundurmak aynı hatayı karşınıza getirebilir. Eğer foo(2.1, 1); ile fonksiyon çağırılırsa ambiguity olur derleyici hangisini çağıracağını bilemez ve hata oluşur.
Değişken uzunluklu argüman alan fonksiyonlar sıfır argüman "foo();" ile çalışabilir olduğunu göz önüne alarak sizde bunlara benzer hataları anlayabilirsiniz.
Yazımızın sonuna geldik başka bir yazıda görüşmek üzere umarım faydalı olmuştur.
Bu özelliğin kullanımı şu şekildedir.
void Test(int ... v);
Bu prototip şunu söylemektedir. Bana int türünden parametre gönder sayısı önemli değil. Olay tamamen bundan ibaret şimdi birde neler yapabiliriz neler yapamayız neler yaparsak hata olur onlara bir bakalım.
Öncelikle fonksiyonumuz birden fazla parametrenin yanında değişken uzunluklu argüman alabilir. Örnek kod ile gösterirsek.
void f1(double x, int ... v); void f2(int x, int ... v); void f3(int x, double, y, int ... v);
gibi;
Fakat kurallarımızdan birincisi gördüğünüz gibi değişken uzunluklu argüman en sonda olmalı. Bilmemiz gereken bir diğer kural ise sadece bir adet değişken uzunluklu argüman bulunmalı.
void foo(double x, int ... v, boolean ... b); //Hata
Kurallarımız bu kadar bu kurallara uyduk şimdi ise overload mekanizmasını bu fonksiyonlarda nasıl kullanırız onlara bakalım.
Değişken Uzunluklu Argüman Alan Fonksiyonlarda Overloading
Overload mekanizması (bkz. ) aynı isimle farklı parametreli fonksiyonlar yazmak için işimize yarıyordu. Şimdi değişken uzunluklu argüman alan fonksiyonlarda bu olay nasıl oluyor ne gibi sorunlarla karşılaşabiliriz ona bakacağız. Overload mekanizması yine aynı mantıkla çalışmakta imzaları farklı olduğu sürece overload olmaktadır. Örnek ile gösterirsek;
void foo(int ... v); //1. Fonk void foo(boolean ... v); //2. Fonk void foo(double x, int ... v); //3. Fonk void foo(double x, int y, int ... v); //4. Fonk void foo(int x, int ... v); //5. Fonk
Gördüğünüz gibi overlaod mekanizması hepsi için geçerli fakat tabi bu fonksiyonları overload ederken dikkat etmemiz gereken noktalar var. 1. fonksiyon , 2.-3.-4. overload edilebilir bir sıkıntı çıkarmaz. Fakat 5. ile edilebilmesine rağmen eğer ki fonksiyon foo(1); gibi tek bir int değer ile çağırırsak ambiguity olur. Derleyici hangi fonksiyonu çağıracağını bilemez. Aynı nedenlerden dolayı 3. ile 4. fonksiyonları da bir arada bulundurmak aynı hatayı karşınıza getirebilir. Eğer foo(2.1, 1); ile fonksiyon çağırılırsa ambiguity olur derleyici hangisini çağıracağını bilemez ve hata oluşur.
Değişken uzunluklu argüman alan fonksiyonlar sıfır argüman "foo();" ile çalışabilir olduğunu göz önüne alarak sizde bunlara benzer hataları anlayabilirsiniz.
Yazımızın sonuna geldik başka bir yazıda görüşmek üzere umarım faydalı olmuştur.
27 Ocak 2014 Pazartesi
Kompozisyon (Composition) C++ - Java
Merhaba arkadaşlar bugün yazımızda kompozisyon olayını işleyeceğiz. Kompozisyon nesne yönelimli programlamada kısaca içinde barındırma sahip olma (...has a...) ilişkisidir diyebiliriz. Yani Araba ve Motor sınıflarımız olsun Araba sınıfı içerisinde bir Motor nesnesi barındırırsa kompozisyon olur. Şimdi örneğimizi kodla inceleyelim.
C++ :
Java :
Kodunu yazacağım 1b :
C++ :
class Motor{ int a; public: int b; int foo(); Motor(int x, int y){ a = x; b = y; } }; class Araba{ public: Motor r; Araba(int x, int y): r(x, y){ } };Burada Araba sınıfı Motor sınıfı türünden bir nesneye sahiptir. Java kodlarını da yazdıktan sonra açıklamalara devam edelim.
Java :
class Motor { private int a; public int b; public int foo(){ return 1; } public Motor(int a, int b){ this.a = a; this.b = b; } } class Araba { private Motor m; public Araba(int x, int y){ m = new Motor(x, y); } }Burada da olay aynı java syntax'ı ile şimdi asıl kurallarımıza gelir isek.
C++ :
- Araba nesnesi hayata geldiğinde Motor nesnesi de hayata gelir.
- Araba nesnesi construct edilmeden önce Motor nesnesi construct edilir.Bunun sebebi Motor nesnesine MIL syntax'ı ile ilk değer verdik MIL syntax'ına göre ilk değer vermeler constructor çağırılmadan önce yapılır. Dinamik Motor nesnesi kullansaydık. Nesneyi constructor'ın neresinde hayata getirirsek orasında Motor nesnesi construct olacaktı. (Kodunu yazacağım 1a)
- Araba nesnesi Motor'den önce destruct edilir.
- Araba nesnesi Motor nesnesinin private bölümlerine erişemez! Yani Araba'nın üye fonksiyonları içersinde " r.a " error olur.
- Aralarında ömürsel bir ilişki olmuş olur.
Java :
- Araba nesnesi hayata geldiğinde Motor nesnesi de hayata gelir.
- Javada nesneler dinamik ömürlü olduğundan biz kodumuzda Motor nesnesini Araba'nın constructor'ı içinde hayata getirdik bu nedenle önce Araba construct olurken Motor o arada olacak. İlk değer ile hayata getirseydik (Kodunu yazacağım 1b) ilk Motor hayata gelirdi.
- Javada destructtorlar çöp toplayıcı (Garbage Collection) 'nın ne zaman öldüreceğine göre değişir.
- Araba nesnesi Motor nesnesinin private bölümlerine erişemez! Yani Araba'nın üye fonksiyonları içersinde "m.a " error olur.
Kodunu yazacağım 1a :
class Araba{ public: Motor *r; Araba(int x, int y): { r = new Motor(x, y); } }; // Burada önce Araba cons. olur içersinde Motor cons. olur.
class Araba { private Motor m = new Motor(3, 5); public Araba(int x, int y){ System.out.println("Araba cons."); } }Evet arkadaşlar kısaca bir özet geçersek sahip olma ilişkisi olan senaryolarda kompozisyon kullanabiliriz. Kullanımı iki dilde açıklamaya çalıştım temel mantıkları aynı olduğundan ayrı ayrı açıklamak istemedim. Yazımın sonuna geldim umarım faydalı olmuştur. Hatam var ise güncellerken düzeltmeleri yapacağım. Teşekkürler.
10 Ocak 2014 Cuma
C 'de Belleklerle İşlemler
Merhaba arkadaşlar bugünkü konumuzda C 'de türden bağımsız işlemler (kopyalama vs.) yapacağız. Öncelikle jenerik programlama(Generic Programming) nedir bir ona el atalım. Jenerik programlama türden bağımsız programlamadır. Java, C++ gibi diller bunlara direk destek verirken biz yine C 'de kendi çabalarımız ile birşeyler yapmaya çalışacağız. Bunu yaparken bazı standart fonksiyonlardan yararlanacağız bunlar ; memset, memcpy, memmove, memchr, memcmp bunları birazdan prototipleri ile birlikte açıklayacağım.
Bu tarz bir programlama ne işimize yarar öncelikle ona bakalım. Bu tarz programlamadaki en büyük avantajlardan biri en basitinden bir fonksiyonu türe bağlı olmadan yazabilmektir. Örneğin standart qsort fonksiyonu türden bağımsız bir fonksiyondur ve ne türden dizi gönderirseniz onu sıralar. Böylece onca kodu tekrardan yazma zahmetinden kurtulmuş oluruz.
Kısaca void *
C 'de jenerik fonksiyon yazabilmemiz için öncelikle bilmemiz gerek bir tür var bunun adı void * türü. Jenerik bir fonksiyon yazmamız için parametremiz de belirli bir tür almamalıyız bunun çözümü ise void * 'dır.
void * her türden nesneyi tutabilen pointerdır. Fakat içeriğini, almak amacıyla kullanılamaz. Kullanılırken de istenilen türe cast edilmesi C++ 'da mecburi iken C 'de değildir fakat edilmelidir.
Bellek bloklarında işlem yapan fonksiyonlar
void aldığımız parametrelerin ne tür olduğunu bilmediğimizden bunlara atama vb. işlemler yaparken bellek bloklarını kullanmalıyız. Bunun için <string.h> 'da bildirilmiş fonksiyonlarımız var bunlar;
Memset
Bu tarz bir programlama ne işimize yarar öncelikle ona bakalım. Bu tarz programlamadaki en büyük avantajlardan biri en basitinden bir fonksiyonu türe bağlı olmadan yazabilmektir. Örneğin standart qsort fonksiyonu türden bağımsız bir fonksiyondur ve ne türden dizi gönderirseniz onu sıralar. Böylece onca kodu tekrardan yazma zahmetinden kurtulmuş oluruz.
Kısaca void *
C 'de jenerik fonksiyon yazabilmemiz için öncelikle bilmemiz gerek bir tür var bunun adı void * türü. Jenerik bir fonksiyon yazmamız için parametremiz de belirli bir tür almamalıyız bunun çözümü ise void * 'dır.
void * her türden nesneyi tutabilen pointerdır. Fakat içeriğini, almak amacıyla kullanılamaz. Kullanılırken de istenilen türe cast edilmesi C++ 'da mecburi iken C 'de değildir fakat edilmelidir.
Bellek bloklarında işlem yapan fonksiyonlar
void aldığımız parametrelerin ne tür olduğunu bilmediğimizden bunlara atama vb. işlemler yaparken bellek bloklarını kullanmalıyız. Bunun için <string.h> 'da bildirilmiş fonksiyonlarımız var bunlar;
Memset
void * memset ( void * ptr, int value, size_t num );
Bu fonksiyon atama işlemleri için kullanılır. İlk parametresi atanacak adresi alır, ikincisi atanacak değeri, üçüncüsü ise kaç baytını value ile atamak istediğini belirtir. Gönderilen adres ile geri döner.
Ör:
char str[] = "Guven";
char str[] = "Guven";
memset(str, 'c', 3);
puts(str);
Çıktı -> cccen olur.
Memcpy-Memmove
void * memcpy ( void * destination, const void * source, size_t num );
Bu fonksiyon bellek kopyalaması yapar. Kopyalama mantığı şu şekildedir birlikte memcpy yazalım nasıl olduğunu anlamış oluruz.
void * mymemcpy ( void * pDest, const void * pSource, size_t num) { char *pd = (char *)pDest; const char *ps = (const char *)pSource; while (num--) *pd++ = *ps++; return pDest; }
İşte size kendi yazdığımız basitçe memcpy fonksiyonumuz. Blok blok kopyalama yapar. Eğer bloklar çakışık ise memmove kullanmanızı öneririm.
void * memmove ( void * destination, const void * source, size_t num );
Protoip aynıdır işleme mantığıda benzerdir blokları kopyalar.
Memchr
void *memchr(const void *str, int c, size_t n);
Prototipine sahip fonksiyonumuz ilk parametresinde gönderdiğimiz nesnenin içinde ikinci parametrede gönderdiğimiz (Unsigned char) c karakterini arar. Bulduğu yerin adresini döner.
Kullanımı şu şekildedir.
const str[] = "Guven";
const char ch = 'u';
char *ptr;
ptr = (char *)memchr(str, ch, strlen(str));
// ptr burada str + 1 adresini tutmuş olur.
Memcmp
int memcmp(const void *str1, const void *str2, size_t n)
Protoripine sahip memcmp fonksiyonu karşılaştırma işlemini yapar. Eğer birinci büyükse pozitif ikinci büyükse negatif eşit iseler 0 değeri ile geri döner. Birinci ve ikinci parametre karşılaştırılacak nesneler üçüncü parametre ise kaç baytın karşılaştırılacağını ifade eder.
Bu fonksiyon ile karşılaştırılma yapılırken bayt bayt karşılaştırıldığını göz önüne alarak fonksiyonu kullanınız!
Bugünde yazımızın sonuna geldik arkadaşlar umarım faydalı olmuştur. Yazılarımı arada tekrar okuyarak eksikleri ve hataları güncellemekteyim hata veya eksik bulduğunuz kısımları bana iletebilirsiniz. Teşekkürler.
Kaydol:
Kayıtlar (Atom)