دورد
بازگشت گودزيلا
فکر نمی کردم انقدر بشه اما يه غيبت طولانی شد. به هر حال اميدوارم ديگه پيش نياد!!
--------------------------------------------------------
اما بعد...
داشتم فکر می کردم با چی شروع کنم که ياد (...) يا همون Ellipsis افتادم. شايد ديده باشيد که ازش توی برنامه نويسی استفاده کرده باشن و شايد هم به احتمال زياد اصلا نديده باشيد که خوب يه جورايی طبيعی هستش٬ چون کاربرد رايجی نداره و کمتر استفاده ميشه.
(...) رو اصطلاحا ميگن Ellipsis .
کجا ها کاربرد داره ؟
- جاهايی که نمی خوان محدوديتی در تعداد و نوع پارامترهای پاس شده باشه!
مثلا تابع printf رو در نظر بگيريد که يک رشته ورودی بهش پاس می کنيد که می تونه علاوه بر اين رشته٬ يک سری پارامتر دلخواه با هر نوع ممکن رو که دوست داريد در محلی که در رشته مشخص کرديد چاپ بشه٬ رو هم می تونيد به عنوان ورودی بهش پاس کنيد يا نکنيد.
شايد بگيد خب که چی؟!؟!
- اگه يکم دقت کنيد می بينيد که توی تعريف تابع بايد نام و نوع ورودی ها کاملا مشخص و معتبر باشه و تعداد نامحدود عملا نمی تونه داشته باشه!! پس چطوری تابعی مثل printf بنويسيم؟؟
اينجاست که Ellipsis ضرورت پيدا ميکنه.
حالا چطوری استفاده ميشه ؟
- خيلی ساده!
شکل کلی تعريف تابع با استفاده از Ellipsis به شکل زير هستش:void MyFunction(int x,...);
البته اين يک نمونه مثال هستش. به کمک x که قبل از ... اومده به آدرس اولين متغيير بعدی پاس شده به تابع بر روی stack دسترسی خواهيم داشت٬ اما اين اصلا ربط مستقيم به نوع و مقدار x نداره و کامپايلر از اين تنها برای دسترسی به متغيير های بعدی استفاده می کنه که اصطلاحا Variable Argument می گن.
ابتدا بايد يک متغيير از نوع va_list تعريف کنيد. بعد بايد از تابع va_start به شکل زير استفاده کنيد:
va_list vl;
va_start( vl, &x);
حالا از طريق متغيير vl به متغييرهای پاس شده دسترسی خواهيد داشت٬ مثلا به شکل زير:
double d;
d = va_arg( vl, double );
خط بالا اولين متغيير رو که فرض کردم double هستش بر می گردونه و برای متغييرهای احتمالی بعدی به همين شکل ادامه پيدا می کنه.
در پايان استفاده بايد تابع va_end رو صدا بزنيد :
va_end( vl );
حالا ديگه به چه شکل دوست داريد استفاده کنید با خودتونه!
اميدوارم به دردتون بخوره!
موفق باشيد