الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

[ تمت الإجابة ]سؤال في recursion

بدأه c0de في 31 أكتوبر 2012 · 7 رد · 777 مشاهدة · في الأسئلة المجابة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم،

اولا" اشكركم على هذا المنتدى الرائع واتمنى ان تقبلوني كتلميذ وصديق لكم ،واعذروا كتابتي الركيكه لان اهلي ادرجوني في مدارس وجامعات انجليزيه بحت. :wacko:

وسؤالي، عندي كود معين واعرف معظمه كيف يعمل ولكن الاشكال عندي في فهم اخر عمليه في ال function singTheSong!

#include <stdio.h>

void singTheSong(int numberOfBottles)
{
    if (numberOfBottles == 0) {
        printf("There are simply no more bottle of beer on the wall.\n");
    } else {
        printf("%d bottle of beer on the wall. %d bottle of beer.\n", numberOfBottles, numberOfBottles);
        int oneFewer = numberOfBottles - 1;
        printf("Take one down, pass it around, %d bottles of beer on the wall.\n", oneFewer);
        singTheSong(oneFewer); // This function calls itself
        printf("Put a bottle in the recycling, %d empty bottles in the bin.\n", numberOfBottles);
    }
}


int main(int argc, const char * argv[])
{
    singTheSong(99);
    return 0;
}

لماذا عندما يصل البرنامج الي هنا يبتدء المتغير numberOfBottles بالأزدياد وبرغم انه لا يوجد اي عملية جمع؟ لاماذا لا يقف البرنامج عندما يكون numberOfBottles صفر؟؟

   printf("Put a bottle in the recycling, %d empty bottles in the bin.\n", numberOfBottles);

ومرة" اخرى اعذروا اسلوبي في التعبير.

#2

أخي لاتوجد هناك أي زيادة كما قد تظن. خذ هذا البرنامج, مثل البرنامج السابق لكن بدون الإضافات :

#include <stdio.h>

int function(int number)
{
    if( number == 0 ) {
        return 0; 
    }

    printf("-> %d\n", number);   // A
    function(number - 1);        // B
    printf("=> %d\n", number);   // C

}

int main(int argc, char **argv)
{
    function(2);

    return 0;
}

عند تشغيله :

-> 2
-> 1
=> 1
=> 2

ماسيحدث مع الحاسوب يشبه هذا السيناريو:

أولاً لما مررت 2, لن تنجح عملية المقارنة لأن قيمة number لاتساوي 0. وسينفذ هذا السطر:

    printf("-> %d\n", number);   // A

ويطبع "-> 2". سيجد بعدها هذا السطر :

    function(number - 1);        // B

سيطرح 1 من 2, 2-1 = 1 ويستدعي function مع 1. لكن هناك:

    printf("=> %d\n", number);   // C

هذا السطر "سيؤجّل". حتى لاينسى الحاسوب الرقم الذي كان يريد طباعته, سيقوم بأخذ ورقة وكتابة الرقم 2 عليها ويضعها جانباً.

سيعيد بعدها تنفيذ الدالة, ولن تنجح عملية المقارنة أيضاً وسينتقل للسطر:

    printf("-> %d\n", number);   // A

ويطبع "-> 1". وينتقل للسطر :

    function(number - 1);        // B

سيطرح 1 وينتج لدينا 1-1=0, وسيتدعي الدالة function مع 0. لكن قبلها سيأخذ ورقة أخرى ويكتب فيها 1 ويضعها "فوق" الورقة السابقة حتى لاينسى.

الآن سيجد :

    if( number == 0 ) {
        return 0; 
    }

لان الرقم أصبح صفر لن يستمر.

هناك أسطر أجّلها لم ينفذها بعد, سيقوم بتنفيذها كالتالي:

سيسحب أول ورقة أمامه , آخر ورقة وضعها, وسيجد مكتوب عليها "1", وسيطبع هذا السطر مع 1 :

    printf("=> %d\n", number);   // C

سيسحب الورقة الثانية وسيجد أنه كتب عليها "2", وسيطبع هذا السطر مع 2:

    printf("=> %d\n", number);   // C

كما ترى لاتوجد هناك أي زيادة. لكن هذا يحدث لأن الحاسوب يقوم بتذكر الأشياء التي يؤجلها لفترة قصيرة عن طريق تكديسها فوق بعضها البعض بحيث أن آخر مايضعه, أول مايسحبه.

5
#3

يعني الحاسوب لم يجمع شي! فقط يسترجع القيم التي وضعت جانبا" من اخر قيمه الي اول قيمه حفظه الكمبيوتر (اي من الاجدد الي الاقدم)!

فهمت وشكرا" على هذا الشرح.

:)

تم تعديل هذه المشاركة بواسطة مصطفى 36a2 في 28 نوفمبر 2013 في 13:32 — السبب: إزالة الاقتباس

#4

مرحبا بك أخي الكريم :)

لكن لماذا البيرة ؟ :D

عموماً, الفكرة بسيطة جدا و هي أنه يتم التوقف في كل مرة عند قيمة numberOfBottles حيث يتم استدعاء الدالة بالوسيط oneFewer, و في النهاية ستتم العودة إلى قيم numberOfBottles بالمقلوب.

الصورة التالية تشرح الفكرة بافتراض أن numberOfBottles = 5 :

post-225348-021705900 1351724773_thumb.j

تحياتي.

المرفقات
Exemple.jpg
3
#5

اهلا" خالد!

بخصوص البيره انا نقلت الكود من كتاب اقرءه .. لكن كان افضل ان اغير البيره الي بيبسي او كوكاكولا مثلا" ههههه

41KYuQqMSZL._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA300_SH20_OU01_.jpg

شكرا" على مساهمتك ثبتت المعلومه اكثر. :cool:

#6

أهلا بك :)

فقط كملاحظة :

يوجد خطأ في السهم ذو اللون البرتقالي الذي يخرج من singTheSong(4) متجها إلى singTheSong(1), لأن استدعاء الدالة بالعدد 4 يليه 3 ثم 2 و بعد ذلك يأتي الاستدعاء بـ 1 في الخطوة الأخيرة.

الاستدعاءات الموجودة بين 4 و 1 عبرتُ عنها بنقاط التتابع, لكن السهم السابق يجب أن يخرج من استدعاء 4 متجها إلى نقاط التتابع و من نقاط التتابع إلى الاستدعاء بــ 1.

بالمناسبة, أصدقائي دائماً ما يقولون لي أنني سيء قي التصميم :D

أرجو أن أكون قد وُفقت في الشرح.

تحياتي.

#7

شكرا" اخي! كفيت ووفيت وفهمت المضمون العام من الفكره التي رسمتها ،شرحتها بصوره سهله جدا".

ولعلمك هذا لن يكون اخر استفساراتي ههههه

لي العوده.

مواضيع مشابهة