Ana sayfa > Programlama > C++ Programlama > Önişlemci direktifleri

Önişlemci direktifleri

► Detaylı anlatım

Derleme işleminin ilk safhasında, önişlemci derleyiciye bazı direktifler ulaştırır. Derleyici tarafından bazı özel işlemlerin yapılmasını sağlayan bu direktiflere Önişlemci Direktifleri adı verilir. Şimdi, önişlemci direktiflerini sıra ile incelemeye çalışalım:

#define önişlemci direktifi

#define önişlemci direktifi, programlarımızın herhangi bir işlem satırında kullanılmak üzere, istediğimiz ifadelerin kısa bir isim altında tanımlamamızı sağlar. #define önişlemci direktifinin genel yapısı aşağıda gösterilmektedir:

#define makro-adı karakter-dizisi

Yukarıdaki işlem satırını programımızın başında kullandığımızda, program makro-adı ifadesi ile gösterilen makro adını gördüğü her yerde karakter-dizisi ifadesi ile gösterilen karakter dizisi yazılmış gibi hareket eder. #define önişlemci direktifinin tanımlandığı satır normal işlem satırları gibi noktalı virgül işareti ile sona ermez.

Kullandığımız makro adlarını küçük veya büyük harflerle tanımyabiliriz. Programların daha kolay anlaşılması için büyük harf kullanılması tercih edilebilir. Makro adı ile karakter dizisi arasında bir veya birden fazla boşluk bırakabilirsiniz.

Şimdi, #define önişlemci direktifinin kullanılmasını bir örnek üzerinde incelemeye çalışalım:


#include <iostream>

using namespace std;

#define MAK01 "ABCDE"

int main(void)
{
  cout << MAK01; // = cout << "ABCDE";

  return 0;
}

Yukarıdaki programı derleyip çalıştırdığımızda, aşağıdaki ifadeleri ekrana yazar:

ABCDE

Program, "ABCDE" karakter dizisine karşılık gelen MAK01 adlı bir makro tanımlar. main() fonksiyonu içindeki işlem satırında MAK01 ifadesi yerine "ABCDE" karakter dizisi otomatik olarak yerleştirilmektedir.

Makro işlemlerinde, #define satırında tanımlanan ve program içinde makro adının yerine kullanılan ifade ister karakter ister sayısal değerler içersin, daima bir karakter dizisi olarak kabul edilir.

#include önişlemci direktifi

En çok kullanılan ve sistem tarafından hazır olarak sunulan fonksiyonlar kütüphane dosyaları adı verilen .LIB uzantılı dosyalara yerleştirilmiştir. Bu dosyalarda yer alan kütüphane fonksiyonlarının prototipleri ise başlık dosyası adı verilen .H uzantılı dosyalarda yer alır.

#include direktifini kullanarak, başlık dosyalarında bildirimleri yer alan fonksiyonları programımızda yazılmış gibi kullanabiliriz.

Aşağıdaki satırı programımıza dahil ettiğimizde, <cstdio> başlık dosyası içinde bildirimleri bulunan bütün kütüphane fonksiyonlarını, programımızda yazılmış gibi kullanabiliriz:


#include <cstdio>

#include önişlemci direktifini aşağıda gösterilen 2 farklı şekilde kullanabiliriz.


#include <dosya-adı>
#include "dosya-adı"

Eğer dosya adını < > işaretleri arasında tanımlarsak, derleyici tanımladığımız dosyayı başlık dosyalarının içinde bulunduğu alt dizinde arar. Bu dizin genellikle include alt dizinidir. Eğer dosya adını " " işaretleri arasında tanımlarsak, derleyici tanımlanan dosyayı önce aktif dizinde, daha sonra diğer dizinlerde arar. " " işaretlerini kullandığımızda, eğer varsa, derleyici tanımladığımız dosyayı mutlaka bulur. Sistem uygun şekilde düzenlendiğinde, < > işaretlerini kullanmak derleme zamanını kısaltır.

Şimdi, #include önişlemci direktifinin kullanılmasını örnekler üzerinde incelemeye çalışalım:


#include <iostream>
#include <cstring>

using namespace std;

int main(void)
{
  char cdizi[20];

  strcpy(cdizi, "Bilgisayar");

  cout << cdizi;

  return 0;
}

Yukarıdaki programı derleyip çalıştırdığımızda, aşağıdaki ifadeleri ekrana yazar:

Bilgisayar

Program, bir karakter dizisine "Bilgisayar" kelimesini atar ve dizi değerini ekrana yazar. iostream ve cstring başlık dosyalarının her ikisini de < > işaretleri arasında tanımlar.


#include <iostream>
#include "cstring"

using namespace std;

int main(void)
{
  char cdizi[20];

  strcpy(cdizi, "Bilgisayar");

  cout << cdizi;

  return 0;
}

Program, bir önceki program tarafından yapılan işlemin aynısını gerçekleştirir. Tek fark, başlık dosyalarının birini < >, diğerini ise " " işaretleri arasında tanımlamış olmasıdır.

Koşula bağlı derleme

C++'da, yazılan programların belirli bölümlerini seçeneğe bağlı olarak derleyebiliriz. Bu işleme Koşula Bağlı Derleme adı verilir. Koşula bağlı derleme aşağıdaki direktifler tarafından gerçekleştirilir:


