زبان برنامه نویسی سی/آشنایی با نوشتن و کار با تابع
پیش از آغاز بحث تابع ، لازم است تا پیشنیازهایی را با هم مرور کنیم . زبان C همان طور که پیشتر نیز گفته شد توسط دنیس ریچی در آزمایشگاه بل برای نوشتن بیشتر قسمتهای سیستمعاملی که بعدهایونیکس Unix نام گرفت ، طراحی شد و باقیمانده کدها نیز برای کرنل Kernel آن به زبان اسمبلی Assembly به کار گرفته شدند . دیری نپائید که هم زبان C و هم سیستمعامل نوشته شده توسط دنیس ریچی و همکارانش با استقبال بیسابقه و بسیار زیادی توسط Sun ، IBM ، Apple و ... مواجه گشت و این استقبال روزافزون بود تا جایی که هنوز هم بعد از گذشت چندین دهه ، این زبان مورد استفاده بیشتر برنامهنویسان حرفهای و مهندسین الکترونیک قرار میگیرد . علت نامگذاری Unix نیز همین مطلب میباشد که یکپارچه و تحت استاندارد واحد می باشد ( بر خلاف سیستم عامل کن تامپسن به نام مالتیکس Multics ) یکی از آن استانداردها محیط پنجرهای ایکس X است و Unix به معنی United X میباشد که تمام شرکتها و جامعههای برنامهنویسی مثل Linux از آن تبعیت میکردند ؛ اما زمان زیادی نگذشت که هر کدام ، هر طور که مایل بودند استانداردها را رعایت میکردند برای همین امروزه به این سیستمعاملها Unix-like یا شبهیونیکس گفته میشود
یک مدار الکتریکی ، یک ورودی برای ورود جریان الکتریکی به داخل مدار دارد و یک خروجی برای خارج شدن جریان الکتریکی از آن ( سرهای مثبت و منفی مدار ) ؛ در این بین نیز از جریان الکتریکی برای روشن کردن لامپ و یا گرم کردن یک المنت ( مثل هیتر Heater ) و ... استفاده میشود . اما در یک مدار الکترونیکی با ورود جریان الکتریکی به مدار با استفاده از از قطعات الکترونیکی مثل ترانزیستورها ، مقاومتها ، دیودها و مخصوصاً مدارهای مجتمع ( IC ها ) در کنار خازنها و قطعات دیگر برای تغییر جریان ورودی که معمولاً تغییرات برای پردازش هستند ، پیش از خروج جریان الکتریکی از مدار ، جریان تغییر یافته ( پردازش شده ) به خروجی دیگری نظیر یک نمایشگر مثل تلویزیون یا مانیتور ، استفاده میشود ( که در دستگاههای الکترونیکی Device ها به این تغییرات ، همان طور که گفته شد ، پردازش گفته میشود که همانند برنامهنویسی میباشد و البته همان طور که در ادامه نیز خواهیم نوشت ، در هر سیستم - مثل دستگاه پخش دیسکهای بلوری و یا تلویزیونهای هوشمند - چه رایانهای باشد و یا نه ؛ بخش عمدهای از پردازشها در Device توسط برنامهنویسی به سطح پائین - توسط زبانی مثل C در کنار زبان ماشین مثل اسمبلی - انجام میشود و با ارائه آن از طریق جریان به داخل IC ها و Chipset ها و ... بر روی دستگاه ثبت و ضبط میشود ، چه بر روی حافظههای دائمی مثل HDD و SSD در رایانه و چه حافظههای دیگر مثل MOS ها و ROM ها و ... که در تمام دستگاههای الکترونیکی موجود هستند ) . در یک سیستم رایانهای ، مجموعهای از دستگاههای الکترونیکی در کنار هم ، یک مجموعه منظم یا سیستم را تشکیل میدهند . در یک کامپیوتر وجود Motherboard مادربرد ( تخته مادر ) CPU ( سیپییو - واحد پردازش مرکزی ) ، حافظه موقت - که البته دسترسی تصادفی نیز دارد - (RAM) ، حافظه دائمی (H.D.D یا S.S.D) و منبع برق ( Power Supplier ) ضروری است ولی شما میتوانید از جعبه رایانه Case برای محافظت رایانه ، سیستمهای تهویه Fan ها و سیستمهای خنک کننده Cooling Systems مختلف و دستگاههایی برای خواندن و یا خواندن/نوشتن دیسکهای نوری Optical Discs مثل سیدیها ، دیویدیها و بلوریها که در انواع مخلف وجود دارند و البته به کمک وجود سلاتهای توسعه (Extension Slots) بر روی تخته مادر یا همان مادر برد ، کارتهای توسعه را به سیستم خود ، اضافه کنید ؛ مثل کارت گرافیک Graphics Card یا کارت صدا Audio Card و ... هر دستگاه Device ورودیها و خروجیهایی دارد . یعنی از ورودیها سیگنالهایی را دریافت میکند ، آنها را مورد پردازش قرار میدهد و سپس از طریق خروجیهای خود ، سیگنالهایی را میفرستد . برای همین دنیس ریچی در ادامه برخی از زبانها ولی برخلاف زبانهایی مثل پاسکال Pascal زبان C را طوری طراحی کرد تا بتوان برای تمام دستگاههای الکترونیکی برنامه نوشت
تابع ( Function ) در زبان C نوعی داده است که داده یا دادههای دیگری را به عنوان ورودی ، دریافت میکند و میتواند بر روی آنها پردازش یا پردازشهایی را انجام دهد و سپس به قسمت مربوطه ، خروجیای را بفرستد . با کمک زبان C و مقدار ناچیزی اسمبلی شما هیچ گونه محدودیتی در نوشتن برنامه خود ندارید . شما میتوانید در کمپانیهای بزرگ استخدام شوید و حقوق ماهیانه بالای ۱۰ هزار دلار تا ۲۰ هزار دلار و یا حتی بیشتر را دریافت کنید . کمپانیها و انستیتوها و شرکتهایی مثل IBM ، Macintosh ، Sun Microsystems ، Red Hat ، Microsoft ، SAMSUNG ، LG ، SONY ، JVC ، HP ، Panasonic و ... که البته برای این کار باید حتماً به الکترونیک نیز اشراف داشته باشید . از سویی دیگر بعد از زبان C میتوانید به راحتی به سراغ زبان ++C بروید و برنامههایی که نوشتن آنها توسط زبان C بسیار وقتگیر و کلافهکننده است ، در مدت زمان بسیار کمتری بنویسید و همچنان از قدرت C برخوردار باشید و پیشنهاد ما به شما این است که هم برنامهنویسی سطح پائین انجام بدهید ( به کمک سی و اسمبلی ) و هم برنامهنویسی سطح بالا ( به کمک سی و سیپلاسپلاس )
BIOS بایوس در سیستمهای رایانهای نیز با زبانهای سطح پائین نوشته می شود . کمپانی تولید کننده Motherboard مهندسین الکترونیکی دارد که برنامه BIOS را مینویسند که به این گونه برنامهها Firmware یا میانافزار گفته میشود . BIOS با ورود جریان الکتریکی به مادربرد تک تک دستگاهها را کنترل میکند و از سالم بودن و کار کردن آنها اطمینان حاصل مینماید ؛ سپس Boot Sectors ( سکتورهای بوت ) را در حافظه دائمی اصلی متصل به مادربرد بر روی CPU بارگذاری میکند . CPU نیز با بارگذاری کرنل و درایورها و کامپوننتهای سیستمعامل ( اجزاء کمکی میانافزار ) بر روی Cache خود و البته حافظه موقت RAM ، سیستمعامل را بارگذاری میکند . معمولاً نیز سیستمعاملها یک Boot Loader ( بوت لودر ) دارند تا تمام Boot Sector های سیستمعاملهای نصب شده بر روی کامپیوتر را شناسایی کرده و در فهرست بوت قرار دهد تا کاربر هر کدام را که خواست بارگذاری کند ؛ یکی از قویترین بوت لودرها ، GRUB گراب از GNU ( گنو ) میباشد . بوتلودر یک شبهکرنل است به همراه Component های دیگر ( اجزاء کمکی میانافزار ) که تمام Boot Sector ها را بر روی پارتیشنهای (Partitions) مختلف شناسایی میکند و اجازه Boot شدن آنها را به کاربر میدهد . ضمن اینکه Firmware های دیگری نیز وجود دارند که معروفترین آنها همان درایورها Drivers در سیستمعامل ویندوز میباشند که باعث راهاندازی و کار کردن Device ها ( دستگاههای مختلف سیستم ) میشوند و بدون آنها دستگاه یا کار نمیکند یا به صورت خیلی ضعیف و مشکلدار کار میکند . شما این Firmware ها را به کمک C و Assembly مینویسید ( شرکتهایی مثل nVidia یا ATi که بعدها توسط AMD خریده شد یا Creative یا ASUS و ... )
همان طور که گفته شد ، در هنگام استفاده از تابع که به آن فراخوانی Call یا احضار Invoke تابع میگوئیم ، دیگر نوع داده تابع و نوع داده و شناسههای پارامترهای آن را نمینویسیم ؛ بلکه نام تابع را به همراه دادههایی که میخواهیم به تابع پاس بدهیم یا به پارسی بفرستیم ( که به آنها آرگومان میگوئیم ) مینویسیم و تابع ، دادههای پاس داده شده به آن را در صورت نیاز مورد پردازش قرار میدهد و خروجی تعریف شده برای خود را ارائه میدهد که البته این در صورتی است که تابع را پیش از استفاده ، تعریف کرده باشید ( Function Definition ) در غیر این صورت باید پیش از استفاده ، آن را اعلان کنید ( Function Prototype ) و سپس آن را استفاده کنید و در جایی دیگر ، تابع را تعریف کنید . همچنین دادههایی که داخل جفت پرانتز باز و بسته تابع برای اعلان یا تعریف نوشته میشوند ، پارامتر نام دارند Parameter ولی در هنگام فراخوانی یا همان احضار تابع ، دادههایی که به تابع پاس میدهیم و میفرستیم و جایگزین پارامترها میکنیم « آرگومان » Arguments نام دارند
return-data-type function_name(data-type parameter_name1, data-type parameter_name2, ....)
{
data-processings;
return value;//for value
OR
return expression;//for expression
}
شبهکد بالا نحوه تعریف تابع را نشان میدهد : ابتدا نوع داده تابع را که قرار است بازگرداند ( return ) مینویسیم ، سپس نام و شناسه تابع را و در مقابل آن یک جفت پرانتز باز و بسته مینویسیم که داخل آن پارامترهای تابع را با نوشتن نوع داده آنها و نام و شناسه آنها تعریف مینمائیم ( در صورتی که تابع پارامتری ندارد و پذیرای آرگومانی نیست باید بنویسیم : function_data_type function_name(void) که ابتدا نوع داده تابع را مینویسید که قرار است بازگرداند و در مقابل آن نام و یا همان شناسه تابع را و سپس یک جفت پرانتز باز و بسته برای ایجاد تابع مینویسید که چون پارامتر ندارد به صورت استاندارد داخل پرانتزها کلیدواژه void را مینویسید ) ؛ سپس داخل بلوک تابع ( یعنی داخل آکولادهای باز و بسته ) دادهها را مورد پردازش قرار میدهیم و در پایان یا یک مقدار را یا یک عبارت را که باید ارزیابی شود و مقدار آن به دست بیاید را به کمک دستور return بازگرداندهایم . دقت کنید تا زمانی که تابع را تعریف نکنید ، مجاز به استفاده از آن نیستید مگر آنکه پیش از استفاده از آن ، تابع را اعلان کنید ( بدون آکولادهای باز و بسته و فقط نوع داده و شناسه تابع را بنویسید به علاوه پارامترهای آن که شامل نوع داده آنها و شناسههای آنها میشود که در پایان آن نیز باید یک نقطه ویرگول ، سمی کالن ( ; ) بگذارید ) سپس بعد از استفاده از تابع ، آن را در جایی دیگر ؛ خارج از هر بلوکی ، تعریف کنید . دقت کنید زمانی که آرگومانی را به تابع میفرستید و به عبارتی پاس میدهید ، نسخه کپیشدهای از آن ساخته میشود و به تابع فرستاده میشود تا تابع آن نسخه کپیشده را تغییر دهد و بازگرداند ؛ در صورتی که بخواهید ، تابع شما ، مقدار آرگومان شما را تغییر دهد ، باید پارامتر تابع خود را از نوع اشارهگر تعریف کنید و آرگومان خود را با کمک علامت امپرسند (&) که در زبان C به نام عملگر آدرسدهی شناخته میشود ، به تابع بفرستید تا با هر بار احضار تابع ، مقدار متغیر شما ( آرگومانی که میفرستید ) تغییر کند و به روز رسانی شود ؛ این مبحث را به صورت کامل و مفصل در بحث پارامترها و آرگومانها در همین فصل تشریح خواهیم نمود
در قطعه کد زیر نمونهای از یک تابع کاربردی را مینویسیم :
#include<stdio.h>
int power(int base , int exp)
{
int res = 0, var = 0;
for(int count=0; count<base; count++)
{
var = var + base;
}
for(int count=0; count<(exp-2); count++)
{
res = 0;
for(int count2=0; count2<base; count2++)
{
res = res + var;
}
var = res;
}
if (base == 0)
return 0;
if (exp == 0)
return 1;
else if (exp == 1)
return base;
else if (exp == 2)
return var;
else
return res;
}
int main()
{
int a = 0, b = 0;
printf("Enter base and exponent :\n");
scanf("%d%d", &a , &b);
printf("Your result is : %d\n", power(a, b));
return 0;
}
همین قطعه کد را میتوانستیم به صورت زیر بنویسیم :
#include <stdio.h>
int power(int base, int exponent);
int main()
{
int a = 0, b = 0;
printf("Enter base and exponent :\n");
scanf("%d%d", &a, &b);
printf("Your result is : %d\n", power(a, b));
return 0;
}
int power(int base , int exp)
{
int res = 0, var = 0;
for(int count=0; count<base; count++)
{
var = var + base;
}
for(int count=0; count<(exp-2); count++)
{
res = 0;
for(int count2=0; count2<base; count2++)
{
res = res + var;
}
var = res;
}
if (base == 0)
return 0;
if (exp == 0)
return 1;
else if (exp == 1)
return base;
else if (exp == 2)
return var;
else
return res;
}
در شکل اول ، تابع را تعریف کرده و سپس از آن استفاده کردهایم و در شکل دوّم ، ابتدا تابع را اعلان ( prototype ) کردهایم و سپس در جای دیگری از برنامه ، آن را تعریف کردهایم . دقت کنید : اگر بخواهید تابع را در فایلی دیگر تعریف کنید باید در اعلان آن از کلیدواژه ( keyword ) کلاس ذخیره خارجی ، یعنی extern استفاده کنید و سپس فایل را به برنامه خود ضمیمه کنید ( مراجعه شود به کلاسهای ذخیره )
تشریح برنامه :
این قطعه برنامه همان طور که در ادامه کتاب آن را کاملتر می نویسم میتواند صنعت رایانه و پردازندهها و یا همان پردازشگرها ( CPU ) را به سوی یک انقلاب رهنمون کند . ما در این برنامه ، با کمک عملگر جمع ، عمل به توان رساندن را تعریف نمودهایم که نیازی به عملیات ضرب در CPU ( به واسطه instruction - دستور العمل ) ضرب که زمان بیشتری میبرد ندارد و ضرورت وجود عملیات ضرب در CPU را از میان برمیدارد ( مطابق با مطالبی که در تاپیک « اندیشه » در تالار گفتگوی آزاد سایت لوتی نوشتم و در حال تکمیل آن در فیسبوک هستم ماشینها نیز همانند یک انسان سالم باید ادراک خطی و در یک راستا و سلسلهمند و یکپارچه داشته باشند ) . ابتدا یکی از فایلهای سرآیند استاندارد زبان C ( یعنی stdio ) که قصد استفاده از تابعهای آن را داشتیم ، یعنی printf و scanf را به برنامه خود ؛ با کمک دستور پیشپردازنده include ضمیمه نمودهایم . سپس تابعی با نام power به معنی توان را از نوع صحیح int که دو پارامتر به نامهای base به معنی پایه و exp ( مخفف exponent ) به معنی نما که هر دو از نوع داده صحیح int هستند دارد را تعریف نمودهایم ، بنابراین میتواند دو آرگومان صحیح را پذیرا باشد و میتوانیم دو آرگومان را به آن بفرستیم ( که باید از نوع داده صحیح int باشند ) . سپس ۲ متغیر با نوع صحیح تعریف کردهایم ، با نامهای var و res که هر دو مقدار 0 دارند . اولی مخفف variable است که به یک متغیر احتیاج داشتهایم و دومی res که مخفف result به معنی نتیجه است که نتیجه تابع ما میباشد . ابتدا با یک حلقه for توان ۲ عدد داده شده را محاسبه نمودهایم و آن را داخل var ذخیره کردهایم ؛ برای این کار باید متغیر var را که مقدار 0 دارد ؛ به تعداد base بار به معنی به تعداد پایه بار با مقدار 0 متغیر var جمع کنیم که در واقع مثل این میماند که عدد پایه را ، پایه بار منهای یک بار با خودش جمع کنیم ( حلقه for از 0 شروع میشود و تا زمانی که به base نرسیده انجام و تکرار میشود ) ؛ توضیح : ابتدا var مقدار 0 دارد و با base یا پایه جمع میشود و مقدار همان پایه را به خود میگیرد در انجام دوم حلقه for متغیر var که مقدار base و پایه را دارد دوباره با مقدار base جمع میشود و دوباره در متغیر var ذخیره میشود ) و این کار را به تعداد توان ( یا نما ) انجام می دهیم ( و به تعداد نمای منهای ۱ بار تکرار میشود ) . پس توان ۲ عدد را به دست میآوریم . توان ۰ هر عدد میشود ۱ و استثناء است و توان ۱ هر عدد میشود خود عدد پایه که باز هم استثناء است و از طریق محاسبات منطقی ما به دست میآید و توان ۲ نیز محاسبه شد که در var ذخیره شده بود و در حلقه for دوم نیز محاسبه نمیشود چون حلقه for به اجرا در نمیآید ( نمای ما ۲ است که 0 = 2 - 2 پس حلقه اجرا نمیشود ) ؛ حالا باید در صورتی که کاربر توانی ( نمایی ) بالاتر از ۲ را وارد کرد محاسبه کنیم . برای این کار با یک حلفه for به تعداد نما منهای ۲ تا ( exp - 2 ) بار ( چون نمای ۲ را حساب کردهایم و باید بعد از آن را حساب کنیم ، پس از نما ۲ واحد کم میکنیم ) احکام و دستوراتی را اجرا کردهایم که یکی از آنها دستور حلقه for دیگری است که همانند حلقه اوّلی res را که مقدار 0 دارد پایه بار با مقدار توان ۲ جمع کردهایم ( متغیر var مقدار توان ۲ را در خود دارد ) که بدین ترتیب توان ۳ به دست خواهد آمد ، بیرون از حلقه داخلی و در انتهای حلقه بیرونی نوشتهایم var = res تا مقداری که از res به دست آمد داخل var ریخته شود و سپس که حلقه باز میگردد تا دستورات را اجرا کند که در ابتدای حلقه for بیرونی res دوباره مقدار 0 میگیرد تا پایه بار با مقدار var که مقدار به دست آمده از توان قبلی بود ( در اینجا توان ۳ ) جمع شود و توان ۴ به دست بیاید و این مراحل به تعداد exp -2 یعنی توان یا نمای منهای دو بار اجرا میشود ( exp همان طور که گفته شد مخفف exponent به معنی نما میباشد ) . سپس در پایان تابع نوشتهایم که اگر پایه ۰ بود 0 را بازگردان و اگر نما ۰ بود مقدار ۱ را باز گردان و اگر نما ۱ بود مقدار پایه را برگردان و اگر بیشتر بود مقدار res را بازگردان ( چون شرط کردهایم که اگر نما 0 بود مقدار 1 را برگردان باید شرط دیگری هم بگذاریم که اگر پایه 0 بود مقدار 0 را بازگرداند و لزومی به انجام آن نبود و خود برنامه آن را محاسبه میکند اما چون شرط گذاشته شده که اگر نما 0 بود مقدار 1 را بازگرداند ، مجبور به گذاشتن شرط دیگری شدیم ) که مقدار به توان رسیده پایه را دارد ( که آخرین مقدار به جای مانده قبل از اجرای حکم res = 0 است . به یاد دارید که زبان C یک زبان دستورگرا است ؛ پس پیادهساز ، دستورات را خط-به-خط و کد-به-کد به مقادیر کدبایت codebyte های قابل ترجمه توسط کرنل و یا باینری Binary که برای ماشین خوانا است ترجمه میکند - بسته به اینکه برنامهنویسی سطح بالا انجام میدهید و یا سطح پائین که با توجه به دستور شما به پیادهساز است - پس دستور for با پایان خود مقدار توانیافته پایه را در res ذخیره میکند و دیگر res = 0 به اجرا در نخواهد آمد )
سپس در تابع اصلی برنامه که سطح بالا است ، یعنی تابع main دو متغیر به نامهای a و b با مقدار 0 تعریف نمودهایم . سپس با تابع کتابخانهای printf در خروجی خطدستوری چاپ کردهایم مقدار پایه و نما را وارد کنید و سپس با تابع کتابخانهای scanf که همانند printf در فایل سرآیند stdio تعریف شده است از کاربر دو مقدار گرفتهایم که در متغیرهای a و b ذخیره میشوند ( به ترتیب ) و سپس با تابع کتابخانهای printf چاپ کردهایم مقدار نتیجه شما میشود : / مقدار به دست آمده / Your result is : که به با فراخوانی و یا همان احضار تابع power و فرستادن دو آرگومان a و b که مقادیرشان را کاربر وارد کرده است مقدار ، محاسبه شده و در خروجی خطدستوری چاپ میشود ( دقت کنید چون تابع را به عنوان آرگومان ، فرستادهایم در پایان آن سمی کالن نمیگذاریم اما در صورتی که بخواهیم تابعی را فراخوانی و یا احضار کنیم باید سمی کالن بگذاریم ) ؛ در پایان نیز با دستور return مقدار 0 را به سیستم عامل بازگردانداهایم تا برنامه را با موفقیت پایان دهد ( terminate کند ) و منابع ( resources ) اشغال شده را آزاد کند
استدعا : از آنجایی که من این مشکل ریاضی را در سال ۸۶ حل کردم و با راهنمایی من از سالهای قبل و در همین چند وقته در سایت لوتی این معما در محاسبات ریاضی و برنامهنویسی حل شده بود ، من نیز خود در اینجا مسئله را به زبان برنامهنویسی حل کردم و البته برای اعداد کسری و اعشاری نیز در ادامه کتاب حل خواهم کرد ؛ اما از آنجایی که من به خاطر شرط بندی سال ۸۷ از تمامی حقوق خود ، منع شدم ؛ از انستیتوهای ریاضی و کمپانیهای بزرگ سازنده پرازندهها همچون IBM استدعا دارم جایزه در نظر گرفته شده برای حل این مسئله را به ایزدبانو علیاحضرت پرنسس سرکار علّیه خانم الهام طهموری پرداخت بنمائید . باشد که مورد قبول پیشگاه و ساحت مقدّس ایشان واقع شود . ممنون از شما
شما میتوانید مقدار بازگشته از یک تابع را در یک داده ذخیره کنید ؛ ولی در هنگام فراخوانی یا همان احضار تابع باید یک سمیکالن ( نقطهویرگول ) « ; » در انتهای تابع خود بگذارید تا به اجرا گذاشته شود مثل :
int c = power(2, 5);
شما میتوانید به جای پارامترهای تابع یک مقدار و یا یک عبارت را به عنوان آرگومان ، بفرستید و نیازی نیست تا حتماً Value یا مقدار باشد ، بلکه میتوانید یک متغیر و یا هر نوع شناسهای را که مقدار دارد به عنوان آرگومان به تابع بفرستید و یا همان پاس بدهید ولی برای اینکه تابعی را به عنوان آرگومان به تابع دیگری بفرستید حتماً باید پارامتر تابع خود را از نوع اشارهگر تعریف کنید و سپس با عملگر آدرس دهی ، تابع مورد نظر خود را به عنوان آرگومان به تابع دیگرتان ، در هنگام فراخوانی بفرستید ( این مسئله در مباحث بعدی تابع ، مفصلاً تشریح خواهد گردید ) دقت کنید : در برخی از تابعهای کتابخانهای ، مثل تابع printf شما میتوانید یک تابع را بدون ارجاع دادن و با نوشتن خود تابع ، به عنوان آرگومان ، فراخوانی کنید ؛ این مسئله بازمیگردد به نحوه تعریف تابع printf در فایل سرآیند stdio و استاندارد C که باعث میشود تا شما نیازی نداشته باشید تا تابعتان را با عملگر آدرسدهی به تابع ، بفرستید ( این مبحث در فصل فایلهای سرآیند و در مبحث فایل سرآیند stdio به تفصیل مورد تشریح قرار خواهد گرفت )