Önişlemci direktifleri konusuna devam ediyoruz.
YAZI İÇERİĞİ
#if
#else
#elif
#endif
#ifdef
#ifndef
#error
#warning
#hexcomment
#zero_ram
#fill_rom
#undef
#module
#ignore_warnings
#inline
#separate
#opt
#if, #else, #elif, #endif, #ifndef, #ifdef
Bu önişlemci direktiflerinin kolayca anlaşılması için örnekler üzerinden anlatım yapalım.
#define MAX_VAL 520 //MAX_VAL 520
#if MAX_VAL > 255 // MAX_VAL 255 ten büyükse
long sayac; // Sayaç değişkeni long yani 2 bytelık olsun
#else // MAX_VAL 255 ten büyük değilse
int sayac; // sayac değişkeni int yani 1 byte olsun
#endif
Görüldüğü gibi bu önişlemci direktiflerini kullanarak duruma bağlı kodlar oluşturabiliyoruz. Yapı aynı if, else, else if yapısındaki gibi.
#define MAX_VAL 1 // MAX_VAL 1 olur
#if MAX_VAL > 255 // MAX_VAL 255 ten büyükse
long sayac; // Sayaç değişkeni long yani 2 byte'lık olsun
#elif MAX_VAL > 1 // MAX_VAL 255'ten büyük değilse
int sayac; // sayac değişkeni int yani 1 byte olsun
#else // sayac 255 ten ve 1 den büyük değilse
BOOLEAN sayac; // sayac degiskeni 1 bit olacak (Boolean)
#endif
Bunlara benzer olarak #ifdef (if defined) bir tanımlamanın yapıdığının #ifndef (if not defined) ise yapılmadığının kontrolünü yapar.
#ifndef MAX_VAL // MAX_VAL tanımlanmamışsa
#define MAX_VAL 100 // MAX_VAL 100 olarak tanımla
#endif
#ifdef debug //debug tanımlı ise
printf("Herhangi bir hata oluşmadirn"); // ekrana mesaji yaz
#endif
İçerisinde değişken ve fonksiyon tanımlamalarının olduğu “surucu.h” adında bir başlık (Header) dosyamız olduğunu düşünelim.
int deger1,deger2,deger3;
long hesapla(int a, int b)
{
return ((a*b) / 5);
}
Şimdi bu dosya birden fazla dosya içerisinden #include ile dahil edilirse, derleyici kodu derlerken hata verir. İlk #include edilen dosya derlenirken surucu.h dosyası içerisindeki tanımlamalar yapıldığından #include edilen diğer dosya derlenirken zaten tanımlandığından hata oluşur. Bu durumun önüne geçmek için surucu.h dosyasını şu hale getirebiliriz.
#ifndef __SURUCU_H__ //__SURUCU_H__ tanımlı değilse
#define __SURUCU_H__ // tanımla
int deger1,deger2,deger3;
long hesapla(int a, int b)
{
return ((a*b) / 5);
}
#endif
derleyici ikinci kez bu dosyaya geldiğinde __SURUCU_H__ kelimesi tanımlanmış olacağından dosyayı işleme almayacağı için herhangi bir hata oluşmaz.
#error, #warning
Bu direktifler ile derleyiciyi hata veya uyarı mesajı vermesine zorlayabilirsiniz. Örneklere bakalım
#if BUFFER > 255 // BUFFER 255 ten büyükse
#error buffer cok buyuk // derleyici bu mesajı cikarir ve derlemeyi sonlandirir
#endif
#if BUFFER < 10 // BUFER 10 dan küçükse
#warning buffer tasmasi olusabilir // derleyici uyari mesaji cikarir ve derlemeye devam eder
#endif
Görüldüğü gibi #error (Hata) direktifinde derleyici çalışmasını sonlandırıyor #warning (Uyarı) direktifinde devam ediyor.
#hexcomment
Bu direktif kullanılarak derleyicinin PIC'i programlamak için oluşturduğu .hex dosyasının başına veya sonuna yorum satırları eklenebilir.
#hexcomment version 1.2 4 mhz kristal // dosya başına eklenir
#hexcomment version 1.2 4 mhz kristal // dosya sonuna eklenir
#zero_ram
Bu direktif RAM değişkenlerinin sıfırlanmasını sağlar. Böylece program başladığında değişkenler rast gele değerler almazlar. Değişkenlerinizin başlangıç değerlerini veriyorsanız kullanmak zorunda değilsiniz
#zero_ram
main()
{
}
#fill_rom
Bu direktif ile kullanılmayan rom alanına istenilen değer yazılır. #fill_rom deger şeklinde kullanılır.
#fill_rom 0x36 // programın bitiminden itibaren
// boş kalan bölgeye 0x36 değerini yaz
#undef
Bu direktifi aslında #define'yianlattığım konuda işleyecektim ama gözden kaçırmışım :) #undef direktifi #define ile yapılan bir tanımlamayı geçersiz kılmak için kullanılır
#include "tanimlar.h" // tanimlar.h dosyasını koda dahil et
#if MAKSIMUM < 100 // MAKSIMUM 100 den küçükse
#undef MAKSIMUM // MAKSIMUM için yapılan tanımlamayı iptal et
#define MAKSIMUM 100 // MAKSIMUM 100 olarak tekrar tanımla
#endif
#module
Bu direktif kullanılarak kod içerisindeki bazı global tanımlamaların sadece o dosya için geçerli olması sağlanır. Aşağıdaki örnekte #module direktifinden sonra gelen tüm tanımlamalar sadece aynı dosya içerisinde kullanılabilir olurlar.
int GetCount(void);
void SetCount(int newCount);
#MODULE
int g_count;
#define G_COUNT_MAX 100
int GetCount(void) {return(g_count);}
void SetCount(int newCount) {
if (newCount>G_COUNT_MAX)
newCount=G_COUNT_MAX;
g_count=newCount;
}
Yukarıdaki kodların bulunduğu dosya bir başka dosya tarafından #include edildiğinde GetCount() ve SetCount() fonksiyonları o dosyadan çağırılabilirler. #module direktifinden sonra gelen G_COUNT_MAX ve g_count değişkeni ise dahil eden dosya tarafından ulaşılamaz.
#ignore_warnings
Derleyicinin ürettiği warning (uyarı ) mesajlarını yönetmek için kullanılan bu direktif şu üç şekilde kullanılabilir
#ignore_warnings ALL //Tüm uyarı mesajlarını kapat , hiç warning mesajı almazsınız
#ignore_warnings NONE // Tüm uyarı mesajlarını göster
#ignore_warnings 203 // 203 nolu uyarıyı yok say
#ignore_warnings 203,202 // 203 ve 202 nolu Uyarıları yok say
örneğin while(1) kodu için derleyici "Condition Always True" yani durum her zaman doğru şeklinde bir uyarı verir ve bu uyarının numarası 203'tür. #ignore_warnigs 203 satırını koda eklerseniz uyarı mesajı çıkmaz.
#inline
Bu direktif verildikten sonra gelen fonksiyon inline olarak tanımlanır. Fonksiyonun inline olması demek kod içerisinde fonksiyonun çağrıldığı tüm noktalara fonksiyonun bir kopyasının yerleştirileceği manasına gelir. Bu şekilde kullanmanın avantajı daha hızlı çalışma Stack alanından tasarruf dezavantajı ise fazla kod üretilmesidir. Herhangi bir direktif verilmediğinde fonksiyonun inline olup olmamasına derleyici karar verir.
#inline
swapbyte(int &a, int &b) {
int t;
t=a;
a=b;
b=t;
}
swapbyte() fonksiyonunun çağrıldığı her yere aynı kod derleyici tarafından yerleştirilir.
#separate
Bu direktif ise #inline direktifinin aksine fonksiyonları ayrık yapar. Yani fonksiyon her çağrıldığında yazmaçlar Stack alanına yedeklenip fonksiyonun bulunduğu adrese dallanılır ve fonksiyondan dönerken dönüş adresleri Stack'ten geri çekilerek program kaldığı yerden devam eder. Böylelikle daha az kod üretilirken daha fazla Stack kullanılmış olur.
#opt
Bu direktif ile derleyiciye optimizasyon seviyesi belirtilir. 16f serisi için full optimizaston seviyesi 9 18Fxxx için 11 dir. Kodunuz PIC'e sığmadığında veya çalışma hızı sorunlarında optimizasyon seviyesi ile oynayabilirsiniz.
#opt 6 // optimizasyon seviyesi 6
Bir yazımızın daha sonuna gelmekle beraber "Önişlemci Direktifleri" konusunun sonuna henüz gelmemiş bulunuyoruz. Konuyla ilgili 2 adet yazı daha yayınlayacağım inşallah. O yazılarda görüşmek üzere
Güzel bir yazı olmuş, CCS C nin “help”ini her zaman anlayamıyorum, açıklamalarınızla öğrenmiş oldum :) teşekkür ederiz. İyi çalışmalar dilerim.
Eyvallah
Hep beraber öğreniyoruz :)
Hocam sayenizde çok şey öğrendim.
Diğer yazılarınızı sabırsızlıkla bekliyoruz.
İyi günler, çalışmalar…
hocam emeklerinize teşekkür ederiz, verdiğiniz bilgier gerçekten çok güzel. Hele yani başlayanlanlara çok yayrlı olacağın düşünüyorum. Çalışmalarınızın devamını dileriz. :) Yaşasın C CCS:):)
@Hasan & gazi
Eyvallah devamı gelecek inşallah bu aralar biraz yoğunum en kısa sürede bitireceğim önişlemci konusunu
s.a bi sorum olucak nette surf yaparken bazı sitelerde resim doğrulama bölümü gelmiyo..mesela tc no bakarken x işareti veriyo ve bakamıyom…kablosuz bağ.kullanıyom bide bilg.format attım acba program mı gerekiyo onun için yoksa modem yazılımını mı güncellicem eğer 2. şık ise modemi nasıl güncellerim :)
Diğer sitelerde resimler normal çıkıyorsa, belki java’yı yüklemen gerekebilir.
http://www.java.com/tr/
[...] İşlemler İçin Kullanılan Dahili Fonksiyonlar 09- Derleyici Önişlemci Direktifleri – 1 10- Derleyici Önişlemci Direktifleri – 2 11- Derleyici Önişlemci Direktifleri – 3 12- Gecikme (Delay) Fonksiyonları ve [...]
#elif MAX_VAL > 1 // MAX_VAL 255′ten büyük değilse
burdaki 1 doğrumu Neye göre 255ten büyük değilse diye yorumlanıyor…
#elif MAX_VAL >255 olması gerekmiyormuydu ?
255 ten büyük değilse diyor, büyükse demiyor büyükse kontrolü if satırında yapılıyor.