گشتاسب مظفریان – GMozafarian

مشاور و توسعه دهنده نرم افزار -Adviser and Software Developer

پیش پردازنده ها در زبان C و ++C

پیش پردازنده ها در زبان C

به نام اهورامزدای پاک

پیش پردازنده یا preprocessor

پیش پردازنده دستور خاصی است که دستورات یک زبان را به دستورات قابل درکی برای مفسر تبدیل می کند. در زبان برنامه نویسی C , ++C و با تعریف پیش پردازنده ها که از لحاظ مفهومی مرحله نخست تفسیر برنامه هستند, امکانات فراوانی در اختیار برنامه نویسان قرار می گیرد. ورودی پیش پردازنده برنامه ای با دستورات توسعه یافته و خروجی آن برنامه ای است که CPU قادر به پردازش و اجرای آن است. include# و define# به عنوان دو پیش پردازنده مهم و پر کاربرد زبان C/C++ محسوب می شوند. همچنین تفسیر شرطی و ماکروها نیز از دیگر پیش پردازنده های این زبان ها هستند. پیش پردازنده ها در استاندارد ANSI عبارتند از:

if#

ifdef#

ifndef#

else#

elif#

include#

define#

ubdef#

line#

error#

pragma#

همانطور که ملاحظه میکنید, تمام این پیش پردازنده ها با علامت # شروع شده اند و هر یک از آنها باید در یک خط و بطور جداگانه نوشته شوند.

پیش پردازنده define#

از پیش پردازنده define# برای تعریف یک ماکرو یا انجام تعاریف جدید به جای مقادیر استاندارد و از پیش تعیین شده در مفسر استفاده می شود. در واقع ماکرو رشته ای است که می تواند شامل حرف , عدد, مقادیر ثابت, توابع و …. باشد.

مدل کلی بکار گیری این پیش پردازنده به صورت زیر است:

 #define macro_name string 

 برخلاف دیگر دستورات زبان C که انتهای آنها با علامت نقطه ویرگول مشخص می شود, پیش پردازنده ها بدون این کاراکتر نوشته می شوند.

در حد فاصل نام ماکرو و آرگومان String یک یا چند فاصله وجود دارد که از آنها برای جدا کردن این دو آرگومان استفاده می شود. برای مثال اگر بخواهیم از کلمه TRUE به جای مقدار عددی ۱ و از کلمه FALSE به جای مقدار عددی ۰ استفاده کنید, باید به صورت زیر عمل کنید:

 #define TRUE 1 #define FALSE 0 

 تعاریف فوق در برنامه باعث می شود تا مفسر کلمات FALSE و TRUE را به جای مقادیر عددی یک و صفر مورد استفاده قرار دهد. با تعاریف ماکروهای قبل , خروجی خط زیر به شکل ۰,۱,۲ می شود.

 std::cout << FALSE << " " << TRUE << " " << TRUE+1; 

 از ماکروهای تعریف شده می توان در تعریف ماکروهای بعدی نیز استفاده کرد. برای مثال در تعاریف زیر ماکروهای two , one و three برابر معادلهای عددی شان تعریف شده اند. در این مثال برای تعریف ماکروهای دوم و سوم از ماکروهای قبلی آن استفاده شده است:

 #define one 1 #define two one+1 #define three two+one 

 در تعریف ماکرو میتوان با استفاده از آرایه ای از کاراکترها, پیغام خاصی را تعریف کنید:

 #define MSG "Error in input\n" std::cout << MSG; 

در این مثال می توان به جای تعریف ماکرو فقط به نوشتن جمله زیر اکتفا کرد:

 std::cout << "Error in input\n"; 

 در دستور فوق مفسر مقدار Error in input\n را به ماکروی MSG نسبت می دهد. توجه داشته باشید که در صورت برداشتن علامت ” از طرفین رشته کاراکتری هیچ مقداردهی , اتجام نمی شود.

