زبان برنامه نویسی سی/مقدمهای بر پیش پردازندهها
اگر مطالب پیشین را مطالعه نموده باشید ، میدانید که خارج از هر رشته و یا کاراکتر ؛ اگر از علامت شارپ « # » استفاده نمائید ، شما مجاز و مجبور به استفاده از تنها یک چیز خواهید بود : آن هم دستورات مستقیم پیشپردازندهها ( Preprocessors ) هستند ؛ که در این مورد یک دستور مستقیم را در مقابل علامت شارپ مینویسیم که به کامپایلر دستور صریح برای نحوه خواندن ، ترجمه ، اجرا و ... برنامه را میدهد . اما در ادامه باید بگوئیم که شما در صورت استفاده از دو زیرخط یعنی دو « _ » ، که به صورت « __ » در می آید ، مجاز و مجبور به استفاده از تنها یک چیز خواهید بود : و آن هم ماکروها هستند . پیشپردازندهها دستوراتی هستند که اولویت اجرایی ، بر تمام کدهای متن شما دارند و به شما اجازه می دهند تا بر کامپایل و اجرای برنامه خود ، نظارت و حاکمیت داشته باشید . ماکروهای سراسری نیز واحدهای جاری هستند که مطمئناً در برنامه های خود به آنها احتیاج پیدا خواهید نمود . مثلاً زمان کامپایل برنامه ، زمان فعلی ، اسم فایلی که در حال کامپایل است و ... همگی امکاناتی هستند که ماکروهای سراسری با بازگرداندن مقادیر عددی و/یا حروفی برای شما فراهم میآورند و با دو زیر خط آغاز شده ، سپس حروف معرّف ماکرو و در نهایت دو زیر خط دیگر ، دوباره نوشته میشوند تا در انتهای حروف معرّف ماکرو قرار بگیرند و به یک ماکروی قابل فهم برای کامپایلر در بیایند
یکی از مهم ترین پیشپردازندهها ، دستور مستقیم include میباشد که به صورت include# نوشته میشود . شما در زبان سی ، بدون تابع های کتابخانهای ؛ تنها مجاز به ایجاد دادهها و پردازش های محاسباتی و منطقی بر روی آنها هستید که می تواند به صورت عددی یا حروفی باشد . اما به خودی خود قادر نخواهید بود که با سختافزار و یا سیستمعامل ، ارتباط برقرار کنید تا بتوانید اطلاعاتی را بگیرید و آن را بر اساس برنامه خود ، مورد پردازش قرار دهید و در نهایت آن را به یک خروجی ( مثل یک برنامه جانبی خطدستوری ، مثل ترمینال در خانواده یونیکس یا کامندر در ویندوز ) بفرستید . بنابراین بدون وجود فایلهای سرآیند ، شما باید خود ، تمام پردازشها و دستورات و اطلاعات ورودی/خروجی ها را تعریف کنید ؛ درست مثل اینکه خودتان بخواهید کامپایلر و کرنل و سیستمعامل را به C و اسمبلی بنویسید . از طرفی گاهی پیش میآید که شما در برنامه خود شرط کردهاید که فقط در صورت خاصی ، تابع نوشته شده توسط شما اجرا گردد ؛ اما میخواهید همان قسمت از برنامه خود که مثلاً شامل تعریف یک متغیر میگردد و یا اصلاً یک تابع را شامل می شود در صورت برقراری شرط دیگری اجرا نگردد و به کلّی توسط کامپایلر ، نادیده گرفته شود ( به مثابه اینکه اصلاً آن تابع را ننوشتهاید ) و شما با پیشپردازندههای شرطی که تعیین میکنید ، به کامپایلر دستور میدهید تا در صورت برقراری شرطی ، مقصود شما را برآورده نماید ( آن قسمت از برنامه را نادیده بگیرد )
ماکروها بر دو نوع سراسری و کتابخانهای هستند . ماکروهای سراسری بدون ضمیمه شدن فایل سرآیند ( که با دستور مستقیم include ، توسط شما انجام میپذیرد ) و در داخل خود زبان سی موجود هستند و تعریف شدهاند و میتوانید هر جا که نیاز داشته ، کدهای مورد نیاز را تایپ نموده و از آنها بهره بجوئید . اما ماکروهای کتابخانهای ، تنها در صورتی که فایل سرآیند مربوطه که داخل آن تعریف شدهاند را ضمیمه کرده باشید قابل استفاده میباشند
چند نکته در مورد نوشتن پیشپردازندهها ضروری میباشد . اول اینکه شما مجاز و مجبور به استفاده از هر دستور مسقیم پیشپردازنده ، فقط در یک خط هستید ؛ بنابراین اگر میخواهید چند پیشپردازنده بنویسید ، باید آنها را در چند خط بنویسید و نمیتوانید چند دستور مستقیم پیشپردازنده را داخل یک خط بنویسید . دومین مورد اینکه از استفاده غیر ضروری از پیشپردازندهها بپرهیزید . مثلاً شما میخواهید از چند تابع کتابخانهای استفاده کنید ، اما با خود میگوئید : بگذار تمام فایل های سرآیند را ضمیمه کنم ! و با خیال راحت ، هر آنچه خواستم بنویسم ! این کار ، شما و حتی کامپایلر را گیج خواهد کرد و امکان نوشتن کد خطا در برنامه شما را افزایش میدهد . یا مثلاً شما میخواهید در داخل برنامه خود شروطی را برای توابع ، تعیین کنید ، در این صورت بهتر است از دستورات داخل برنامه کمک بگیرید و نه اینکه آن را با پیشپردازندهها شرطی کنید . این کار شما فقط در صورتی مفهوم خواهد داشت که کاملاً به برنامهنویسی و زبان سی ، مسلّط باشید ؛ چرا که پیشپردازندهها ، عموماً در برنامهنویسی سطح پائین و برای نوشتن ابزارهایی مثل کامپایلر یا برنامه کرنل و میانافزارها Firmwares و یا اجزاء کمکی سیستمعامل ( کامپوننتها Components ) استفاده میشوند . استفاده از آنها تا زمانی که مسلط نشدهاید و قصد نوشتن برنامه سطح پائین را ندارید توصیه نمیشود و ممکن است خطاهایی را ایجاد کنید که هر چه تلاش کنید تا ایراد را برطرف کنید ، نتیجهای حاصل نگردد . حال آنکه شما به خاطر استفاده بیجا ، به برنامه خود آسیب وارد کردهاید . برخی از دستورات مستقیم پیشپردازنده نیز تخصصیتر و پیشرفتهتر میباشند که در ادامه همین فصل همگی آنها را به همراه مثالهایی خواهیم نوشت