السلام عليكم و رحمة الله و بركاته :-
قد تلاحظ كثيرا و أنت تستخدم مكتبات سي القياسية ، أن بعض الوظائف ليس محدد لها عدد معين من الوسطاء ، أي يمكنك أن تستدعيها مع أي عدد ممكن من الوسطاء من عدد 1 إلى ما لا نهاية من الوسطاء ..... ، و المثال التالي خير شاهد على ذلك :-
printf("%d %d %d .......n" , var1 , var2 , var3 );حيث تتيح لك لغة سي ذلك بواسطة طريقة معينة في التصريح عن الوظائف ، و تتيح أيضا عدد من المايكروهات للتعامل مع المتغيرات التي تمررها إلى الوظيفة . و نحن اليوم سوف نصرح عن وظيفتين تجمع العناصر التي ممررها إليهما بشرط أن يكون آخر عدد يرر إليهما هو -1 لكي يعلم الوظيفة أنه إلى هنا قد أنتهى عدد الوسطاء . الأولى سوف ننفذها بدون مايكروهات ، لكي نفهم ماذا يجري وراء الكواليس ....... و الثانية سوف ننفذها عنطريق الماكروهات التي تتيحها لغة سي القياسية . و فيما يلي شرح لما يجب علينا فعله لكي ننفذ هذا النوع من الوظائف .
أولا :- أن يكون إعلان الوظيفة علىالشكل التالي ....
type MyFunc(type first , ... ) ;
حيث أن كلمة type أعني بها النوع التي تريد من الوظيفة أن تتعامل معه . أما النقاط فهو يعني أنه سوف يتم تمرير عدد غير معين من النوع type إلى الوظيفة .
ثانيا :- التعامل مع الوسطاء ، سوف يتم وضع الوسطاء في الذاكرة مرتبين بحسب تمريرهم إلى الوظيفة و يكون أول وسيط هو first هذا يعني أنه مجرد الحصول على مؤشر عليه فإن الوصول إلى باقي الوسطاء أمر يسير .
و فيما يلي مثال بسيط ......
#include <stdarg.h>
#include <iostream.h>
int MyFunc1(int first , ... )
{
int sum = 0;
int * marker = 0; // create a pointer
marker = &first; // make it points to the first number
for (int x = 0 ; marker[x] != -1 ; x++)
sum += marker[x];
marker = 0; // // make it points to NULL
return sum;
}
int MyFunc2(int first , ... )
{
int sum = 0, i = first;
va_list marker; // create a pointer
va_start( marker, first );
// make it points to the first number
while( i != -1 )
{
sum += i;
i = va_arg( marker, int);
// make it points to the next number
}
va_end( marker ); // make it points to NULL
return sum ;
}
void main () {
cout << "The result of MyFunc1 is " <<
MyFunc1(1,2,3,4,5,6,7,8,9, -1) << endl;
cout << "The result of MyFunc2 is " <<
MyFunc2(1,2,3,4,5,6,7,8,9, -1) << endl;
}ملاحظة :- قد ترى أن الوظيفة الأولى قد قامت من المطلوب و ليس هناك حاجة إلى الماكروهات التي تبدأ بـ va_ ، و هذا خاطئ فالماكروهات هذه مكتوبة بطريقة يمكنها أن تعمل أي مصرف و أي معالج و مع أي نوع من الأنواع البسيطة . و قد كتبت الوظيفة الأولى لكي أبين الفكرة التي تعمل عليها هذه الماكروهات و ليس لكي يتم الإستغناء عنها .
تحياتي ............