إعادة القيم من الدالة في ++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 kilograms
float 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 kilograms
float 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); // declarations
void 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 d2
engldisp(d1); cout << " + "; // display all lengths
engldisp(d2); cout << " = ";
engldisp(d3); cout << "\n";
getche();
}
// addengl()
// adds two structures of type Distance, returns sum
Distance 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 feet
return dd3; // return structure
}
// engldisp()
// display structure of type Distance in feet and inches
void 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
حيث إن عملية جمع الهيكلين تحتاج لسبع خطوات
تعليقات
إرسال تعليق