الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

شرح استخدام دوال متعددة الوسائط va_list

بدأه the inventor habib في 21 يوليو 2012 · 6 رد · 1,711 مشاهدة · في المواضيع والدروس
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

إنَّ الحَمْدَ لِلَّهِ نَحْمَدُهُ وَنَسْتَعِيُنُهُ وَنَسْتَغْفِرُهُ وَنَسْتَهْدِيهِ وَنَعُوذَ بِاللهِ مِن شُرُورِ أَنفُسِنَا وَسَيئَاتِ أَعْمَاِلَنَا،

مَن يَهْدهِ اللهُ فَلا مُضلَّ لَه ، وَمَن يُضْلِل فَلا هَادِي لَه، وَأَشْهَدُ أَنَّ لاَ إِلهَ إلا اللهُ وَحدَهُ لاَ شَريكَ لَهُ،

وَأَشْهدُ أنَّ مُحَمَّداً عَبدُهُ وَرَسُولُهُ .

اليوم سوف أتتطرق الي طريقة استعمال تعدد البرامترات أو ما يسمي ب variable arguments

وسف ننشأ دالة جديدة تقوم بعمل الدالة printf

وسوف نعطيها في كل مرة أنواع من البرامترات

وسوف أشرح هده الدوال وأنواع

va_list

()va_start

()va_arg

()va_end

أولا ننشئ مشروع جديد ولا ننسي أن نستدعي الملف الراسي stdarg.h

وننشئ دالة من نوع void وأنا سميتها Myprintf

وأعطيتها برامتر الاول وهو فورمات المتغيرات المراد طباعتها متل d% ...


#include <stdio.h>
#include <stdarg.h>
void Myprintf(char *frmt,...)
{

}
main()
{
getchar();
return 0;
}
#include <stdlib.h>

تم نقوم بانشاء مغيرات جديدة :

Mylist وهي التي يخزن فيها البرامترات التي سوف نضعها عند استدعاء دالتنا الجدية...وهي من نوع va_list

value وهو الدي سوف يقوم بأخد قيمة الفورمات frmt وسوف يأخد حرف يحرف منه

cval:وهو المتغير الدي سيأخد قيمة البرامتر من نوع string الدي سنمرره في دالتنا

ival : وهو المتغير الدي سيأخد قيمة البرامتر من نوع int الدي سنمرره لها عند استدعاء دالتنا

ونفس الشي مع fval


#include <stdio.h>
#include <stdarg.h>
void Myprintf(char *frmt,...)
{
va_list Mylist;
char *value,cval;
int ival;
float fval;
}
main()
{
getchar();
return 0;
}
#include <stdlib.h>

تم نقوم باستدعاء دالة بدأ الحصول علي البرامترات ألا وهي va_start

التي تأخد برامرين واحد va_list والا خر هو أخر برامتر معروف لديانا وهو frmt

وتم نقوم بانهاء الحصول عليها باستعمال va_end


#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
void Myprintf(char *frmt,...)
{
va_list Mylist;
char *value,cval;
int ival;
float fval;
va_start(Mylist,frmt);

va_end();
}
main()
{
getchar();
return 0;
}

تم نقوم بالتكرار طالما value=frmtو نزيد في قيمة value ليشير دائما الحرف الموالي

وطالما قيمة value تخالف نهاية السلسلة \0


#include <stdio.h>
#include <stdarg.h>
void Myprintf(char *frmt,...)
{
va_list Mylist;
char *value,cval;
int ival;
float fval;
va_start(Mylist,frmt);
for(value=frmt;*value;value++)
{

}
va_end();
}
main()
{
getchar();
return 0;
}
#include <stdlib.h>

تم نقوم بوضع شرط ادا كان قيمة value ليست % يعني أننا نريد طباعة ما نريد

أعطيك متال عندما تكتب هكدا

printf("%d years old\n",18);

فهل يتم طباعة years old نعم ولكن لا يتم طباعة d%

لانها تشير الي 18 وهدا هو غرض هدا الشرط ادا كان قيمة value لا تشير الي برامتري ما فقم بطباعة دلك

وقم بقفز التالي وابدأ من جديد

continue


