نمایش نتایج 1 تا 6 از 6

نام تاپیک: وجود 2 ساختار return در تابع

  1. #1

    وجود 2 ساختار return در تابع

    سلام
    من برای بالا بردن مهارتم در برنامه نویسی دارم تمرین های مختلفی رو حل می کنم که یکی از مابع من کتاب جعفرنژاد هست . تو صفحه 93 این کتاب یک تمرین وجود داره که الگوریتم اصلا سختی نداره ولی من یکم با نحوه نوشتن اون می خوام با دوستان هم فکری کنم .
    متن تمرین به این شرح است : برنامه ای که دو عدد صحیح مثبت را از ورودی خوانده ، حاصلضرب آن را با استفاده از جمع محاسبه کنید .
    خوب من عموما قبل اینکه پاسخ رو بخونم این کد رو خودم نوشتم (با توجه به این که فصل بیشتر در مورد تابع بازگشت هست باید برنامه با تابع بازگشت نوشته بشه ) :
    # include <iostream.h>
    # include <conio.h>

    int mul (int a , int b ){
    static int result = 0 ;
    if (b == 0 )
    return result ;
    else{
    result += a;
    return mul (a , b-1);
    }
    }
    int main () {
    int a , b ;
    cin >> a >> b ;
    cout << mul (a , b);
    getch ();
    return 0;
    }
    توضیح : متغیر static int result برای b بار جمع شدن a با خودش است و برای جلوگیری از مقدار گیری دوباره static تعریف شده.شرط پایان دهنده صفر شدن b می باشد.

    خروجی کد من کاملا درست بود ولی وقتی کتاب جعفر نژاد رو نگاه کردم به یه نکته جالب برخورد کردم . کد پاسخ به این صورت بود :
    # include <iostream.h>
    # include <conio.h>

    int product (int x , int y ){
    if (y == 1)
    return x ;
    return (x + product(x , y-1));
    }
    int main () {
    int x , y ;
    clrscr();
    cout << "Please enter two integer numbers .";
    cin >> x >> y ;
    cout << "Their product is : " << product (x , y);
    getch ();
    return 0;
    }
    خوب خروجی این کد هم درست بود ولی به فراخوانی ها نگاه کنید(x = 4 و y = 3 ) :
    فراخوانی اول :
    if (3 == 1)
    return 4 ;
    return (4 + product(4 , 3-1));
    فراخوانی دوم :
    if (2 == 1)
    return 4 ;
    return (4 + product(4 , 2-1));
    فراخوانی سوم :
    if (1 == 1)
    return 4 ;
    return (4 + product(4 , 1-1));
    نگاه کنید توی فراخوانی سوم شرطمون ارضا میشه یعنی 1 == 1 پس مقدار return 4 درست هست . حالا سوال من اینه که وقتی یک return در یک خط بالاتر وجود داره return بعدی یا در حالتی کلی return های بعدی skip میشن ؟ چرا توی فرراخوانی سوم product(4 , 1-1) اجرا نمیشه ؟
    ممنون
    سرافراز باشید

  2. #2
    کاربر دائمی آواتار clover
    تاریخ عضویت
    خرداد 1388
    محل زندگی
    اصفهان - اراک
    پست
    646

    نقل قول: وجود 2 ساختار return در تابع

    حالا سوال من اینه که وقتی یک return در یک خط بالاتر وجود داره return بعدی یا در حالتی کلی return های بعدی skip میشن ؟ چرا توی فرراخوانی سوم product(4 , 1-1) اجرا نمیشه ؟
    skip نمی شوند. دستور return باعث خروج از تابع و برگرداندن مقدار مورد نظر می شود، پس با رسیدن به اولین return از تابع خارج شده و کد های بعدی اجرا نمی شوند. به همین خاطر در if هایی که در بدنه اونها دستور return وجود داره از نوشتن else خودداری می کنند، اما در هر صورت نوشتن else از نظر مهندسی نرم افزار کار بهتری هست.

  3. #3

    نقل قول: وجود 2 ساختار return در تابع

    توی توابع بازگشتی وقتی همچین return haei وجود داره کامپایلر میره تا نهایت تابع بازگشتی یعنی تا حالا مقدار return ها واسه کامپایلر سواله وقتی تابع بازگشتی به جایی رسید که شرط برقراره یه مقدار دقیقی return میکنه و شروع میکنه از اخر به اول اومقدار دهی میشه و return هایی که کامپایلر نمیدونست جیه مقدار دستی میگیره وبا استفاده از اونا return نهایی حاصل میشه مثلا در قطعه کدی که شما نوشتی
    کامپایلر تا شرط میره و مقدار 4 رو return میکنه وبقیه فراخوانی چهارم اجرا نمیشه یعنی فاراخوانیدومت اینجوری میشه
    return (4 + 4);
    بعدش فراخوانی اولش اینجوری میشه
    return (4 +8);
    و نهایتا مقدار 12 return میشه امیدوارم موفق باشی

  4. #4

    نقل قول: وجود 2 ساختار return در تابع

    توابع بازگشتی دارای دو قسمت هستند : Base case (حالت پایه ) و Recursive Case (حالت بازگشتی)

    در توابع این قانون وجود داره که بعد returnتابع هر چند خط کد که وجود داشته باشد ، کامپایل نخواهد شد و

    از ساختار تابع خارج میشود که توابع بازگشتی نیز از این قانون مستثنا نیستند .

    تو این توابع تا زمانیکه شرط حالت پایه برقرار نیست ، قسمت بازگشتی فراخوانی میشه تا در نهایت برسیم

    به حالت پایه ، و وقتی به حالت پایه رسیدیم یک مقداری return شده و از تابع خارج میشویم و قسمت

    بازگشتی اجرا نخواهد شد . در ضمن گذاشتن if/else ها در ساختار توابع بازگشتی خوانایی کد ما را بالا

    میبرد و همانطور که دیدید حذف else هیچ مشکلی نخواهد داشت .

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

    کد اول :


    int fact(int n){
    if(n==1)
    return 1;
    return n*fact(n-1);
    }


    کد دوم :


    int fact(int n){
    if(n==1)
    return 1;
    else
    return n*fact(n-1);
    }


    موفق باشید .






  5. #5

    نقل قول: وجود 2 ساختار return در تابع

    خیلی ممنون از پاسخ های کاملی که دادید.
    سالار جان در مورد تابع فاکتوریالی که نوشتید یک سوال دیگه داشتم . من با قرار دادن unsigned long به عنوان datatype برای تابع تونستم تا فاکتوریل 33 رو حساب کنم . نکته جالب اینکه الباقی فاکتوریل ها رو به صورت صفر برمی گردوند ( از این جهت می گم جالب چون که وقتی Integer بود تا فاکتوریل 6 یا 7 محاسبه می شد و بعد اون رو یه سری مثبت رد می کرد و یه سری منفی اگه این دلیلش رو هم به من بگید ممنون میشم )وقتی long double گذاشتم تونستم تا فاکتوریل 384 رو حساب کنم اما خوب برای فاکتوریل های بالاتر به نظرتون چه کار دیگه ای میشه کرد ؟ مثلا فاکتوریل 1000 یا بالاتر . اینو از اون لحاظ می گم که توی انتخاب r شی از n شی نیاز به محاسبه فاکتوریل های عظیم هست.
    ممنون
    سرافراز باشید

  6. #6

    نقل قول: وجود 2 ساختار return در تابع

    نقل قول نوشته شده توسط hossein2kk مشاهده تاپیک
    خیلی ممنون از پاسخ های کاملی که دادید.
    سالار جان در مورد تابع فاکتوریالی که نوشتید یک سوال دیگه داشتم . من با قرار دادن unsigned long به عنوان datatype برای تابع تونستم تا فاکتوریل 33 رو حساب کنم . نکته جالب اینکه الباقی فاکتوریل ها رو به صورت صفر برمی گردوند ( از این جهت می گم جالب چون که وقتی Integer بود تا فاکتوریل 6 یا 7 محاسبه می شد و بعد اون رو یه سری مثبت رد می کرد و یه سری منفی اگه این دلیلش رو هم به من بگید ممنون میشم )وقتی long double گذاشتم تونستم تا فاکتوریل 384 رو حساب کنم اما خوب برای فاکتوریل های بالاتر به نظرتون چه کار دیگه ای میشه کرد ؟ مثلا فاکتوریل 1000 یا بالاتر . اینو از اون لحاظ می گم که توی انتخاب r شی از n شی نیاز به محاسبه فاکتوریل های عظیم هست.
    ممنون
    سرافراز باشید
    نوع داده ای unsigned یعنی بدون علامت (فقط اعداد مثبت) به همین دلیل برای اعداد بزرگ

    صفر نشون داده میشه ولی نوع int میتونه مثبت یا منفی باشه !

    در مورد محاسبه فاکتوریل اعداد بزرگ نیز بحث های زیادی توی تالار شده ، با جستجو میتونید

    موردهای مناسبی پیدا کنید !

    موفق باشید.






قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •