450 likes | 696 Views
مبانی برنامه نویسی. محسن باقریان baqerian@iust.ac.ir دانشکده مهندسی برق دانشگاه علم و صنعت ایران پاییز 1390. توابع و مقدمه ای بر بازگشتی. برنامه هایی که تا حالا نوشتیم، بسیار ساده بودند. برنامه های کاربردی واقعی بوده و بسیار پیچیده تر هستند.
E N D
مبانی برنامه نویسی محسن باقریان baqerian@iust.ac.ir دانشکده مهندسی برق دانشگاه علم و صنعت ایران پاییز 1390
توابع و مقدمه ای بر بازگشتی برنامه هایی که تا حالا نوشتیم، بسیار ساده بودند. برنامه های کاربردی واقعی بوده و بسیار پیچیده تر هستند. این برنامه ها عمدتا به چندین بخش کوچکتر تقسیم شده و هر بخش کوچک تر که وظیفه خاصی دارد به صورت مجزا نوشته شده و در نهایت برنامه اصلی ساخته می شود. به این روش تقسیم و غلبه (divide & conquer)می گویند. تست و خطایابی چند تابع کوچک خیلی سریعتر و بهتر از یک تابع بزرگ انجام می شود.
توابع و مقدمه ای بر بازگشتی (ادامه) یک تابع با فراخوانی فعال می شود و وظیفه ای که به عهده دارد را انجام می دهد. برای این منظور باید نامی برای تابع انتخاب کنیم و همچنین اطلاعات مورد نیاز آن را (آرگومان) به آن ارسال کنیم. هنگامی که تابع وظیفه خود را به انجام رساند، کنترل برنامه به فراخواننده بازگردانده می شود. تابع می تواند نتیجه ای را هم به عنوان خروجی به فراخواننده برگرداند. نکته ای که وجود دارد این است که فراخواننده نمی داند که تابع چگونه وظیفه خود را انجام می دهد. حتی نمی داند که آیا تابع به تنهایی کار میکند یا از توابع دیگری هم استفاده می کند. مثال کارفرما و کارگر
توابع و مقدمه ای بر بازگشتی (ادامه) همانطور که در قبل دیدیم یک کلاس حاوی تعدادی تابع عضو است که وظایف خاصی را انجام می دهند. به عنوان نمونه کلاس GradeBook که قبلا تعریف شد و استفاده هایی از آن شد دارای چندین تابع بود. تعدادی تابع در این کلاس استفاده شد که عضو کلاس نبودند. به این توابع توابع سراسری می گویند. این توابع سراسری در فایل سرآیند تعریف شدهاند. مثلا قبلا از تابع pow از کتابخانه <cmath> استفاده شد. این تابع یک تابع سراسری بود. تعریف آن هم در سرآیند math.h بود. به آدرس http://www.cplusplus.com/reference/clibrary/cmath/یا http://msdn.microsoft.com/en-us/library/7wsh95e5%28v=VS.100%29.aspxسری بزنید.
توابع و مقدمه ای بر بازگشتی (ادامه) برنامه هایی که تا اینجا نوشته شد اکثرا یک پارامتر به عنوان ورودی میگرفتند. تابع pow از کتابخانه <cmath> دو ورودی می گرفت. در اینجا می خواهیم به معرفی توابعی بپردازیم که چند پارامتر به عنوان ورودی دریافت می کنند. به عنوان مثال فرض کنید در کلاس GradeBook می خواهیم یک تابع اضافه کنیم که سه نمره را دریافت کرده و ماکزیمم آنها را به خروجی ارسال کند. برای این منظور نیاز به سه تابع داریم. یکی برای گرفتن نمرات یکی برای محاسبه ماکزیمم و دیگری برای نمایش دادن ماکزیمم نمرات.
توابع و مقدمه ای بر بازگشتی (ادامه)
توابع و مقدمه ای بر بازگشتی (ادامه)
توابع و مقدمه ای بر بازگشتی (ادامه) سه راه برای بازگشت به نقطه فراخواننده وجود دارد 1- عبارت return; برای زمانی که نوع برگشتی تابع void است. 2- { زمانی که نوع برگشتی تابع void است. 3- برگشت دادن مقداری به تابع با استفاده از return statement; تعریف نمونه اولیه تابع (اعلام تابع) همیشه باید صورت پذیرد. این کار به کامپایلر نام تابع، نوع برگشتی و نوع و تعداد آرگومان های ورودی را اعلان می کند. بهتر است این کار در فایل سرآیند انجام شود و تعریف بدنه تابع نیز در فایل با پسوند cpp صورت پذیرد. اگر نمونه اولیه تابع به درستی تعریف شود، دیگر در توابع ترتیب تعریف اهمیت نداشته و همه جا به آن دسترسی است.
توابع و مقدمه ای بر بازگشتی (ادامه) همان چیزی که در نمونه اولیه تابع مشخص شده باید تعریف گردد. به عنوان مثال اگر اعلان تابع maximum (معرفی نمونه اولیه تابع) در کلاس GradeBook به صورت intmaximum(int, int, int); باشد دیگر نمی توان آن را به صورت void maximum(int x, int y, int z); تعریف کرد. این کار خطا ایجاد می کند. یکی از ویژگی های مهم در نمونه اولیه تابع تبدیل آرگومان است.یعنی اگر شما در نمونه اولیه تابع نوع متغیر ورودی را از نوع double انتخاب کرده باشید می توانید به آن یک نوع صحیح انتقال دهید. به تبدیل نوع متغیرها به هم ترقی متغیر می گویند.
توابع و مقدمه ای بر بازگشتی (ادامه) ترقی متغیر بر طبق قانون صورت می پذیرد. قوانین ترقی متغیرها بیان میکند که چگونه متغیرها بدون از دست دادن داده به یکدیگر تبدیل شوند. یک متغیر int را اگر به double تبدیل کنیم، بدون از دست دادن هیچگونه اطلاعاتی این تبدیل انجام می شود. اما اگر یک متغیر double را به یک متغیر int تبدیل کنیم، قسمت اعشاری از بین می رود. دقت داشته باشید که در تبدیل نوع بزرگتر به نوع کوچکتر (مثلا در تبدیل long به short) احتمال اینکه داده کلا تغییر کند وجود دارد. در تبدیل پارامترها همیشه پارامترها به بالاترین نوع موجود در عبارت تبدیل شده و سپس ارزیابی صورت می گیرد. البته این تغییر زمانی رخ می دهد که نوع داده با آنچه در تعریف تابع یا نمونه اولیه تابع آمده فرق داشته باشد.
توابع و مقدمه ای بر بازگشتی (ادامه) انواع داده بنیادین به ترتیب از بالاترین نوع به پایین ترین نوع
توابع و مقدمه ای بر بازگشتی (ادامه) معرفی کلاس های استاندارد C++ http://msdn.microsoft.com/en-us/library/ct1as7hw.aspx
توابع و مقدمه ای بر بازگشتی (کوییز)
توابع و مقدمه ای بر بازگشتی (ادامه) شانس یا عدد تصادفی در C++ را چگونه تولید کنیم؟ تابع rand() این کار را انجام می دهد. این تابع یک عدد صحیح بدون علامت از صفر تا عدد ثابت RAND_MAX به صورت تصادفی انتخاب می کند. ثابت RAND_MAX اگر 16 بیتی باشد برابر با 32767 است در ویژوال استادیو مقدار RAND_MAX همین 32767 است. اگر تابع rand() اجرا شود کلیه مقادیر از صفر تا RAND_MAX از احتمال یکسانی برخوردار هستند. در برنامه ها تولید عدد تصادفی نیاز می شود. مثلا هنگامی که می خواهیم نویز تولید کنیم باید از همین تابع استفاده کنیم.
توابع و مقدمه ای بر بازگشتی (ادامه) همیشه اعداد تصادفی به همین صورتی که C++ در اختیار می گذارد مناسب نیست و باید عدد تصادفی در بازه ای که نیاز است قرار گیرد. مثلا فرض کنید می خواهیم پرتاب سکه را شبیه سازی کنیم. یا می خواهیم پرتاب تاس 6 وجهی را شبیه سازی کنیم. در اینجا پرتاب تاس 6 وجهی را شبیه سازی می کنیم. چگونه اعداد صفر تا 32767 را به 1 تا 6 نگاشت دهیم؟ بهتر است از دستور rand() % 6+1استفاده کنیم. در ضمن دستور rand() در کتابخانه <cstdlib> قرار دارد. برنامه برای پرتاب تاس در صفحه بعد آمده است.
توابع و مقدمه ای بر بازگشتی (ادامه)
توابع و مقدمه ای بر بازگشتی (ادامه) چگونه مطمئن شویم که احتمال آمدن وجوه در پرتاب تاس تقریبا برابر است؟ اگر 6 میلیون بار تاس را پرتاب کنیم، چه انتظاری دارید؟ انتظار می رود که هر کدام از وجوه حدود یک میلیون بار بیاید. برای این منظور 6 میلیون بار تاس را پرتاب می کنیم و تعداد هر کدام از وجوه را ثبت می کنیم در نهایت تعداد آمدن هر یک از وجوه را در خروجی نشان می دهیم. اگر تعداد هر کدام از وجوه تقریبا برابر با یک میلیون بود، یعنی احتمال آمدن هر وجه تقریبا یک ششم است. برنامه را در 17 مشاهده کنید.
توابع و مقدمه ای بر بازگشتی (ادامه) به نظر شما اگر برنامه اسلاید شماره 15 را چند بار تکرار کنیم چه اتفاقی می افتد. آیا اعداد تکراری نیستند؟ آیا این با حالت تصادفی واقعی اختلاف ندارد؟ برای رفع این مشکل از srand استفاده می کنیم. برای این منظور در برنامه مذکور قبل از استفاده از دستور rand() از دستور rand(seed) استفاده می کنیم. در اینجا seed را از کاربر میگیریم. اگر بخواهیم کاملا اعداد تصادفی باشند می توان به جای گرفتن seed از کاربر آنرا با زمان سیستم نیز تعیین کرد. srand(time(0))
توابع و مقدمه ای بر بازگشتی (ادامه) برای اینکه با ENUMها آشنایی پیدا کنیم و همچنین مبحث ایجاد متغیرهای تصادفی بهتر درک شود به مثال بعدی توجه کنید. در این مثال می خواهیم یک بازی شانس را شبیه سازی کنیم. در این بازی دو تاس 6 وجهی به صورت همزمان پرتاب می شود. اگر جمع دو تاس 7 یا 11 شد، فرد برنده است. در صورتی که جمع برابر با 2، 3 یا 12 شد بازیگر بازنده است و در صورتی که جمع دو تاس 4، 5، 6، 8، 9 و 10 شد، این مجموع به عنوان امتیاز بازیکن در نظر گرفته می شود. در این صورت بازیکن باید پرتاب را ادامه دهد تا به امتیاز مورد نظر برسد. در صورتی که بازیکن به مجموع 7 برسد بازنده است. در برنامه نوشته شده فرایند را مشاهده می کنید. (برنامه شماره 18)
توابع و مقدمه ای بر بازگشتی (ادامه) قرارداد: بهتر است که کلیه حروف ثوابت ENUM بزرگ انتخاب شود تا این ثوابت در برنامه با متغیرها اشتباه نشوند. چند ENUM معروف دیگر وجود دارد enum Months { JAN = 1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NPV, DEC}; enumweekDays{MON =1,TUS, WED, THU, FRI, SAT, SUN}; در نوع های شمارشی فوق به صورت صریح مقدار از یک شروع شده است. بقیه یکی یکی اضافه می شوند. به هر نوع شمارشی می توان یک عدد صحیح نسبت داد. مزیت استفاده از نوع شمارشی در برنامه ها خواناتر کردن برنامه ها میباشد.
توابع و مقدمه ای بر بازگشتی (کوییز) عبارتی بنویسید که به صورت تصادفی یکی از اعداد زیر را تولید کند الف) 2، 4، 6، 8، 10، 12 ب) 3، 5، 7، 9، 11 پ) 6، 10، 14، 18، 22 ت) n از 3- تا 11
توابع و مقدمه ای بر بازگشتی (ادامه) شناسههایی که تا اینجا عنوان شدند، شامل نام نوع و مقدار بودند. در مورد این شناسهها حرفی از کلاس ذخیره سازی، قلمرو (scope) وپیوند (linkage) به میان نیامد. در اینجا قصد داریم با کلاس های ذخیرهسازی قلمرو متغیرها و پیوند آشنا شویم. در C++ پنج کلاس ذخیره سازی با نام های auto، register، extern، mutableو static وجود دارد. شناسه (Identifier)یک کلاس ذخیره سازی تعیین کننده مدت زمانی است که شناسه در حافظه وجود دارد. برخی از شناسه ها مدت زمان کوتاهی در حافظه وجود دارند، برخی به تناوب ایجاد و نابود می شوند و برخی نیز در کل مدت اجرای برنامه در حافظه وجود دارند.
توابع و مقدمه ای بر بازگشتی (ادامه) قلمرو یک شناسه نیز به جایی می گویند که شناسه در آن محدوده قابل استفاده بوده و نمایان است. برخی از شناسه ها در کل برنامه در دسترس بوده و برخی فقط در قسمت خاصی از برنامه در دسترس هستند. پیوند یک شناسه نیز تعیین می کند که آیا شناسه فقط در فایل منبع که در آن اعلان شده است شناخته شود یا در میان فایل های مضاعف که کامپایل شده و به یکدیگر لینک شده اند هم شناخته شود. کلاس ذخیرهسازی یک شناسه در تعیین کلاس ذخیره سازی و پیوند آن نقش دارد. کلاس های ذخیره سازی عمدتا به دو دسته تقسیم می شوند.
توابع و مقدمه ای بر بازگشتی (ادامه) کلاس ذخیره سازی اتوماتیک و کلاس ذخیره سازی استاتیک. کلمات کلیدی auto و register برای اعلان متغیرهایی از کلاس ذخیرهسازی اتوماتیک استفاده می شود. متغیر اتوماتیک در کل برنامه در دسترس نیست و فقط در یک بلوک خاص از برنامه تعریف شده و بعد از خروج از آن بلوک خاص متغیر از بین می رود. کلمه auto به صورت صریح بیان می کند که متغیر از نوع اتوماتیک است. فقط متغیرهای محلی می توانند به صورت اتوماتیک باشند. با توجه به اینکه متغیرهای محلی همگی به صورت پیش فرض اتوماتیک هستند به ندرت کلمه auto در برنامه ها دیده می شود. ذخیره سازی به صورت اتوماتیک از اشغال حجم اضافی حافظه جلوگیری میکند.
توابع و مقدمه ای بر بازگشتی (ادامه) متغیرهای از نوع register عمدتا متغیرهایی هستند که تناوبا به وجود آمده و از بین می روند. این متغیرها نیز متغیرهای محلی هستند. به عنوان مثال زمانی که در برنامه یک counter وجود دارد یا زمانی که در برنامه می خواهید مجموع حساب کنید، در این صورت متغیری دارید که خیلی زیاد مورد استفاده قرار می گیرد. در این صورت به کامپایلر اعلام می کنید در صورت امکان این متغیرها را در قسمتی از سخت افزار قرار بده که سرعت بیشتری از حافظه دارد، تا برای خواندن و نوشتن این متغیر زمان کمتری تلف شود. امروزه کامپایلرها خود تشخیص این امر را داده و متغیرهای اینچنینی را به صورت register تعریف می کنند و نیازی به دستور از طرف برنامه نویس ندارند.
توابع و مقدمه ای بر بازگشتی (ادامه) کلاس ذخیره سازی استاتیک با کلمات کلیدی extern و static معرفی میشود. در کلاس استاتیک شناسه ها در ابتدای برنامه تولید شده و تا زمانی که برنامه در حال اجراست، شناسه ها وجود دارند. یکی از شناسه هایی که همیشه در اول برنامه به وجود می آید نام توابع هستند. که در ابتدای برنامه تولید شده و تا انتهای برنامه حافظه را اشغال می کنند. نکته: وجود یک متغیر به صورت استاتیک دلیلی برای دسترسی به آن نیست. دو نوع شناسه استاتیک وجود دارد. یکی شناسه های خارجی (مانند متغیرهای سراسری و نام توابع سراسری) و دیگری متغیرهای محلی که به صورت استاتیک اعلان می شوند.
توابع و مقدمه ای بر بازگشتی (ادامه) متغیرهای سراسری در خارج از بدنه تابع یا کلاس تعریف می شوند. متغیرهای سراسری در هر جای برنامه می توانند مورد استفاده قرار گیرند. متغیرهای محلی تعریف شده به صورت استاتیک فقط در محل مورد استفاه (مثلا بدنه تابع) قابلیت دسترسی دارند. این متغیرها پس از اتمام کار تابع از بین نمی رود. البته به آن دسترسی هم نداریم. فقط زمانی که تابع دوباره فراخوانی می شود، این متغیر با همان مقداری که برنامه تمام شده بود در دسترس است.
توابع و مقدمه ای بر بازگشتی (ادامه) به بخشی از برنامه که یک شناسه در آنجا می تواند به کار گرفته شود، قلمرو (Scope) آن شناسه می گویند. در اینجا به چهار قلمرو می پردازیم: قلمرو تابع، قلمرو فایل، قلمرو بلوکی و قلمرو نمونه اولیه تابع شناسه اعلان شده در خارج از بدنه تابع یا کلاس دارای قلمرو فایل است. چنین شناسه ای از مکانی که در آن اعلان شده تا انتهای فایل در تمامی توابع شناخته می شود. متغیرهای سراسری، تعریف تابع و نمونه های اولیه تابع که در خارج از تابع قرار می گیرند همگی دارای قلمرو فایل هستند. برچسبها تنها شناسه های با قلمرو تابع هستند. برچسبها می توانند در هرجای تابع که در آن ظاهر می شوند به کار گرفته شوند. در خارج از بدنه تابع قابل استفاده نیستند. برچسب در عبارت goto استفاده دارد.
توابع و مقدمه ای بر بازگشتی (ادامه) شناسههایی که درون یک بلوک اعلان شده اند، دارای قلمرو بلوکی هستند. قلمرو بلوکی از مکان اعلان شناسه آغاز شده و در مکانی که براکت بسته بلوکی که شناسه در آن اعلان شده قرار دارد، خاتمه میپذیرد. متغیرهای محلی دارای قلمرو بلوکی هستند. اگر در بلوک یک متغیر همنام متغیر خارج بلوک تعریف کنیم چه میشود؟ متغیرهای محلی استاتیک نیز از نوع بلوکی هستند. کلاس ذخیره سازی در قلمرو آن تاثیر نداشته و تغییر ایجاد نمی کند. تنها شناسه هایی که دارای قلمرو نمونه اولیه تابع می باشند، شناسه هایی هستند که در لیست پارامتری نمونه اولیه تابع به کار رفته اند. همانطور که قبلا اشاره شد، در اعلان تابع نیازی به حضور نام متغیر ورودی نیست و فقط نوع آنها مورد نیاز است. اسامی به کار رفته در لیست پارامتری یک نمونه اولیه تابع از طرف کامپایلر نادیده گرفته می شوند. (برنامه 20 را مشاهده کنید)
توابع و مقدمه ای بر بازگشتی (ادامه) قسمت های زیر را خودتان مطالعه کنید: 6.11 Function Call Stack and Activation Records 6.12 Functions with Empty Parameter Lists
توابع و مقدمه ای بر بازگشتی (ادامه) توابع inline پیاده سازی یک برنامه به صورت مجموعه ای از توابع از نظر مهندسی نرمافزار کار مناسبی است، اما فراخوانی های تابع، سربارگذاری زمان اجرا به دنبال دارد. برای کاهش سربارگذاری زمان اجرا از توابع inline استفاده می کنیم. این کار برای توابع کوچک و پرکاربرد بسیار مفید بوده و زمان اجرا را کاهش می دهد. هنگامی که از توصیف کننده inline استفاده می کنیم به کامپایلر اعلام می کنیم که در جایی که تابع اعلان شده است، یک کپی از آن را قرار دهد.
توابع و مقدمه ای بر بازگشتی (ادامه) از طرفی حجم برنامه با کپی های متوالی افزایش می یابد. پس بهتر است که توابه inline در جایی که تابع کوچک و پرکاربرد است به کار گرفته شود. این بدان معناست که توابع inline حجم برنامه را افزایش داده و در قبال آن قادر خواهند بود تا زمان اجرا را کاهش دهند. باید دید کدام بهتر است؟
توابع و مقدمه ای بر بازگشتی (ادامه) مراجعه و پارامترهای آن تا به اینجا هر پارامتری که به یک تابع ارسال می شد، تابع از آن یک کپی می گرفت و پردازشهای لازم را روی آن انجام می داد. اگر حجم داده بزرگ باشد چه کنیم؟ اجازه دهیم تا زمان زیادی صرف کپی گرفتن از پارامترهای ورودی کند؟ همچنین اجازه دهیم تا فضای اضافی توسط برنامه اشغال شود؟ برای این منظور از ارسال با مقدار استفاده نکرده و از روش ارسال با مراجعه استفاده می کنیم. مزیت این روش استفاده بهینه از حافظه است. عیب آن هم امنیت کمتر آن است. در برنامه نویسی باید ببینیم کدام ارجح است.
توابع و مقدمه ای بر بازگشتی (ادامه) count یک مراجعه به int است. int &count برنامه (22) را مشاهده کنید.
توابع و مقدمه ای بر بازگشتی (ادامه) آرگومان های پیش فرض در برنامه ها ممکن است نیاز باشد تا اگر کاربر تعدادی از ورودی ها را تعریف نکرد از مقادیر پیش فرض استفاده کند. آرگومان های پیش فرض سمت راست ترین آرگومان ها در لیست پارامتری تابع هستند. به عنوان مثال می خواهیم حجم یک مکعب را به دست آوریم. می خواهیم اگر کاربر هیچ عددی را وارد نکرد کلیه وجوه یک در نظر گرفته شوند و اگر مقدار برای آن مشخص کرد از مقدار داده شده توسط کاربر استفاده کنیم. به مثال توجه کنید (برنامه 23)
توابع و مقدمه ای بر بازگشتی (ادامه) استفاده از متغیرهای سراسری (global) نکته: برای اجتناب از خطا از به کار بردن متغیرهای همنام استفاده نکنید متغیر محلی متغیر سراسری
توابع و مقدمه ای بر بازگشتی (ادامه) سربارگذاری تابع (Function Overloading) زمانی که تابعی با پارامترهای از نوع مختلف نیاز داریم، می توانیم توابعی همنام تعریف کرده و از آن ها استفاده کنیم. به عنوان مثال فرض کنید می خواهیم تابعی داشته باشیم که متغیری از نوع int، doubleو حتی char را به عنوان ورودی دریافت کرده و پردازش لازم را روی آن انجام دهد. برای این منظور می توان سه تابع با یک نام با متغیر نوع متفاوت تعریف کرد. در اینصورت C++ خود تشخیص می دهد که کدام تابع را انتخاب کند. به مثال توجه کنید.
توابع و مقدمه ای بر بازگشتی (ادامه)
توابع و مقدمه ای بر بازگشتی (ادامه) الگوهای تابع (Function Templates) در صورتی که برنامه برای انواع مختلف داده کار یکسانی انجام داده و منطق برنامه تغییری نمی کند می توان به جای سربارگذاری از الگوی تابع که به مراتب ساده تر و خلاصه تر است استفاده کرد. پس در صورتی از سربارگذاری استفاده می کنیم که منطق برنامه برای انواع مختلف داده فرق کند. مثلا فرض کنید می خواهیم برنامه بنویسیم که ماکزیمم بین چند عدد را پیدا کند. برای این منظور با توجه به اینکه منطق برنامه برای کلیه انواع داده یکسان است می توانیم از الگوی تابع استفاده کنیم. به مثال توجه کنید.
توابع و مقدمه ای بر بازگشتی (ادامه) روش تعریف الگوی تابع maximun.h
توابع و مقدمه ای بر بازگشتی (ادامه) روش استفاده از الگوی تابع
توابع و مقدمه ای بر بازگشتی (ادامه) توابع بازگشتی (Recursion) برنامه هایی که تا اینجا نوشته شدند توابع را به صورت سلسله مراتب و صریح فراخوانی می کردند. تا اینجا هیچ تابعی خود را فراخوانی نمی کرد. برای حل برخی از مسایل لازم است که یک تابع خود را فراخوانی کند. به عنوان مثال فرض کنید که می خواهیم برنامه ای بنویسیم تا n! را به دست آورد. برای این منظور دو راهکار وجود دارد. یکی استفاده از حلقه و ضرب اعداد 1 تا n و به دست آوردن n!. راهکار بعدی این است که n! را از ضرب n در (n-1)! به دست آوریم. این همان فراخوانی یک تابع در خود تابع است. نکته ای که وجود دارد این است که باید شروعی را برای این کار تعریف کنیم.
توابع و مقدمه ای بر بازگشتی (ادامه) 5! 120 5×4! 4×3! 24 6 3×2! 2×1! 2 1
توابع و مقدمه ای بر بازگشتی (ادامه)
توابع و مقدمه ای بر بازگشتی (ادامه) حال می خواهیم سری فیبوناتچی را تولید کنیم. سری فیبوناتچی به این صورت تعریف می شود: فیبوناتچی صفر = صفر فیبونتچی یک = یک فیبوناتچی n = جمع فیبوناتچی n-1 و فیبوناتچی n-2 سری فیبوناتچی = 0، 1، 1، 2، 3، 5، 8، 13، 21، 34 و ....