#include <stdio.h>
#include <stdarg.h>
void Myprintf(char *frmt,...)
{
va_list Mylist;
char *value,cval;
int ival;
float fval;
va_start(Mylist,frmt);
for(value=frmt;*value;value++)
{
if(*value!='%')
{
putchar(*value);
continue;
}
}
va_end();
}
main()
{
getchar();
return 0;
}
#include <stdlib.h>

تم نقوم بشروط أخي عن طريق أستخدام switch

وهده الشروط سوف تكون عبارة عن ادا كانت قيمة value*... تم نزيد قيمته في كل مرة لأخد الحرف الدي بعد %


#include <stdio.h>
#include <stdarg.h>
void Myprintf(char *frmt,...)
{
va_list Mylist;
char *value,cval;
int ival;
float fval;
va_start(Mylist,frmt);
for(value=frmt;*value;value++)
{
if(*value!='%')
{
putchar(*value);
continue;
}
switch(*++value)
{

}
}
va_end();
}
main()
{
getchar();
return 0;
}
#include <stdlib.h>

تم نقوم بمعالجة قيمة value ادا كانت i يعني int فقم وضع قيمة البرامتر التالي الدي هو من نوع int في المتغير ival

باستعمال الدالة va_arg

وقم بطباعته ونفس الشئ مع s و f

وادا كانت القيمة غير معروفة فقم فقط بطباعة قيمته default


#include <stdio.h>
#include <stdarg.h>
void Myprintf(char *frmt,...)
{
va_list Mylist;
char *value,cval;
int ival;
float fval;
va_start(Mylist,frmt);
for(value=frmt;*value;value++)
{
if(*value!='%')
{
putchar(*value);
continue;
}
switch(*++value)
{
case 's':
cval=va_arg(Mylist,char*);
puts(cval);
break;
case 'f':
fval=va_arg(Mylist,double);
printf("%f",fval);
break;
case 'i':
ival=va_arg(Mylist,int);
printf("%d",ival);
break;
default:
putchar(*value);
break;
}
}
va_end();
}
main()
{
getchar();
return 0;
}
#include <stdlib.h>

الان دعونا نجرب دالتنا الجديدة : نقوم بانشاء متغيرين من نوع string و int

تم نقوم بطباعتهما كما يلي:


#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
void Myprintf(char *frmt,...)
{
va_list Mylist;
char *value,cval;
int ival;
float fval;
va_start(Mylist,frmt);
for(value=frmt;*value;value++)
{
if(*value!='%')
{
putchar(*value);
continue;
}
switch(*++value)
{
case 's':
cval=va_arg(Mylist,char*);
puts(cval);
break;
case 'f':
fval=va_arg(Mylist,double);
printf("%f",fval);
break;
case 'i':
ival=va_arg(Mylist,int);
printf("%d",ival);
break;
default:
putchar(*value);
break;
}
}
va_end();
}
main()
{
int age=18;
char *str="Years old";
Myprintf("Hi I'm %i %s",age,str);
getchar();
return 0;
}

1
#2

أتمني أن تستفيد من هدا الدرس

#3

شكرا على الدرس أخي حبيب ، لما كل هذا التعقيد ...

يكفي أن تضيف هذا الماكرو فقط :lol:

#define Myprintf(x) printf(x)

أكرر شكري لك أخي الغالي ... :clapping:

rS3eY.png
#4

موضوع جميل, بارك الله فيك :)

فقط كملاحظة, تم تعريف va_list, va_start, va_arg et va_end على أنهم ماكرو و ليسوا دوال.

هذا الموضوع يستعرض مختلف الطرف التي يمكننا من خلالها كتابة دالة غير محدودة الوسائط.

تحياتي.

1
#5
اقتباس
موضوع جميل, بارك الله فيك :)

فقط كملاحظة, تم تعريف va_list, va_start, va_arg et va_end على أنهم ماكرو و ليسوا دوال.

هذا الموضوع يستعرض مختلف الطرف التي يمكننا من خلالها كتابة دالة غير محدودة الوسائط.

:cool:

#6

+1 مجهود مميز

post-15367-027053900%201340345097.gifpost-15367-087183200%201340344597.gif
post-247365-0-10080400-1379403554_thumb.

#7

السلام عليكم

اقتباس
يكفي أن تضيف هذا الماكرو فقط :lol:

hنعم بالطبع لكن المهم في الدرس هو تطبيقه في دالة أخري خاصة بك وليس دالة الكتابة من printf

اقتباس
+1 مجهود مميز

بارك الله فيك

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