PDA

View Full Version : چرا تعداد پارامترهای ارسالی در تابع printf نامشخص هست؟



Layla.Download
چهارشنبه 17 خرداد 1391, 23:04 عصر
با درود بر دوستان

خواهش می کنم به سوال زیر پاسخ دهید (البته از دید طراحی زبان سی)

چرا تعداد پارامترهای ارسالی در تابع printf نامشخص هست؟
چطور امکان داره که هر تعداد پارامتر بخواهیم می توانیم ارسال کنیم، برعکس تابع printl در جاوا و تابع write در Ada.

سپاس

#target
جمعه 19 خرداد 1391, 23:02 عصر
تابع با حالت __cdecl هست
void __cdecl printf(char* format , ... )

توابع که به این صورت هستند . (پیش فرض در c ) امکان ارسال تعداد متغیری پارامتر را میدهند

ی نمونه از نحوه استفاده :

#include<iostream.h>
#include <stdarg.h>
int __cdecl test(int i , ...)
{
va_list OtherArgs;
va_start(OtherArgs,i);
float SecondArg = va_arg(OtherArgs,int);
char* ThirdArg = va_arg(OtherArgs,char*);
cout << SecondArg << " " << ThirdArg ;
return 0;
}
int main(){
test(12,67,"Test");
}
ی متغیر از نوع va_list تعریف میکنید با va_start اولین آرگومان یا شروع اونو مشخص میکنید بعد با va_arg هر بار ی آرگومان بعدی رو میگیرید !

حامد مصافی
جمعه 19 خرداد 1391, 23:04 عصر
کلی فکر کردم اما متوجه منظور شما نشدم. اما فکر کنم یکی از دو گزینه زیر باید باشه:


چرا طراحان زبان سی اینطوری طراحیش کردن؟
چطور می‌تونیم خودمون چنین تابعی ایجاد کنیم؟

لطفا کمی بیشتر توضیح بدید.

Layla.Download
شنبه 20 خرداد 1391, 09:03 صبح
دقیقا چرا اینطوری طراحی شده که printf می تواند هر چند تعداد پارامتر ارسالی را داشته باشه؟؟؟

#target
شنبه 20 خرداد 1391, 10:32 صبح
این برمیگرده به نحوه ارسال پارامتر ها به پشته و پاک سازی اون
در فراخوانی stdcall که تعداد پارامتر ها مشخصه وقت فراخوانی پارامترها وارد پشته میشه و اجرا به تابع انتقال داده میشه در نهایت کار تابع که تمام شد خود تابع به تعداد پارامترهایی که قرار بوده دریافت کنه پشته رو پاک میکنه (اشاره گر پشته رو کم میکنه)
اما در فراخوانی C وظیفه فراخوان تابع هست که پشته رو پاک کنه . یعنی وقت فراخوانی پارامترها وارد پشته میشن بعد تابع فراخوانی میشه بعد از اتمام کار تابع کنترل به جای فراخوان برمیگرده (تابع هیچ کاری با پشته نمیگیره) و خود فراخوان تابع بعد از فراخوانی میاد پشته رو به انداره ای که پارامتر واردش کرده پاکسازی میکنه . این به فراخوان امکان میده که تعداد متغیر پارامتر رو ارسال کنه چون خودش مسول پاک کردن اونا هست .

کدی هم که در پست قبلی نوشتم نحوه ساخ ت این توابع و دسترسی به پارامترهاست