هرگاه مقدار رشته کاراکتری ماکرو بیش از یک خط باشد, میتوان با استفاده از کاراکتر \ آن را در خط بعد ادامه داد:

 #define L_String "Hello this is a ling string fot \ backslash usage" 

 در هنگام تعریف ماکروها و برای مشخص شدن آنها بهتر است از حروف بزرگ استفاده کنید. همچنین بهتر است این تعریف در ابتدای فایل برنامه و از طریق دستور define# انجام شود. در غیر این صورت در تعریف شناسه های دیگر که ماکروهای تعریف شده در آن دخالت دارند با مشکل مواجه می شوید.

داشتن آرگومان از جمله ویژگی های ماکروها است. هر زمان که ماکروی مورد نظر فراخوانی شود, مقدار آرگومانهای آن به جای ماکرو جایگزین شده و در واقع میتوان به عنوان یک تابع عمل کند. برای مثال برنامه کوچک زیر تابع ()abs را تعریف میکند:

 #include <iotream> #define abs(a) (a) < 0 ? -(a) : (a) main() { std::cout<<"abs of -1 and 1: " << abs(-1) << " " << abs(1); } 

 وجود پرانتزها در مثال فوق ضروری است و در صورتی که پرانتزهای بکار رفته در ماکرو را حذف کرده و تابع ()abs را به صورت (۱۰,۲۰)abs بکار ببرید, ماکروی مزبور به صورت زیر تبدیل خواهد شد:

 ۱۰-۲۰ : ۱۰-۲۰- ? ۰ > 10-20 

همانطور که ملاحظه می کنید نتیجه حاصل با حذف پرانتز در ماکروی ()abs اشتباه محاسبه می شود.

همچنین می توان آرگومانهایی را در تعریف ماکروها مورد استفاده قرار داد به نحوی که متن جایگزین در فراخوانی های مختلف ماکرو به شکل متفاوتی عمل کند. به عنوان مثال در ماکروی زیر که به نام max تعریف شده است:

 #define max(A,B) ( (A) > (B) ? (A) : (B) ) 

 هر چند عملکرد این ماکرو همانند فراخوانی یک تابع است, اما استفاده از ماکرو مزبور در کدنویسی به شکل حرفه ای باعث توسعه برنامه نویسی می شود. هر رویداد از یک پارامتر قراردادی ( در اینجا A و B) با آرگومان واقعی متناظر آن جایگزین میشود. از این رو دستور:

 x = max (p+q, r+s); 

 با دستور زیر جایگزین می شود:

 x = ( (p+q) > (r+s) ? (p+q) : (r+s) ); 

 تا زمانی که آرگومانها به صورت سازگار و همسان عمل میکنند, این ماکرو را میتوان برای هر نوع داده ای بکار گرفت.

اگر چه بکارگیری نامناسب ماکروها و عدم دقت در تعریف صحیح آنها ممکن است نتایج غیر قابل پیش بینی در برنامه شما ایجاد کند, اما با توجه به ارزش بالای آنها, استفاده از ماکروها همچنان مورد توجه قرار دارند. به عنوان مثال توابع ()getchar و ()putcher که در فایل اصلی <stdio.h> قرار دارند, برای جلوگیری از سربار شدن زمان اجرای بارگذاری توابع در فراخوانی هر کاراکتر, اغلب به صورت ماکرو تعریف می شوند.

نکته: با توجه به آنکه در یک ماکرو زمانی برای ذخیره آدرس تابع در حافظه Stack به همراه دیگر متغیر ها صرف نمیشود, سرعت ماکروها نسبت به توابع بیشتر است. اما این عمل باعث ازدیاد حجم برنامه خواهد شد, زیرا کدهای ماکرو در تمام نقاط استفاده شده در برنامه در فایل exe کپی میشود. اما هنگام استفاده از یک تابع , کدهای آن یکبار در فایل نگهداری شده و در زمان نیاز تنها به آدرس آن رجوع خواهد شد.

پیش پردازنده include#

از این پیش پردازنده برای ضمیمه مردن یک فایل در برنامه استفاده می شود. فایل مورد نظر کی تواند حاوی اطلاعاتی نظیر تعریف تابع , ماکرو یا دیگر مقادیر ثابت و متغیر باشد. توجه داشته باشید که نام فایل مورد نظر در این پیش پردازنده حتماً باید در بین دو علامت ” یا علائم <> قرار گیرد.