#if
#else
#elif
#endif
#ifdef
#ifndef

#if direktifinin genel yapısı aşağıda göstermektedir:


#if sabit-ifade
   işlem-satırları
#endif

Burada, sabit-ifade değeri doğru sonuç verirse #if ile #endif satırı arasında kalan bütün işlem satırları derlenir, aksi takdirde derleyici bu satırları derlemeden geçer. Derlemenin ilk safhası önişlem safhası olduğu için burada bahsi geçen sabit-ifade yerine herhangi bir değişken değeri kullanamayız. #if ve #endif direktiflerinin kullanılmasını örneklerle incelemeye çalışalım:


#include <iostream>

using namespace std;

#define MAK01 20
#define MAK02 50

int main(void)
{
  #if MAK01<MAK02
     cout << "MAK01 değeri MAK02 değerinden küçüktür." << "\n";
     cout << "MAK01 değeri: " << MAK01 << "\n";
     cout << "MAK02 değeri: " << MAK02;
  #endif

  // Aşağıda yer alan işlem satırları derleyici tarafından derlenmez.
  #if MAK01>MAK02
     cout << "MAK01 değeri MAK02 değerinden büyüktür." << "\n";
     cout << "MAK01 değeri: " << MAK01 << "\n";
     cout << "MAK02 değeri: " << MAK02;
  #endif

  return 0;
}

Yukarıdaki programı derleyip çalıştırdığımızda, aşağıdaki ifadeleri ekrana yazar:

MAK01 değeri MAK02 değerinden küçüktür.
MAK01 değeri: 20
MAK02 değeri: 50

Program, MAK01 değeri MAK02 değerinden küçük olduğundan, sadece ilk #if direktifi içinde yer alan satırları derler. İkinci #if direktifi içinde yer alan işlem satırları hiç derlenmez.

#if direktifi ile birlikte #else direktifini kullanabiliriz. #else direktifinin genel yapısı aşağıda gösterilmektedir:


#if sabit-ifade
   işlem-satırları
#else
   işlem-satırları
#endif

#if satırında yer alan sabit-ifade doğru sonuç verirse, #if direktifi ile ilgili işlem satırları, aksi takdirde #else direktifi ile ilgili işlem satırları derlenir. Bu özelliği örnekler üzerinde incelemeye çalışalım:


#include <iostream>

using namespace std;

#define MAK01 1

int main(void)
{
  int id;

  #if MAK01 == 1
     for (id=0; id<10; id++) cout << id+1 << " ";
  #else
     for (id=10; id>0; id--) cout << id << " ";
  #endif

  return 0;
}

Yukarıdaki programı derleyip çalıştırdığımızda, aşağıdaki ifadeleri ekrana yazar:

1 2 3 4 5 6 7 8 9 10

Program, #if satırındaki ifade doğru sonuç verdiği için, sadece #if direktifi ile ilgili işlem satırını derler ve 1'den 10'a kadar olan sayıları ekrana yazar. Diğer işlem satırları hiç derlenmez.


#include <iostream>

using namespace std;

#define MAK01 2

int main(void)
{
  int id;

  #if MAK01 == 1
     for (id=0; id<10; id++) cout << id+1 << " ";
  #else
     for (id=10; id>0; id--) cout << id << " ";
  #endif

  return 0;
}

Yukarıdaki programı derleyip çalıştırdığımızda, aşağıdaki ifadeleri ekrana yazar:

10 9 8 7 6 5 4 3 2 1

Program, #if satırındaki ifade yanlış sonuç verdiği için, sadece #else direktifi ile ilgili işlem satırını derler ve 1'den 10'a kadar olan sayıları sondan başlayarak ekrana yazar. Diğer işlem satırları ise hiç derlenmez.

Aşağıda genel yapısı verilen #elif direktifini kullanarak bir if-else-if merdiveni oluşturabiliriz:


#if sabit-ifade1
   işlem-satırları
#elif sabit-ifade2
   işlem-satırları
#elif sabit-ifade3
   işlem-satırları
.
.
.
#endif

if-else-if merdiveninde doğru olan ilk ifadenin yer aldığı #if veya #elif satırına bağlı olan işlem satırları derlenir, diğer işlem satırları derleyici tarafından dikkate alınmaz. if-else-if merdiveninin kullanılmasını bir örnek üzerinde incelemeye çalışalım:


#include <iostream>

using namespace std;

#define MAK01 3

int main(void)
{
  int id;

  #if MAK01 == 1
    for (id=1; id<=10; id++) cout << id << " ";
  #elif MAK01 == 2
    for (id=2; id<=10; id++) cout << id << " ";
  #elif MAK01 == 3
    for (id=3; id<=10; id++) cout << id << " ";
  #endif

  return 0;
}

Yukarıdaki programı derleyip çalıştırdığımızda, aşağıdaki ifadeleri ekrana yazar:

3 4 5 6 7 8 9 10

MAK01 makrosuna 1 ile 3 arasındaki sayılardan hangisini atarsak, program o sayıdan başlamak suretiyle 10'a kadar olan sayıları ekrana yazar.