Objective C ön işlemcisi, her direktifi satır bazında işleme soktuğu için, define direktifi içinde daha önceki bir define ile tanımlanmış bir değere referans verilebilir. Örneğin;
#define BIRIM_UCRET 5
#define NORMAL 40
#define FAZL_MES_SAAT_UCR 8
#define HAFTALIK_CALISMA 47
#define UCRET BIRIM_UCRET*NORMAL+\
(HAFTALIK_CALISMA\
-NORMAL)*FAZL_MES_SAAT_UCR
şeklindeki tanımlamalar geçerlidir. Burada, normal saat ücreti NORMAL ve fazla mesai ücreti de FAZL_MES_SAAT_UCR adlı alanlarda saklanıyor.
Personelin haftalık normal çalışma süresi olan 40 saat NORMAL alanında ve haftalık toplam çalışma süresi (fazla mesai ile birlikte) HAFTALIK_CALISMA alanlarında saklanıyor.
Personelin haftalık ücreti ise UCRET adlı alanda saklanıyor ve
UCRET =BIRIM_UCRET*NORMAL+
(HAFTALIK_CALISMA-NORMAL)*
FAZL_MES_SAAT_UCR
şeklinde hesaplanmak isteniyor.
KOD BLOĞU:
#define BIRIM_UCRET 5
#define NORMAL 40
#define FAZL_MES_SAAT_UCR 8
#define HAFTALIK_CALISMA 47
#define UCRET BIRIM_UCRET*NORMAL+\(HAFTALIK_CALISMA\-NORMAL)*FAZL_MES_SAAT_UCR
#import <Foundation/Foundation.h>
int main(int argc, char* argv[])
{
NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
NSLog(@"\nUCRET=%i",UCRET);
[pool drain];
return 0;
}
PROGRAMIN ÇIKTISI:
UCRET=256
AÇIKLAMA:
Burada beklediğimiz gibi bu personele ait haftalık ücret,
40*5+7*8=256
olarak bulunmuştur.
Ancak bazı durumlarda makro tanımında dikkatli olmalıyız. Örneğin; aşağıdaki örnekte, normal ve fazla mesai saat ücreti aynı kabul edilerek SAAT_UCRETI 10 olarak belirlenmiştir ve
TOPLAM_SAAT=NORMAL+FAZLA
UCRET=TOPLAM_SAAT*SAAT_UCRETI
bağıntıları ile toplam ücret belirlenmek isteniyor. Normal olarak sonucun
TOPLAM_SAAT=40+7=47 ve UCRET=47*10=470
olarak hesaplanması beklenir. Oysa, aşağıda görüldüğü gibi sonuç 110 çıkıyor.
KOD BLOĞU:
#define NORMAL 40
#define FAZLA 7
#define SAAT_UCRETI 10
#define TOPLAM_SAAT NORMAL+FAZLA
#define UCRET TOPLAM_SAAT * SAAT_UCRETI
#import <Foundation/Foundation.h>
int main(int argc, char* argv[])
{
NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
NSLog(@"\nUCRET=%i",UCRET);
[pool drain];
return 0;
}
PROGRAMIN ÇIKTISI:
UCRET=110
Bunun nedeni şudur:
#define TOPLAM_SAAT NORMAL+FAZLA
tanımı ile TOPLAM_SAAT alanına,
40+7
stringi aktarılır.
#define UCRET TOPLAM_SAAT * SAAT_UCRETI
tanımı içinde de TOPLAM_SAAT alanı içine bu string yerleştirilir ve
40 + 7 *10
ifadesine erişilir. Bu ifade içinde çarpma öncelikli olduğu için önce çarpma yapılır ve
40+70=110
değeri hesaplanır. Bunu önlemenin yolu uygun parantezler kullanmaktır. Aşağıdaki düzeltilmiş versiyonu dikkatle inceleyelim:
DÜZELTİLMİŞ VERSİYON:
#define NORMAL 40
#define FAZLA 7
#define SAAT_UCRETI 10
#define TOPLAM_SAAT (NORMAL+FAZLA)
#define UCRET TOPLAM_SAAT * SAAT_UCRETI
#import <Foundation/Foundation.h>
int main(int argc, char* argv[])
{
NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
NSLog(@"\nUCRET=%i",UCRET);
[pool drain];
return 0;
}
PROGRAMIN ÇIKTISI:
UCRET=470
Düzeltilmiş versiyonda, TOPLAM_SAAT yerine (40+7) stringi aktarılır. UCRET yerine ise, (40+7)*10 stringi aktarılır ve hesaplama 47*10=470 şeklinde yapılır.
ÖRNEK:
KARE adlı ve KARE(X) şeklinde tek bir argümanı olan ve bu argümanın karesini hesaplayan bir makro oluşturmak isteyelim. Bu durumda:
#define KARE(x) x*x
şeklindeki bir tanım bize çok doğru ve doğal görünür. Oysa bu makroyu KARE(a+3) şeklinde çağırdığımızda, makro ifadesi
a+3 * a+3
şeklinde bir stringe dönüşecektir. Bunun sonucunda ise hesaplanacak olan şey
a+3*a+3 ya da 4a+3
ifadesi olacaktır. Oysa başlangıçta hesaplamak istediğimiz şey (a+3)2 ifadesiydi. Tamamen farklı ve hatalı bir sonuca varılmış oldu.
Burada da çözüm, uygun parantezleri yerleştirmektir. Aşağıdaki C programı KARE adlı makroyu doğru biçimde tanımlıyor ve örnek bir veri ile birlikte kullanıyor:
KOD BLOĞU:
#define KARE(x) (x) *(x)
#import <Foundation/Foundation.h>
int main(int argc, char* argv[])
{
NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
int i;
NSLog(@"\SAYI\tKARESİ\n");
for (i=1; i<=5; i++)
NSLog(@"\n%i\t%i ",i,KARE(i));
[pool drain];
return 0;
}
PROGRAMIN ÇIKTISI:
SAYI KARESI
1 1
2 4
3 9
4 16
5 25