إعادة القيم من الدالة في ++C
إعادة القيم من الدالة
قد يكون الهدف من الدالة الإجابة علي سؤال معين , مما يتطلب أن تبعث الدالة بالرد علي الدالة المستدعية . وفي البرنامج التالي سوف نستخدم دالة فرعية تتقبل الوزن بالرطل من الدالة المستدعية . ثم تعيده بالكيلو جرامات :
convert.cpp
// convert.cpp// demonstrates return values, converts pounds to kg#include <iostream.h>
#include <conio.h>
float lbstokg(float);
void main() { float lbs, kgs; cout << "\nEnter your weight in pounds: ";cin >> lbs;
kgs = lbstokg(lbs);
cout << "Your weight in kilograms is " << kgs;getche();
}
// lbstokg()// converts pounds to kilogramsfloat lbstokg(float pounds)
{ float kilograms = 0.453592 * pounds; return kilograms;}
وحينما تعيد الدالة قيمة ما , فإن نوع هذه القيمة يجب أن يعرف في الإعلان , ولذا فقد سبق اسم الدالة كلمة float المعبرة عن نوع القيمة المعادة , فظهر سطر الإعلان في صدر البرنامج كالتالي :
Float lbstokg (float);
أما كلمة float بين القوسين فتعرف نوع معامل الدالة (القيمة المرسلة للدالة ) كما عرفنا . كما تم نفس الشئ في سطر التنويه عن الدالة في الجزء الخاص بتعريفها .
عبارة return
تتقبل الدالة lbstokg() الوزن بالأرطال وتخزنه في المتغير pounds , وتحسب قيمته بالكيلو جرامات ثم تخزن الناتج في المتغير kilograms , وبعد ذلك تعيد الناتج إلي الدالة المستدعيه بالأمر :
Return kilograms;
وعند إرسال القيمة للدالة المستدعية , تخزن في المتغير kgs الخاص بها . معني ذلك أن الدالة المستدعيه لا علاقة لها بالمتغير الخاص بالدالة الفرعية (kilograms) , فكل ما يعنيها هو القيمة المرتجعه منه . ويبين الشكل هذه العملية .
شكل إعادة القيم
وفي الوقت الذي يمكننا فيه إمرار أكثر من قيمة للدالة المستدعاه , فإن هذه الخيرة لا تستطيع أن تعيد إلا قيمة واحدة , هي ناتج العملية التي وضعت لها . ويمثل هذا قصورا في هذا الأسلوب من التعامل مع الدوال , وهناك أساليب أخري تمكن من إعادة أكثر من قيمة من دالة لأخري , منها الإمرار بواسطة الإشارة , والذي نتناوله بعد قليل :
ويجب علي الدوام تحديد طبيعة القيمة التي تعاد , وفي حالة عدم إعادة قيم تكتب الكلمة الحاكمة Void , أما إذا لم يتبع ذلك , فإن محول الصياغة سوف يعتبر القيمة المعادة من نوع العدد الصحيح , ولكن ليس من المستحسن الاعتماد علي ذلك , فيجب تحديد نوع القيمة حتي ولو كانت من هذا النوع , تيسيرا علي متتبعي البرنامج , وتمشيا مع العرف العام .
حذف متغيرات غير مطلوبة
في البرنامج المعروض أدرجنا عددا من المتغيرات أكثر مما هو مطلوب حقا وقد كان ذلك لغرض زيادة الإيضاح , والأن سوف نستدرك ذلك .
سوف تعدل صياغة البرنامج , لتبين كيف يوفر استخدام التعابير من الاسراف في استخدام المتغيرات .
convert2.cpp
// convert2.cpp// eliminates unnecessary variables#include <iostream.h>
#include <conio.h>
float lbstokg(float);
void main() { float lbs; cout << "\nEnter your weight in pounds: ";cin >> lbs;
cout << "Your weight in kilograms is " << lbstokg(lbs);getche();
}
// lbstokg()// converts pounds to kilogramsfloat lbstokg(float pounds)
{ return 0.453592 * pounds;}
لقد استغنينا عن المتغير kgs في الدالة الرئيسية , مكتفين بأن ندخل التعبير الخاص بإستدعاء الدالة libstokg(lbs) في أمرالإظهار مباشرة , حيث سوف تعيد الإجابة فيه . كما استغنينا عن المتغير kolograms في الدالة الفرعية , وقد حل محله تعبير التحويل من الأرطال للكيلو جرامات , متضمنا في أمر الإرجاع return مباشرة .
ومحترفي برمجة السي يفضلون هذا الإيجاز علي الصيغ المفصلة , حتي ولو كان ذلك علي حساب وضوح الصياغة .
ويجري العرف أيضا بين المبرمجين علي إحاطة تعبير إعادة القيم بقوسين , علي النحو التالي :
Return (0.453592 * pounds);
ورغم كون القوسين غير مطلوبين لمحول الصياغة , فإن وجود عدد زائد من الأقواس يؤدي لوضوح الصياغة .
وعلي العموم فإن مقابلة الوضوح بالإيجاز أمر متعلق بالتفضيل الشخصي للأسلوب , ويعتمد علي مدي تمكن الشخص , وتقديره لمستوي المتعاملين مع البرنامج فيما بعد .
إعادة متغير هيكلي
رأينا أن الهيكل يمكن أن يمثل معاملا يرسل من دالة أخري , وهو أيضا يمكن أن يستخدم كقيمة معادة من دالة مستدعية لها . وإليك برنامج retstrc يتضمن دالة فرعية addengl() مهمتها أن تجمع هيكلين . ثم تعيد النتيجة علي هيئة هيكل , كما يتضمن البرنامج دالة ثابتة لا تعيد قيما , حيث إن مهمتها إظهار الهياكل .
retstrc.cpp
// retstrc.cpp// demonstrates returning a structure// UCS Laboratories#include <iostream.h>
#include <conio.h>
struct Distance // English distance
{ int feet; float inches;};
Distance addengl(Distance, Distance); // declarationsvoid engldisp(Distance);void main() { Distance d1, d2, d3; // define three lengths // get length d1 from user cout << "\nEnter feet: "; cin >> d1.feet; cout << "Enter inches: "; cin >> d1.inches; // get length d2 from user cout << "\nEnter feet: "; cin >> d2.feet; cout << "Enter inches: "; cin >> d2.inches; d3 = addengl(d1, d2); // d3 is sum of d1 and d2engldisp(d1); cout << " + "; // display all lengths
engldisp(d2); cout << " = "; engldisp(d3); cout << "\n";getche();
}
// addengl()// adds two structures of type Distance, returns sumDistance addengl( Distance dd1, Distance dd2 )
{ Distance dd3; // define a new structure for sum dd3.inches = dd1.inches + dd2.inches; // add the inches dd3.feet = 0; // (for possible carry)if(dd3.inches >= 12.0) // if inches >= 12.0,
{ // then decrease inches dd3.inches -= 12.0; // by 12.0 and dd3.feet++; // increase feet } // by 1 dd3.feet += dd1.feet + dd2.feet; // add the feetreturn dd3; // return structure
}
// engldisp()// display structure of type Distance in feet and inchesvoid engldisp( Distance dd ) {cout << dd.feet << "\'-" << dd.inches << "\"";
}
وإليك مثالا للحوار بين البرنامج والمستخدم :
Enter feet: 4
Enter inches: 5.5
Enter feet: 5
Enter inches: 6.5
4'-5.5'' + 5 6.5'' = 10''
تقوم الدالة الأصلية بإجراء عملية جمع الهيكلين باستدعاء دالة الجمع addengl() لتقوم بذلك , وذلك بالأمر :
D3 = addengl(dl, d2 );
وهذه الدالة الأخيرة لها متغير خاص هو dd3 لتضع فيها حاصل الجمع , ثم تعيد النتيجة لتخصص للمتغير d3 في الدالة الأصلية . وقد احتاجت دالة الجمع للمتغير dd3 حيث لا يصح أن تعيد الدالة تعبيرا مثل :
Return dd2 + dd3
حيث إن عملية جمع الهيكلين تحتاج لسبع خطوات
تعليقات
إرسال تعليق