اگر نام فایل در هنگام فراخوانی در بین یک جفت کاراکتر ” قرار داده شود, مفسر آن را در همان دایرکتوری فایلهای برنامه جستجو خواهد کرد. از این شیوه بیشتر برای ضمیمه کردن فایلهایی استفاده می شود که توسط برنامه نویسان نوشته می شود. مفسرها در صورت عدم یافتن فایل در این محل, آن را در محدوده تعیین شده در زمان نصب مفسر جستجو میکنند.

در صورتی که قصد ضمیمه کردن فایلهایی را داشته باشید که در هنگام نصب مفسر بر روی سیستم شما نصب شده اند باید از علائم <> استفاده کنید. در این حالت مفسر این فایلها را در پوشه محل نصب برنامه مفسر جستجو میکند. به عبارت دیگر برای ضمیمه فایلی با نام stdio.h که در دایرکتوری جاری و در کنار فایل اصلی برنامه قرار دارد, از دستور include “stdio.h”# و برای ضمیمه کردن فایلی با نام iostream که در محدوده تعیین شده در هنگام نصب مفسر قرار دارد, از دستور include <iostream># استفاده می شود. در نتیجه در هنگام تفسیر برنامه به ازای هر دستور include “file name”# یا include <file name># محتوای آنها در برنامه فراخوانی و جایگزین می شود.

زبان C امکان تفسیر چندین فایل را با یکدیگر می دهد, اما به یاد داشته باشید که هیچ یک از فایلهای برنامه نباید حجم بیشتر از ده هزار بایت داشته باشد. البته در برخی از مفسر ها این محدودیت کاهش یافته و میزان حجم فایل میتواند تا پانزده هزار بایت باشد. در زبان ++C این محدودیت تنها به سخت افزار وابسته بوده و فایلهایی با حجم بسیار بزرگ نیز قابل تفسیر هستند.

پیش پردازنده error#

این پیش پردازنده مانع ادامه ترجمه و تفسیر یک برنامه به کد قابل اجرا خواهد شد.

مدل کلی بکارگیری این پیش پردازنده به صورت زیر است:

 #error ERROR_MSG 

 آرگومان ERROR_MSG در این پیش پردازنده محصور در علامت گیومه نیست و پیغام خروجی میتواند شامل مجموعه ای از پیغامهای مورد نظر برنامه نویس باشد.

در برنامه زیر کاربرد این پیش پردازنده نشان داده شده است:

 #include &amp;amp;lt;iostream&amp;amp;gt; #include &amp;amp;lt;conio.h&amp;amp;gt; int main() { int arr[4] , I; for(i=0;i&amp;amp;lt;100;i++) { if(i&amp;amp;gt;4) #error enter less than 20 else std::sin&amp;amp;gt;&amp;amp;gt; &amp;amp;amp;arr[i]; } getch(); return 0; } 
 پیش پردازنده های  endif , #elif , #else# و if#

هر برنامه نویس میتواند با استفاده از عبارات شرطی که در طول پیش پردازش محاسبه و ارزیابی می شوند, پیش پردازش را کنترل کند. در نتیجه می توان با توجه به مقدار محاسبه شده در طول تفسیر برنامه , کدهای مورد نظر را به صورت انتخابی در برنامه وارد کرد. از پیش پردازنده های endif , #elif  #else# و if# برای طراحی و توسعه یک نرم افزار در نسخه های متفاوت استفاده می شود. دستور if# یک عبارت ثابت صحیح را محاسبه می کند. هرگاه شرط if# به صورت TRUE باشد, یا به عبارت دیگر اگر مقدار حاصل از این شرط غیرصفر باشد, خطوط بعدی برنامه تا زمانی که با یکی از دستورات elif , #endif# (این دستور مشابه دستور else if است) یا else# مواجه شود, به برنامه وارد شده و کد مابین دو دستور if# و endif# تفسیر می شود, در غیر این صورت از تفسیر کدهای حد فاصل این دو دستور صرف نظر خواهد شد. مدل کلی بکارگیری این دو دستعور به صورت زیر است:

 #if constant expression code zone #endif 

در مثال زیر یکی از کاربردهای این ماکروها را ملاحظه می کنید:

 #include&amp;amp;lt;iostream&amp;amp;gt; #define MAX 100 main() { #if MAX &amp;amp;gt; 99 std::cout &amp;amp;lt;&amp;amp;lt; &amp;amp;quot;Compiled for array grater than 99\n&amp;amp;quot;; #endif } 

در مثال فوق از آنجا که ماکروی MAX بزرگتراز ۹۹ در نظر گرفته شده است, بنابراین متن آرگومان Cout نمایش داده خواهد شد. مقدار شرط این برنامه تنها در زمان تفسیر آن بررسی می شود, بنابراین تنها باید آخرین مقداردهی را آزمایش کرد, یا اینکه از مقادیر ثابت به جای مقادیر متغیر استفاده کرد.

پیش پردازنده else# دقیقاً  مانند قسمت else در دستور if عمل می کند و هرگاه پیش پردازنده if# به مقدار FALSE برخورد کند, قسمت else# اجرا می شود. به این ترتیب می توان مثال قبلی را به صورت زیر نیز نوشت:

 #include &amp;amp;lt;iostream&amp;amp;gt; #define MAX 100 main() { #if MAX &amp;amp;gt; 99 std::cout &amp;amp;lt;&amp;amp;lt; &amp;amp;quot;Compiled for array grater than 99\n&amp;amp;quot;; #else std::cout &amp;amp;lt;&amp;amp;lt; &amp;amp;quot;Compiled for array less than 99\n&amp;amp;quot;; } 

 پیش پردازنده else# در مثال فوق نه تنها شروع بلوک جدید است, بلکه مانند endif# در قمست if# عمل می کند. لازم به ذکر است که این برنامه در برخی از مفسرها مانند کامپایلر Turbo C ver.2.0 حتماً به ماکروی endif# نیاز دارد.

 پیش پردازنده elif# دقیقاً معنای دستور else if را می دهد و در مفسرها برای بررسی چند حالت شرطی متفاوت بکار می رود.

مدل کلی بکارگیری این دستور به صورت زیر است:

 #if expression1 statement sequence #if expression2 statement sequence #if expression3 . . . . . . . . #if expression n statement sequence #endif 

 توجه داشته باشید که پیش پردازنده if# حتماً باید در ابتدا نوشته شود, تا امکان بررسی دیگر حالت ها نیز وجود داشته باشد. پیش پردازنده elif# یکی از ملحقات if# بوده و به تنهایی قابل استفاده نیست. البته if# و elif# می توانند در داخل یکدیگر نیز نوشته شوند, اما در این حال حتماً باید یک endif# مجزا نیز داشته باشند:

 #if MAX &amp;amp;gt; 100 #if SERIAL_VERSION int port=198; #elif int port=200; #endif #else char out_buffer[100]; #endif 

 به عنوان مثال برای اطمینان از اینکه محتوای فایل hdr.h تنها یکبار در برنامه فراخوانی شود, میتوان به صورت زیر فراخوانی فایل را در یک پیش پردازنده شرطی قرار دارد:

 #if !defined(HDR) #define HDR /* contents of hdr.h go here */ #endif 

 پیش پردازنده اول در این دستورات نام HDR را تعریف می کند. سپس پیش پردازنده های بعدی نام تعریف شده را یافته و به پایین endif# می رود. همچنین برای اجتناب از وارد شدن چندین فایل نیز می توان از این روش استفاده کرد. در صورتی که این شیوه به درستی بکار گرفته شود هر فایل اصلی می تواند بدون آنکه کاربر فایل اصلی نیازی به تعیین شیوه وابستگی آنها داشته باشد, فایل های وابسته اصلی دیگر را در برنامه وارد کند.

دستورات زیر نام SYSTEM را بررسی می کنند تا دریابند که کدام نسخه از فایل اصلی را باید در برنامه شامل کنند:

 #if SYSTEM == SYSV #define HDR &amp;amp;quot;sysv.h&amp;amp;quot; #elif SYSTEM == BSD #define HDR &amp;amp;quot;bsd.h&amp;amp;quot; #elif SYSTEM == MSDOS #define HDR &amp;amp;quot;,sdos.h&amp;amp;quot; #else #define HDR &amp;amp;quot;default.h&amp;amp;quot; #endif #include HDR 

 خطوط ifdef# و ifndef# نیز فرمهای مشخص شده ای هستند که وضعیت تعریف یک نام را مورد بررسی قرار می دهند. مثل اول if# را میتوان به شکل زیر نیز نوشت:

 #ifndef HDR #define HDR /* constents of hdr.h go here */ #endif 
پیش پردازنده های indef# و ifdef#

دو دستور indef# و ifdef# مانند پیش پردازنده if# بکار می روند و در نهایت نیز با دستور endif# خاتمه می یابند. پیش پردازنده ifdef# به معنای if define و پیش پردازنده ifndef# به معنای if not define است.

مدل کلی بکارگیری این دستورات به صورت زیر است:

حالت اول:

 #ifdef macro_name statement sequence #endif 

حالت دوم:

 #ifndef macro_name statement sequence #endif 

اگر آرگومان macro_name در مثالهای فوق به صورت ماکرو تعریف شده باشد, بلوک مورد نظر تفسیر می شود, در غیر این صورت از تفسیر بلوک مورد نظر که مقدار FALSE دارد صرف نشر خواهد شد.

توجه داشته باشید که ifdef# و ifndef# میتوانند با define# و else# نیز ترکیب شوند, ولی ترکیب elif# با آنها مجاز نیست.

در مثال زیر یک نمونه از کاربرد این دستور نشان داده شده است:

 #ifdef MAX #define MAX 900 #else std::cout &amp;amp;lt;&amp;amp;lt; &amp;amp;quot;MAX is: &amp;amp;quot;&amp;amp;lt;&amp;amp;lt; MAX; #endif 
پیش پردازنده undef#

پیش پردازنده undef# برای حذف ماکروهای تعریف شده با استفاده از دستور define# بکار می رود.

برای مثال عبارت زیر را در نظر بگیرید:

 #define LEN 100 

در این صورت برای حذف ماکروی تعریف شده با دستور ماکروی LEN را به صورت زیر در برنامه مورد استفاده قرار داد.

 #unef LEN 

به عبارت دیگر در صورتی که بخواهید تنها در محدوده مشخصی از برنامه از ماکرو استفاده کنید, می توانید با بکارگیری از این پیش پردازنده آن را در مفسر حذف کنید.

پیش پردازنده line#

از دستور line# برای مقداردهی ماکروی __LINE__ در مفسر استفاده میشود و میتواند به صورت اختیاری محتوای ماکروی __FILE__ را نیز تغییر دهد.

مدل کلی بکارگیری پیش پردازنده line# به صورت زیر است:

 #line number &amp;amp;quot;filename&amp;amp;quot; 

در این پیش پردازنده آرگومان number یک عدد صحیح مثبت است و مقدار جدیدی به ماکروی __LINE__ خواهد داد و همچنین آرگومان filename نام یک فایل است که جایگزین ماکروی __FILE__ در مفسر می شود. این آرگومان معرف نام فایلی است که در زمان استفاده از ماکرو مورد نظر ترجمه می شود. خروجی برنامه زیر عدد ۱۰۲ است:

 #include &amp;amp;lt;iostream&amp;amp;gt; #Line 100 main() { std::cout &amp;amp;lt;&amp;amp;lt; __LINE__; } 
پیش پردازنده pragma#

از پیش پردازنده pragma# برای بکار بردن یک سری تعارف از قبل تعیین شده در مفسر مانند دنبال کردن رویه یک برنامه استفاده می شود. البته این پیش پردازنده در مفسرهای مختلف به صورت متفاوت است. به عنوان مثال در مفسر Turbo C سه نوع Pragma وجود دارد:

 #pragma inline #pragma warn(+/-) #pragma saveregs 

در این مفسر, pragma inline# مانند آرگومان B- عمل می کند و باعث ایجاد لیست اسمبلری برنامه می شود. در هنگام بکار بردن عبارت asm در یک برنامه , مفسر به صورت اتوماتیک این حالت را فعال می کند.

کلیه مفسرهای C که دارای دستور Pragma هستند, در صورت برخورد به یک Pragma جدید که از نظر آن مفسر ناشناخته باشد, از آن صرفنظر می کنند.

پیش پردازنده های ## و #

استاندارد ANSI دو پیش پردازنده برای ترکیب با define# دارد. در این استاندارد پیش پردازنده # آرگومانهای ماکروی تعریف شده توسط define# را به صورت اتوماتیک در علامت گیومه محصور میکند. جهت درک بیشتر مطلب به مثال زیر توجه کنید:

 #include &amp;amp;lt;iostream&amp;amp;gt; #define mkstr(s) # s void main() { std::cout &amp;amp;lt;&amp;amp;lt; mkstr(this is a string); } 

 در برنامه فوق خطی که شامل دستور cout است به شکل زیر تبدیل می شود:

 std::cout &amp;amp;lt;&amp;amp;lt; &amp;amp;quot;this is a string&amp;amp;quot;; 

از پیش پردازنده ## نیز برای اتصال دو آرگومان استفاده می شود:

 #include &amp;amp;lt;iostream&amp;amp;gt; #define concat(a,b) a ## b void main() { int x,y = 10; std::cout &amp;amp;lt;&amp;amp;lt; concat(x,y); } 

 در برنامه فوق خطی که در آن cout وجود دارد به صورت زیر تبدیل می شود:

 std::cout &amp;amp;lt;&amp;amp;lt; x &amp;amp;lt;&amp;amp;lt; &amp;amp;quot; &amp;amp;quot; &amp;amp;lt;&amp;amp;lt; y; 

البته این دستور کاربرد زیادی ندارد و برای موارد خاص, در مفسر طراحی و در نظر گرفته شده است.

پ.ن: اگر مطالبی دارید که فکر میکنید باید اضافه بشه میتونید اونو به آدرس GMozafarian@gmail.com ارسال کنید .

منابع :

 

  1. The Revised syntax from The Caml language website
  2. Show how to use C-preprocessor on JavaScript files. “JavaScript is Not Industrial Strength” by T. Snyder.
  3. Show how to use C-preprocessor as template engine. “Using a C preprocessor as an HTML authoring tool” by J. Korpela, 2000.
  4. http://randomdeterminism.wordpress.com/2012/06/01/how-i-stopped-worring-and-started-using-markdown-like-tex/
  5. List of predefined ANSI C and Microsoft C++ implementation macros.
  6. Wirzenius, Lars. C “Preprocessor Trick For Implementing Similar Data Types”. Retrieved January 9, 2011
  7. Meyers, Randy (May 2001). “The New C: X Macros”. Dr. Dobb’s Journal. Retrieved 1 May 2008.
  8. Beal, Stephan (August 2004). “Supermacros”. Retrieved 27 October 2008.
  9. GCC Obsolete features
  10. http://gcc.gnu.org/onlinedocs/cpp/Wrapper-Headers.html
  11. “۱٫۳ Preprocessing and conditional compilation”. gnu.org.
  12. Using the fpp Preprocessor”. Intel. Retrieved 14 October 2015
  13. en.cppreference.com/w/cpp/preprocessor
  14. www.cplusplus.com/doc/tutorial/preprocessor/
  15. https://gcc.gnu.org/onlinedocs/cpp/Macros.html
  16. www.cprogramming.com/tutorial/cpreprocessor.html

 

پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C پیش پردازنده ها در زبان C 

پست های مرتبط

لینک کوتاه: http://GMozafarian.ir/rE0Qo
++1411C++‎‎‎‎C++11C++14defineendifififdefifndefincludelinepragmaآموزشآموزش #lineآموزش define#آموزش endif#آموزش ifdef#آموزش ifndef#آموزش include#آموزش pragma#آموزش پیش پردازندهآموزش پیش پردازنده های Cبرنامه نویسیپردازندهپیشپیش پردازندهپیش پردازنده های Cجدیددانلوددانلود کتاب C++14دانلود کتاب آموزش C++فصلکتابکتاب C++کتاب آموزشکتاب آموزش برنامه نویسیکتاب برنامه نویسیکتاب زبان

گشتاسب مظفریان گشتاسب مظفریان • فروردین ۳, ۱۳۹۵


پست‌های قبلی

پست‌های بعدی

پاسخ دهید

Your email address will not be published / Required fields are marked *