تا قبل از سال ۱۹۹۴، زندگی برای برنامهنویسهای C و ++C خیلی سخت میگذشت. اونها رو در حالی تصور کنین که زیر فشارِ درک و خوندن چیزی مثل :
char (*fp)(int, float *);
بودند. مثلا از خودشون میپرسیدن که خب حالا fp چیه ؟!!! اینجا بود که هزار تیرزهرآگین در قلبشون فرو میرفت. آخ بیچاره برنامه نویسهای C و ++C ... (یک دقیقه سکوت)
زندگی همینجور داشت بر برنامهنویسهای C و ++C سخت میگذشت تا این که سال ۱۹۹۴ اومد. خب این عدد چه معنی خاصی داره؟ مثلا بیاین ۹ رو با ۱ جمع کنیم میشه ۱۰ بعد با اون یکی ۹ جمع کنیم میشه ۱۹ که با ۴ جمع بشه میشه ... امم مثل این که به چیزی نرسیدیم. خب این عدد برا ما هیچ معنی خاصی نداره. ولی برای برنامهنویسهای C و ++C این یک عدد مقدسه. چرا که David Anderson در این سال بود که متد Clockwise/Spiral رو معرفی کرد و بالاخره بعد از سالها چهره درهم برنامهنویس های C و ++C رو به چیزی شبیه ? تغییر داد. بالاخره این زندگی ارزش این همه سختی رو نداره ... بیاین ببینیم آقای اندرسون، این ناجی افسانه ای که بود و چه کرد ... خب بیاین از یه چیز ساده شروع کنیم. اول این مثال رو در نظر بگیرین :
int *ptr;
خب اینجا ما اگه از خودمون بپرسیم که ptr چیه خیلی ساده میگیم که : "ptr یک اشاره گر به نوع int است"
خب تا اینجا ساده است. بیاین یکم سخت ترش کنیم. مثال پایین کمی سخت تره:
chat *str[5];
اینجا اگه از خودمون بپرسیم str چیه جوابی که میدیم اینه : "str یک آرایه با سایز ۵ است که اشاره میکند به نوع char" خب اینم آسون بود. حالا اینو شما بگین که همون مثالی هستش که اول گفتیم. پرسش اینه که fp چیه ؟
char *(*fp)(int, float *);
خب ... قبل این که ادامه متن رو بخونین سعی کنین خودتون اینو به فارسی توضیح بدین مثل کاری که با دو مثال قبلی کردیم.
اگه برنامه نویس نسبتا حرفهای C یا ++C بودین و تونستین مثال بالا رو هم جواب بدین، پس اینو هم لطفا به همون صورت توضیح بدین. اینجا پرسش اینه که f چیه ؟
string(const* f(int, void (*const p)(int)))(char[]);
خب اعتراف کنین که گفتن پاسخ سوال f چیه سخته. و گیج کننده است. ولی با متد "ساختار حلزونی در جهت عقربههای ساعت" ( یکم اسمش عجیبه ولی به زودی میفهمین دلیل نام گذاریش چیه) این کار دیگه سخت نیست.
اول بیاین چندتا قرارداد با هم ببندیم :
۱ - هر جا که با [x] یا [] روبهرو شدیم اونو به عبارت فارسی : "آرایهای با سایز x ... آرایهای با سایز تعریف نشده" تبدیل میکنیم
۲ - هرجا که با ) یعنی پرانتز باز روبهرو شدیم که حتما داخلش آرگومان های تابع هست مثل مثلا (int b, int a ) ما اونو به این عبارت تبدیل میکنیم : "تابعی که به آن b از نوع int و a از نوع int پاس داده میشود، و بر میگرداند ..."
۳ - اگه با * روبهرو شدیم اونو به عبارت : "اشاره گری به ..." تبدیل میکنیم.
۴ - اگر با ( یعنی پرانتز بسته روبهرو بشیم باید کارمون رو با عناصر داخل پرانتز ادامه دهیم. نگران نباشین اگه اینا رو متوجه نمیشین در ادامه متوجه میشیم.
۵ - کارمون رو تا وقتی ادامه میدیم که با همه عنصرها رو به رو شده باشیم.
۵ - اگر با ; رو به رو بشیم در حالی که هنوز عنصر دیگهای بوده که باهاش مواجهه نشدیم پس هنوز کارمون تموم نشده و در همون جهت عقربههای ساعت ادامه میدیم.
خب کاری که میکنیم اینه. با مثال دوم شروع میکنیم.
char *str[5];
از خودمون میپرسیم مثلا str چیه؟ جواب اینه : str یک ... خب تا اینجا رو داشته باشین.
از str شروع کنین یه ساختار حلزون مانند در جهت عقربه های ساعت بکشین. مثل پایین :
خب میبینیم که اول با ] رو به رو شدیم. پس یک آرایه است. جوابمون رو اینجور اصلا میکنیم(طبق قرار دادهامون) :
"امم str یک آرایه با سایز ۵ است که ..."
خب اگه مارپیچ رو دوباره نگاه کنین میبینیم که با * مواجه شدیم. پس جوابمون رو اینجوری اصلاح میکنیم :
"امم str یک آرایه با سایز ۵ است که اشاره میکند به ..."
حالا میبینیم که با ; مواجهه شدیم ولی هنوز عنصری هست که باهاش مواجه نشدیم( char ) پس طبق قرار دادی که بالاتر با هم داشتیم هنوز کارو باید ادامه داد. خب میبینیم که با char مواجه شدیم. جوابمون رو به صورت زیر اصلاح میکنیم.
"امم str یک آرایه با سایز ۵ است که اشاره میکند به نوع char"
خب میبینیم که با همه عناصر از جمله ; هم مواجهه شدیم پس کارمون تمومه و سوال و جواب نهاییش اینه :
بهم بگو str تو عبارت بالا چیه ؟
- امم str یک آرایه با سایز ۵ است که اشاره میکند به نوع char
آفرین هوراااا ...
خب حالا فرض کنین با این رو به رو هستیم :
char *(*fp)(int, float *);
از خودمون میپرسیم که مثلا fp چیه؟ خب حواب ما فعلا اینه :
"امم fp یک ..."
مارپیچ رو نگاه کنین. از fp شروع کردیم در جهت عقربههای ساعت پیش میریم. به ( یعنی پرانتز بسته رسیدیم. پس باید طبق قرارداد بالا کار رو تو داخل پراتتز ادامه بدیم. پس اول میبینین که با * رو به رو شدیم. جواب ما تا اینجا به این صورت تغییر میکنه :
"امم fp یک اشارهگر به(اشاره میکند به) ..."
حالا تمام عناصر داخل پرانتز رو باهاش مواجه شدیم. حالا در جهت عقربه های ساعت باز مارپیچ رو ادامه میدیم و مواجه میشیم با ) طبق قرارداد بالا باید جملمون اینجور کنیم :
"امم fp یک اشارهگر به تابعی است که یک int و یک اشارهگر به float به آن پاس داده میشود، و برمیگرداند ..."
حالا مواجه میشیم با *. جملمون اینجوری میشه :
"امم fp یک اشارهگر به تابعی است که یک int و یک اشارهگر به float به آن پاس داده میشود، و برمیگرداند یک اشارهگر به ..."
در ادامه با ; رو به رو میشیم ولی چون هنوز با همه عناصر رو به رو نشدیم طبق قرار داد بالا باید ادامه بدیم. رو به رو میشیم با char. جملمون اینجور میشه :
"امم fp یک اشارهگر به تابعی است که یک int و یک اشارهگر به float به آن پاس داده میشود، و برمیگرداند یک اشارهگر به نوع chat"
با همه عناصر مواجه شدیم و کار تمومه ...