پیش پردازندهها دستوراتی هستند که به کامپایلر اعلام خواهند کرد که اطلاعات را پیش از آغاز عملیات کامپایل، چگونه پیش پردازش کنند.
همه دستورات پیشپردازنده با # آغاز میشوند. در هر خط، قبل از دستور پیش پردازنده فقط استفاده از کارکترهای فضای خالی مجاز است. دستورات پیشپردازنده دستورات ++C به حساب نمیآیند، بنابراین پس از آنها سمیکالن (;) قرار نمیگیرد.
تاکنون دستور include# را در تمام مثالهای خودمان دیدهایم. این ماکرو برای ضمیمه کردن یک هدرفایل در فایل سورس به کار میرود.
++C از چندین دستور پیشپردازنده پشتیبانی میکند.
این دستورات شامل «include ،#define ،#if ،#else ،#line#» و … هستند. اجازه دهید برخی از مهمترین آنها را بررسی کنیم.
پیشپردازنده define#
این پیشپردازنده، ثابتهای نمادین (symbolic constant) ایجاد میکند. این ثابتهای نمادین ماکرو (macro) نامیده میشوند و شکل کلی زیر را دارند.
#define macro-name replacement-text
پس از نوشتن این خط، تمام ماکروهای متعاقب پیش از کامپایل برنامه، با عبارت replacement-text جایگزین میشوند. به عنوان مثال:
#include <iostream> using namespace std; #define PI 3.14159 int main () { cout << "Value of PI :" << PI << endl; return 0; }
اکنون، با فرض داشتن سورس فایل، اجازه دهید کد را پیشپردازش کنیم. اجازه دهید کد را با گزینه E– کامپایل کرده و نتیجه را در test.p ذخیره کنیم. اکنون، اگر test.p را بررسی کنیم، در آن اطلاعات زیر را خواهیم یافت، و مشاهده خواهیم کرد که مقادیر پیشپردازنده جایگزین شدهاند.
$gcc -E test.cpp > test.p ... int main () { cout << "Value of PI :" << 3.14159 << endl; return 0; }
ماکروهای شبه تابع (Function-Like Macros)
با استفاده از دستور define# میتوان ماکرویی تعریف کرد که از ورودی آرگومان دریافت خواهد کرد.
#include <iostream> using namespace std; #define MIN(a,b) (((a)<(b)) ? a : b) int main () { int i, j; i = 100; j = 30; cout <<"The minimum is " << MIN(i, j) << endl; return 0; }
اگر کد فوق را کامپایل و اجرا کنید، نتیجه زیر تولید خواهد شد.
The minimum is 30
کامپایل شرطی (Conditional Compilation)
دستوراتی وجود دارد که با استفاده از آنها، میتوانید تنها بخشهای خاصی از سورس کد برنامهتان را کامپایل کنید.
ساختار پیشپردازنده شرطی (conditional preprocessor) شبیه ساختار دستور if میباشد. کد پیشپردازنده زیر را درنظر بگیرید.
#ifndef NULL #define NULL 0 #endif
میتوان یک برنامه را با هدف دیباگ کردن کامپایل نمود. میتوان با استفاده از یک دستور ماکرو، عملیات دیباگ را در برنامه فعال یا غیرفعال کرد.
#ifdef DEBUG cerr <<"Variable x = " << x << endl; #endif
در صورتی که پیش از این ماکرو (یعنی ifdef DEBUG#)، ثابت نمادین DEBUG تعریف شده باشد، این ماکرو سبب میشود که دستور cerr در برنامه کامپایل گردد. با استفاده از دستور 0 if# ، میتوان بخشی از برنامه را به صورت زیر کامنت کرد.
#if 0 code prevented from compiling #endif
مثال زیر را ملاحظه کنید.
#include <iostream> using namespace std; #define DEBUG #define MIN(a,b) (((a)<(b)) ? a : b) int main () { int i, j; i = 100; j = 30; #ifdef DEBUG cerr <<"Trace: Inside main function" << endl; #endif #if 0 /* This is commented part */ cout << MKSTR(HELLO C++) << endl; #endif cout <<"The minimum is " << MIN(i, j) << endl; #ifdef DEBUG cerr <<"Trace: Coming out of main function" << endl; #endif return 0; }
با اجرای کد فوق، خروجی زیر حاصل میشود.
The minimum is 30 Trace: Inside main function Trace: Coming out of main function
عملگرهای # و ##
عملگرهای پیشپردازنده # و ## در ++C و ANSI/ISO C موجود هستند. عملگر # سبب میشود تا یک توکن replacement-text به یک رشته محصور در کوتیشن تبدیل شود.
ماکروی زیر را درنظر بگیرید.
#include <iostream> using namespace std; #define MKSTR( x ) #x int main () { cout << MKSTR(HELLO C++) << endl; return 0; }
با کامپایل این کد، نتیجه زیر به دست میآید.
HELLO C++
بیایید نحوه عملکرد این کد را بررسی کنیم. به سادگی میتوان فهمید که پیشپردازنده ++C خط
cout << MKSTR(HELLO C++) << endl;
را به خط زیر تبدیل میکند.
cout << "HELLO C++" << endl;
عملگر ## برای چسباندن دو توکن به هم استفاده میشود. مثال زیر را مشاهده کنید.
#define CONCAT( x, y ) x ## y
هرجای برنامه که CONCAT ظاهر شود، آرگومانهای آن بهم چسبیده و جایگرین ماکرو میشوند. برای مثال، (++CONCAT(HELLO, C با «++HELLO C» جایگزین میشود.
#include <iostream> using namespace std; #define concat(a, b) a ## b int main() { int xy = 100; cout << concat(x, y); return 0; }
اگر کد بالا اجرا شود، نتیجه زیر را خواهیم داشت.
100
اجازه دهید نحوه عملکرد برنامه را بررسی کنیم. به سادگی متوجه میشویم که پیشپردازنده ++C خط
cout << concat(x, y);
را به خط زیر تبدیل میکند.
cout << xy;
ماکروهای از پیش تعریف شده در ++C
++C تعدادی ماکروی از پیش تعریف شده فراهم آورده که در جدول زیر لیست شدهاند.
ردیف |
ماکرو و توضیح آن |
1 |
__LINE__ این ماکرو شماره خطی از برنامه که در حال کامپایل شدن است را در خود نگه میدارد. |
2 |
__FILE__ این ماکرو نام فایلی از برنامه که در حال کامپایل شدن است را در خود نگه میدارد. |
3 |
__DATE__ این ماکرو حاوی رشتهای به فرم month/day/year است که بیانگر تاریخ ترجمه فایل سورس به فایل object میباشد. |
4 |
__TIME__ این ماکرو حاوی رشتهای به فرم hour:minute:second است که بیانگر ساعت کامپایل برنامه میباشد. |
مثالی از همه این ماکروها در زیر آمده است.
#include <iostream> using namespace std; int main () { cout << "Value of __LINE__ : " << __LINE__ << endl; cout << "Value of __FILE__ : " << __FILE__ << endl; cout << "Value of __DATE__ : " << __DATE__ << endl; cout << "Value of __TIME__ : " << __TIME__ << endl; return 0; }
خروجی زیر از کد بالا حاصل شده است.
Value of __LINE__ : 6 Value of __FILE__ : test.cpp Value of __DATE__ : Feb 28 2011 Value of __TIME__ : 18:52:48
منبع: ترجمه از سایت tutorialspoint.com
اگر این نوشته برایتان مفید بود لطفا کامنت بنویسید.
عالی بودش .