توی Macro ها کدهایی رو مینویسی که Preprocessor اونها رو اجرا میکنه .
یعنی پیش از اینکه Compiler کارش رو آغاز میکنه .
شما میتونه با Macro ها کدی رو به کد برنامه پیش از اینکه بدست Compiler ترجمه بشه اضافه کنی.
مثال :
#define DECL_FUNC(return_value,name,p1,p2) \
return_value name (p1 a,p2 b) \
DECL_FUNC(int,myFunc,float,float)
{
return (int) (a * b);
}
اگه خوب ببینی میفهمی که کاری که این ماکرو میکنه رو نمیشه با یک تابع کرد !
-- UPDATE --
شما باید مفهوم Preprocessor رو متوجه بشید . Preprocessor بخشی از Compiler هست که میاد قبل از اینکه کد شما Compile بشه خود کد رو تغییر میده .
تمام دستور هایی که با '#' شروع میشن جزو دستورهای Preprocessor هستند مثل :
#define
#include
#ifdef
#ifndef
#endif
#pragma
......
و دستورهای دیگه ای که مثل این دستورها دارای # هستند .
برای اینکه متوجه بشید کد بالا رو یه بار تحلیلش میکنیم .
ما بالا با دستور define# یه Macro تعریف کردیم به اسم DECL_FUNC . و Macro ها جزو Preprocessor هستند . شاید یکم به تابع های معمولی شباهت داشته باشن ولی کلا فرق دارن .
ماکروی DECL_FUNC در واقع ۴ تا ورودی داره به نام های return_value و name و p1 و p2 .
ورودی های ماکرو مثل ورودی های تابع های معمولی نیستند که بخوان از نوع خاصی باشن . در واقع ورودی های ماکرو ها هر نوشته ای میتونن باشن . و کاری که ماکرو میکنه اینه که چیزهایی که به عنوان پارامتر بهش داده شده رو با ورودی های خودش جابجا میکنه و بدنه ی
بدست اومده رو دقیقا همونطوری که هستند میاد میگذاره داخل کد .
حالا بعدش که ما توی کد از ماکروی DECL_FUNC استفاده کردیم این مقادیر رو بهش دادیم : int , myFunc , float , float .
و حالا وقتی که شما مبخواید کد رو Compile کنید ، اول Preprocessor میاد کد رو میخونه و دستورهای مربوط به خودش رو که همون ماکرو ها و ثابت ها هستند رو اجرا میکنه .
Preprocessor توی کد به دستور define# برمیخوره و ماکرویی که جلوش تعریف شده (همون DECL_FUNC ) رو توی خودش نگه میداره .
و حالا جلو تر به جایی برمیخوره که ما ماکروی DECL_FUNC رو صدا زدیم .
کاری که اینجا میکنه اینه که میاد بدنه ی ماکروی DECL_FUNC رو که ما براش تعریف کردیم رو جای کد ما میزاره و پارامترهایی که ما بهش دادیم رو با اون پارامتر های خودش عوض میکنه .
مثلا ما نوشتیم :
DECL_FUNC(int,myFunc,float,float)
Preprocessor این رو میبینه و بدنه DECL_FUNC رو اینجا توی کد قرار میده . درواقعا نتیحه میشه :
return_value name (p1 a,p2 b)
و حالا مقدارهایی رو که ما به ماکرو دادیم رو با مقدار های خود ماکرو جابجا میکنه و نتیجه نهایی میشه :
int myFunc (float a,float b)
اگه دقت کنید ماکرو ۴ تا پارامتر داشت . return_value,name,p1,p2 .
و ما اینها رو بهش دادیم :int,myFunc,float,float .
و پارامترهای ما رو به ترتیب جایگذین خودش کرد .
یعتی :
int میاد جای return_value
myFunc میاد جای name
float میاد جای p1
float میاد جای p2
به طور کلی این کدی هست که ما داریم :
#define DECL_FUNC(return_value,name,p1,p2) \
return_value name (p1 a,p2 b) \
DECL_FUNC(int,myFunc,float,float)
{
return (int) (a * b);
}
و این کدی هست که بعد از مرحله ی اجرای Preprocessor بدست Compiler میرسه :
int myFunc (float a,float b)
{
return (int) (a * b);
}
توی کد نهایی چیزی به نام DECL_FUNC وجود نداره . DECL_FUNC فقط یک ماکرو کمکی هست که در کد نهایی بدنه خودش رو داخل کد قرار میده و وجود خارجی توی کد اصلی نداره .
همونطور که میبینید ماکروی که ما صدا زدیم با جابجایی تبدیل به یک تابع معمولی شد و return هم جزو همین تابع هست .