موضوع مقاله: پیش‌پردازنده | مخاطب: عمومی | لحن: دانشنامه‌ای | ساختار: عنوان، مقدمه، 3 بخش، جمع‌بندی | مقاله: | # پیش‌پردازنده | مقدمه: در علوم رایانه، پیش‌پردازنده، برنامه‌ای را گویند که با پردازش داده‌های ورودی، دادهٔ خروجی‌ای تولید می‌کند که به عنوان ورودی برنامه دیگری مورد استفاده قرار می‌گیرد. | ## بخش 1: پیش‌پردازنده | خروجی پیش‌پردازنده را اصطلاحاً فرم پیش‌پردازش‌شده داده ورودی، که غالباً به وسیله یک برنامه ثانویه مانند همگردان مورد استفاده قرار می‌گیرد، می‌گویند. پیش‌پردازنده‌ها بسته به طبیعتشان ممکن است فقط پردازش‌های ساده‌ای از قبیل جابه‌جائی متنی یا بسط ماکروئی روی داده ورودی انجام دهند، در عین حال، برخی از پیش‌پردازنده‌ها به اندازه یک زبان برنامه‌نویسی بالغ قدرتمند هستند. یک نمونه رایج از برنامه‌نویسی، پیش‌پردازشی است که در پردازشگرهای متنی همگردان‌ها بر روی کد مبدأ انجام می‌گیرد و خروجی آن به پردازشگر نحوی تحویل می‌شود. در برخی زبان‌های برنامه‌نویسی (همچون C)، پیش‌پردازش یک فاز مستقل از فرایند ترجمه می‌باشد. پیش‌پردازنده‌های لغوی پیش‌پردازنده‌های لغوی، سطح‌پائین‌ترین پیش‌پردازنده‌ها هستند، زیرا فقط به تحلیل لغوی احتیاج دارند، یعنی مستقیماً روی کدمبداء کار می‌کنند. راهنمای پیش‌پردازنده راهنما، دستورالعملی به همگردان زبان در مورد چگونگی همگردانی برنامه می‌باشد. برنامه‌نویس به جای تولید کد، از راهنماها برای تعیین چگونگی یا حتی به وقوع پیوستن همگردانی کد مبدأ بهره می‌جوید. راهنماها در بسیاری از زبان‌های برنامه‌نویسی نسبتاً سطح پائین، چون C/C++ و اسمبلی مورد استفاده قرار می‌گیرند. در C/C++ از راهنماها به جهت مقاصدی از قبیل همگردانی شرطی، ماکروها و شمول مورد استفاده قرارمی‌گیرند. باید توجه داشت که راهنماهای پیش‌پردازنده، به مانند دستورهایی هستند که به پیش‌پردازنده داده می‌شوند و بنابراین از قواعد زبان پیروی نمی‌کنند؛ یعنی این راهنماها قواعد املائی و نحوی خاص خود را دارند. پیش‌پردازنده C/C++ رایج‌ترین پیش‌پردازنده، پیش‌پردازنده C می‌باشد، که به صورت فراگیری در C و فرزند آن C++، استفاده می‌شود. از این پیش‌پردازنده به منظور استفاده از خدمات معمول پیش‌پردازنده‌ای استفاده می‌شود. این پیش‌پردازنده قادر به انجام اعمال اولیه‌ای از قبیل همگردانی شرطی، جا دادن فایل در کد منبع، تعیین پیغام خطاهای زمان همگردانی و اعمال قواعد مخصوص ماشین مقصد به بخش‌های کد نهائی می‌باشد. راهنماهای موجود در کد منبع به پیش‌پردازنده دستور می‌دهند تا کار عمل را روی کد منبع انجام دهد. به عنوان مثال، پیش‌پردازنده با دریافت این دستورها می‌تواند در قسمت‌های مختلف کد منبع عمل جایگذاری را نجام دهد، محتویات فایل دیگری را به کد منبع اضافه کند، یا با حذف کردن بخشی از کد منبع، مانع از همگردانی آن شود. خطوط راهنمای پیش پردازنده پیش از بسط ماکروها شناسائی و اجرا می‌شوند، بنابراین اگر بسط یک ماکرو منجر به تولید چیزی شبیه به یک راهنمای پیش‌پردازنده شود، دستور تولیدی توسط پیش‌پردازنده شناسائی نمی‌شود. خطوط دستورات پیش‌پردازنده می‌توانند با استفاده از علامت \ ادامه پیدا کنند (ادامه دستور در خط بعدی نوشته شود). | ## بخش 2: پیش‌پردازنده | دستورات پیش‌پردازنده C/C++ می‌توانند در هر مکان دلخواه از کد منبع آورده شوند، ولی برد اثر این دستورات هموراه از نقطه به‌کارگیری به بعد می‌باشد. راهنمای پیش‌پردازنده شمول، به همگردان می‌گوید که با فایل مشخص شده به‌گونه‌ای رفتارکند که گوئی محتویات آن در کد مبدأ و در نقطه‌ای که این راهنمای پیش‌پردازنده آمده‌است، قرار دارد. قسمت path-spec در نمونه فوق، نام فایلی است که می‌تواند مشخصات مسیر آن فایل را نیز به صورت اختیاری به همراه داشته باشد. هر دو نوع نحو این راهنما باعث جایگذاری محتویات فایل مشخص شده به جای راهنمای پیش‌پردازنده می‌شود. تفاوت این دو نحو، تنها زمانی است که مسیر فایل سرآیند به‌طور صریح مشخص نشده باشد. این تفاوت در ترتیب جستجو برای یافتن فایل سرآیند توسط پیش پردازنده می‌باشد و در جدول زیر مشخص شده‌است. نوع نحو عمل‌کرد نوع "" این نوع به پیش‌پردازنده دستور می‌دهد تا ابتدا در دیرکتوری فایلی که راهنمای شمول در آن قرار دارد و پس از آن در دایکتوری‌های همه فایل‌هائی که همین فایل سرآیند (فایلی با همین نام و مشخصات) را با استفاده از راهنمای #include شامل شده‌اند، به دنبال فایل شامل شده بگردد. پس از آن پیش‌پردازنده در شاخه‌هائی که به واسطه گزینه -Iبه همگردان‌گر داده شده‌اند به دنبال فایل سرایند می‌گردد. نوع <> این نوع به پیش‌پردازنده دستور می‌دهد تا ابتدا در دیرکتوری‌های مشخص شده با گزینه -I و پس از آن در دیرکتوری‌های مشخص شده در متغیر محیطی INCLUDE به دنبال فایل سرآیند بگردد. پیش‌پردازنده تعریف، #define با استفاده از این راهنما می‌توان نامی را به یک ثابت در برنامه اختصاص داد. نوع دوم نحو این دستور امکان نوشتن ماکروهائی را در اختیار برنامه‌نویس قرار می‌دهد که دارای آرگمان‌هائی چون آرگمان‌های تابع باشند. این نوع املاء، لیستی از پارامترهای دلخواه، که باید در داخل پرانتز باشند، را به عنوان آرگومان می‌پذیرد. تعریف چندباره یک ماکرو منجر به بروز خطا می‌شود، مگر آن‌که همه تعاریف کاملاً یکسان باشند. همچنین دستور do-while دستوری است که نیازمند یک؛ در انتهای دستور است و بنابراین کاربر ماکرو با قرار دادن؛ در انتهای فراخوانی ماکرو متوجه تفاوت آن با تابع معمولی نمی‌شود. برای ضد تعریف کردن یک ماکرو که قبلاً تعریف شده‌است، نیازی به نوشتن پارامترها نیست و نوشتن نام ماکرو کفایت می‌کند. به عنوان مثال ممکن است تابعی با توجه به شاخصه‌های محیطی یک ثابت تعریف کند که در سایر بخش‌های کد تأثیری نداشته باشد. در مثال زیر، راهنمای پیش‌پردازنده #undef تعریف یک ثابت و یک ماکرو را بی‌اثر می‌کند. | ## بخش 3: پیش‌پردازنده | به عنوان مثال دستور زیر فقط تعریف B را بی‌اثر می‌کند و تأثیری در تعریف شاخص A ندارد. این کار با حذف یا عدم حذف قسمتی از کد که توسط این راهنماها محدود شده‌است انجام می‌پذیرد. اگر عبارتی که در #if یا #elif می‌آید غیر صفر باشد، قسمت بعد از آن‌ها تا راهنمای شرطی بعدی حذف نمی‌شود. در صورت یافتن مورد غیر صفر، کلیه بلوک شرطی به جز قسمتی که محدود به راهنمای شرطی فعلی و راهنمای شرطی باشد حذف می‌شود. در صورتی که هیچ مورد غیر صفری یافت نشود و راهنمای شرطی #else در بلوک وجود داشته باشد، تمام بلوک به جز قسمت محدود به #else و عبارت شرطی بعدی، حذف می‌شود. عبارت ثابتی که در مقابل #if و #elif قرار می‌گیرد باید دارای شرائط زیر باشد: باید عبارت از نوع صحیح باشد، یعنی فقط ثوابت عدد صحیح، ثوابت نویسه‌ای و عملگر defined می‌توانند در مقابل این راهنماها قراربگیرند. از کاربردهای رایج پیش‌پردازنده‌های شرطی، جلوگیری از شمول چندباره یک فایل سرآیند می‌باشد. در محیط‌های C++ که معمولاً تعریف کلاس‌ها در فایل‌های سرایند جداگانه نگهداری می‌شوند، می‌توان با استفاده از ساخت‌هائی مشابه مثال زیر، از تعریف چندباره کلاس جلوگیری نمود. یک رشته از توکن‌ها در مقابل این راهنما قرار می‌گیرد که عیناً به عنوان پیغام خطا توسط همگردان بازگردانده می‌شود و عمل بسط ماکرو در آن صورت نمی‌گیرد. راهنمای تغییر خط و فایل، #line این راهنما باعث تغییر نام فایل و شماره خط فعلی، ذخیره شده به صورت داخلی، در همگردان می‌شود. غالباً شماره خط به خط فعلی که در حال همگردان‌شدن می‌باشد اشاره می‌کند و با پردازش هر خط یک واحد افزایش می‌یابد، همچنین نام فایل به فایلی که در حال پردازش همگردان است اشاره می‌کند. همچنین می‌توان در این‌جا از بسط ماکروها، به شرطی که نتیجه حاصله املای درستی داشته باشد، استفاده‌کرد. مترجم، با استفاده از مقادیر داخلی نام فایل و شماره خط، مقدار ماکروهای از پیش تعریف شده __FILE__ و __LINE__ را تعیین می‌کند. با استفاده از این ماکروهای از پیش تعریف شده می‌توان پیام‌های خطای مشروحتری تولید کرد. راهنمای #pragma هر پیاده‌سازی از C/C++، ویژگی‌های منحصر به فرد مخصوص به ماشین میزبان یا سیستم‌عامل خود دارد. راهنمای پیش‌پردازنده #pragma به هر همگردان این امکان را می‌دهد تا ویژگی‌های منحصر به فرد خود را در کنار حفظ سازگاری با تعریف استاندارد C/C++، پیاده‌سازی کند. | ## جمع‌بندی | #pragma معمولاً مخصوص به ماشین و سیستم‌عامل مشخص است و غالباً در هر همگردان متفاوت می‌باشد.