C Preprocessor Komutları

Standart

C kodları compiler’a aktarılmadan önce preproccesor tarafından düzenlenir. Preprocessor komutları ile yazdığımız kısımlar preprocessor tarafından derlenir. Ve bu komutlar c kodlarından çok daha farklıdır. Ön işlemci komutları hash(#) ile başlar. Örnegin #include, #define.

#define Direktifi

Program içinde kullanılacak olan sembolik sabitleri tanımlamak için kullanılır. C diline const keyword’ü eklenmeden önce sabit tanımlamak için tek yoldu.

#define PI 3.14

Bu önişlemci komutunun genel kullanımı ise aşagıdaki gibidir.

#define İDENTİFİER replacement-text

Makrolar da #define önişlemci komutuyla tanımlanmaktadır. Define kullanarak c içinde daha önceden tanımlanmış her fonksiyonunda adını değiştirebiliriz ve fonksiyonu yeni ismiyle çağırabiliriz.

#define CIRCLE_AREA( x ) ( ( PI ) * ( x ) * ( x ) )
//makro tanımı
area = CIRCLE_AREA( 4 );
//ve kullanımı
#define PRİNTER printf
//printf yerine PRINTER kullancağız
#define PRİNTER("Bu fonsiyonun adı artık printf değil");
//Yeni adıyla printf fonksiyonunu çağırdık.

#define counter( x ) int i; for ( i = 0; i < (x); i++ ) printf( "%d\n",i );
//girilen sayiya kadar ekrana basan makro

Herşeyi tek bir kodda toparlarsak daha anlaşılır olacak.

#define BEGIN { //{ yerine BEGIN kullanılsın
#define END } //} yerine END kullanılsın
#define PRINTER printf //printf yerine PRINTER
#define MESAJ "define deneme"
#define MAIN_PROGRAM main( ) //main yerine MAIN_PROGRAM kullanılacak

PROGRAM
BEGIN
YAZ(MESAJ);
END

#include Direktifi

Ön işlemci komutları arasında bize en tanıdık geleni çünkü her programımızda c kütüphane fonksiyonlarını kullanabilmek için #include komutunu kullanıyoruz. C kütüphanelerinde bulunan veya kendi yazdığımız bir header dosyasındaki fonksiyonları
#include direktifi kullanarak programımız içinden kullabiliriz.

#include komutunu iki şekilde kullanabiliyoruz.

#include <filename> //C kütüphanelerini kullanmak için <> arasına filename yazarak
#include "filename" //Kendi oluşturduğumuz header dosyasını eklemek için "" kullanırız.

Koşullu Derlme

Koşullu derleme önişlemci direktiflerinin yürütülmesinin ve program kodunun derlenmesini kontrol etmenizi sağlar. #if direktifi örnek kullanımı aşağıda örneklenmiştir.

#if !defined(MY_CONSTANT)
#define MY_CONSTANT 0
#endif
//Bu kod parçası eğer MY_CONSTANT tanımlanmadıysa tanımlamamızı sağlıyor.

Her #if yapısı #endif ile sonlanır.#ifdef and #ifndef direktifleri #if defined(name) ve #if !defined(name) direktiflerinin kısaltılmışı olarak kullanılabilir. #elif ve #else koşul dallanacağı zaman kullanılmaktadır. Genel yapısına bakmak gerekirse:

#if koşul 1
//komutlar
#elif koşul 2
//komutlar
#elif koşul 3
//komutlar
#else
//komutlar
#endif

Koşullu derleme kullanrak programı daha rahat bir şikilde test edebiliriz.

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

#define SIZE 9

void sirala(int* a, const int size);

int main()
{
int a[SIZE] = {1,5,2,12,7,9,4,19,11};
sirala(a,SIZE);
return 0;
}
void sirala(int* a, const int size)
{
int i,j, k;
#if DEBUG
printf("Sıralamadan önce:\n");
for(i = 0; i < size; i++)
{
printf("%d ",a[i]);
}
#endif // DEBUG
for (i = 1; i < size; ++i)
{
k = a[i];
j = i - 1;
while ((j >= 0) && (k < a[j]))
{
a[j + 1] = a[j];
--j;
}
a[j + 1] = k;
}
#if DEBUG
printf("\nSıralamadan sonra:\n");
for(i = 0; i < size; i++)
{
printf("%d ",a[i]);
}
#endif // DEBUG
}

Eğer DEBUG tanımlandıysa kodumuz debug modunda çalışacak demektir. Eğer tanımlanmadıysa #if DEBUG ile kapsanan alanlar çalışmaycaktır.
% cc -DDEBUG -g -o prog main.c
compile kodunda DEBUG’ı tanımlayarak programı debug modunda çalıştırabiliriz.

#error Direktifi

Bu direktif makro komutların işleyişi sırasında bir uyuşmazlık olduğunda kullanılarak programın derleme işlemine
başlamadan hata vererek çıkmasını sağlar. Eğer yazılımı derleyeceğimiz makinede GCC compiler yoksa bunu kontrol edip hata olarak bildirebiliriz.

#ifndef __GCC__
#error Bu kodun isletilebilmesi icin GCC compiler gereklidir.
#endif

# ve ## Operatörleri

Bu operatörleri aşağıdaki kod bloğu üzerinde anlatmak daha anlaşılır olacak.

#include <stdio.h>
//aşağıda tanımlı makroda iki operatörde kullanılmış.# operatörü birlikte kullanıldığı
//değişkenin string muamelesine tabi tutulmasını sağlar aşağıdaki örnektede görüldüğü gibi
//paster fonksiyonu parametre olarak aldığı n değerini # ile birlikte fonksiyona string
//olarak göndermektedir.

#define paster( n ) printf_s( "token" #n " = %d", token##n )
int token9 = 9;

//gelelim ## operatörüne bu öperatör ise iki atomu birleştirir. Token ile 9 u birleştirip
//hemen yukarıda tanımlanmış token9 değişkenini kullanmamızı sağlıyor.

int main()
{
paster(9);
//sonuç olarak burada token9 = 9 sonucu ekrana basılacaktır.
}

Charizing Operator (#@)

Bu operatör sadece makrolarda kullanılabilir. Aşagıdaki makroda parametre olarak alınan x değeri bu operatörü kullanarak char’a dönüştürülüyor. Kullanımından ve isminden anlaşılacağı gibi önünegeçtiği değeri char’a dönüstürür.

#define makechar(x) #@x

#line Preprocessor Direktifi

Bu komut kendinden sonra gelen tüm kaynak kod satırlarının belirlenen tamsayı sabitinin
değerlerinden başlayarak numaralandırılmasını sağlar.

#line 100

komutu kendisinden sonra başlayan satıları 100’den başlayarak numaralandırır.

#include <stdio.h>
#define LINE200 200

int main(void)
{
func_1();
func_2();
}

#line 100
func_1()
{
printf("Func_1 - the current line number is %d\n",__LINE__);
}

#line LINE200
func_2()
{
printf("Func_2 - the current line number is %d\n",__LINE__);
}

Kodu aşağıdaki çıktıyı üretmektedir.

Func_1 – the current line number is 102
Func_2 – the current line number is 202

Önceden Tanımlanmış Sembolik Sabitler

__LINE__ //kullanılan kaynak kodun satır numarası yukarıda bir örneği bulunmaktadır.
__FILE__ //kaynak kodun varsayılan ismidir.
__DATE__ //kaynak kodun derlendiği tarihtir. Aaa gg yyyy formatındadır
__TIME__ //kaynak kodun derlendiği zamandır. ss:dd:sn formatındadır

Bildiriler(Assertions)

Assert makrosu bir deyimin değerini test eder. Ve bu değer istenilen aralıkta veya istenilen bir değere
eşit değilse yani karşılaştırma değeri 0 dönerse assert bir hata mesajı yazdırıp fonksiyonu sonlandırır.

#include <stdio.h>
#include <assert.h>

main()
{
int x;
printf("\nEnter an integer value: ");
scanf("%d", &x);
assert(x >= 0);
printf("You entered %d.\n", x);
return(0);
}

Enter an integer value: 10
You entered 10.
Enter an integer value: -1
Assertion failed: x, file list19_3.c, line 13
Abnormal program termination

Yorum bırakın