الفريق العربي للبرمجةأرشيف المنتديات · 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

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

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

لي العوده.

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

عدد الزوار حالياً

المتواجدون خلال آخر ساعة · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…