شما میدونین اندازهی int، short و long توی سی/سی++ چقدره؟!! من تا همین چند روز پیش فکر میکردم میدونم ولی فهمیدم که نمیدونم!
خیلی از کسایی که توی کامپایلرهای تحت داس سی یاد میگیرن و به حرف استاداشون زیادی اعتماد میکنن فکر میکنن int دو بایتیه! اونهایی هم که شانس دارن و استادشون یکمی بهروز تره و تحت ویندوز برنامهنویسی یاد میگیرن فکر میکنن اندازش ۴ بایتیه...
من براساس چیزایی که قدیما خونده بودم این توی ذهنم بود که اندازهی short و long تقریبا همهجا ثابته و ۱۶ و ۳۲ بیته، اما int کاملا وابسته به سیستمه (در واقع وابسته به کامپایلر) و اندازش با اندازهی واحد محاسباتی cpu (معمولا رجیسترهای عدد صحیح cpu) یکیه. در نتیجه انتظاری که داشتم این بود که توی سیستم ۶۴ بیتی و با یه کامپایلر ۶۴بیتی، اندازهی int هشت بایت باشه (و به طرز مسخرهای از long بزرگتر باشه!). همون چند روز پیش داشتم روی یه کد کارمیکردم که خلاصه یهو متوجه شدم که intم ۴ بایتیه (با این که توی یه لینوکس ۶۴ بیتی بودم). این شد که فهمیدم ای دل غافل! ظاهرا بحث اندازهی این متغیرها به این سادگیها هم نیست. خلاصه بعد از یه چرخی توی اینترنت و به کمک ویکیپدیا و این صفحه (که مزایای سیستم LP64 رو توضیح میده) اطلاعات کاملتری بهدستم رسید به این شرح:
۱. تنها چیزی که استاندارد سی مشخص کرده اینه (این ابهام با توجه به ملاحظاتی صورت گرفته!): اندازهی short حداقل ۲ بایته و از int بزرگ تر نیست، اندازهی int هم از long بزرگتر نیست. اندازهی long حداقل ۳۲بیت و اندازهی long long هم حداقل ۶۴ بیته. همین! مثلا ممکنه توی یه سیستم هر ۴ تای اینا ۶۴ بیتی باشن یا حتی بیشتر.
۲. توی سیستمهای ۶۴ بیتی مدلهای مختلفی استفاده شده. توی ویژوال سی ویندوز اندازهی اون سه نوع اصلی با سیستمهای ۳۲ بیتی یکیه، یعنی short دو بایت و اون ۲تای دیگه ۴ بایتند. برای ۶۴ بیت باید از long long استفاده کرد. البته اشارهگر ها ۸بایتی هستند توی ۶۴بیتیها کلا. این میشه مدل LLP64
توی لینوکس و خیلی از یونیکسها (کامپایلرهاشون) از مدل LP64 استفاده میکنند: short دو بایت، int چهار بایت و long هشت بایت.
یه مدل ILP64 هست که توی اون int و دادههای بزرگتر همه ۸ بایتی هستند. و یه مدل SILP64 که توش حتی short هم ۶۴ بیتیه.
خلاصه توی هیچ کدوم از سیستمهای ۶۴ بیتی که من فعلا ممکنه باهاشون سروکار داشته باشم int هشت بایتی نیست! با توجه به این که زمان زیادی در اشتباه به سر میبردم گفتم بزنم شاید برای بقیه هم خوب باشه!!
البته کلا اگه اندازه مهمه، بهترین راه استفاده از انواع تعریفشده توی stdint.hه مثل int32_t که داده با اندازهی دقیق میده، یا int_least32_t که کوچکترین داده که حداقل ظرفیت ذکر شده رو داره میده و یا int_fast32_t که سریعترین نوعی که به عقلش میرسه با حداقل اندازه ی گفته شده رو میده. برای ذخیرهی اشاره گر ها هم توی یه متغیر عددی باید از intptr_t استفاده کرد.
خیلی از کسایی که توی کامپایلرهای تحت داس سی یاد میگیرن و به حرف استاداشون زیادی اعتماد میکنن فکر میکنن int دو بایتیه! اونهایی هم که شانس دارن و استادشون یکمی بهروز تره و تحت ویندوز برنامهنویسی یاد میگیرن فکر میکنن اندازش ۴ بایتیه...
من براساس چیزایی که قدیما خونده بودم این توی ذهنم بود که اندازهی short و long تقریبا همهجا ثابته و ۱۶ و ۳۲ بیته، اما int کاملا وابسته به سیستمه (در واقع وابسته به کامپایلر) و اندازش با اندازهی واحد محاسباتی cpu (معمولا رجیسترهای عدد صحیح cpu) یکیه. در نتیجه انتظاری که داشتم این بود که توی سیستم ۶۴ بیتی و با یه کامپایلر ۶۴بیتی، اندازهی int هشت بایت باشه (و به طرز مسخرهای از long بزرگتر باشه!). همون چند روز پیش داشتم روی یه کد کارمیکردم که خلاصه یهو متوجه شدم که intم ۴ بایتیه (با این که توی یه لینوکس ۶۴ بیتی بودم). این شد که فهمیدم ای دل غافل! ظاهرا بحث اندازهی این متغیرها به این سادگیها هم نیست. خلاصه بعد از یه چرخی توی اینترنت و به کمک ویکیپدیا و این صفحه (که مزایای سیستم LP64 رو توضیح میده) اطلاعات کاملتری بهدستم رسید به این شرح:
۱. تنها چیزی که استاندارد سی مشخص کرده اینه (این ابهام با توجه به ملاحظاتی صورت گرفته!): اندازهی short حداقل ۲ بایته و از int بزرگ تر نیست، اندازهی int هم از long بزرگتر نیست. اندازهی long حداقل ۳۲بیت و اندازهی long long هم حداقل ۶۴ بیته. همین! مثلا ممکنه توی یه سیستم هر ۴ تای اینا ۶۴ بیتی باشن یا حتی بیشتر.
۲. توی سیستمهای ۶۴ بیتی مدلهای مختلفی استفاده شده. توی ویژوال سی ویندوز اندازهی اون سه نوع اصلی با سیستمهای ۳۲ بیتی یکیه، یعنی short دو بایت و اون ۲تای دیگه ۴ بایتند. برای ۶۴ بیت باید از long long استفاده کرد. البته اشارهگر ها ۸بایتی هستند توی ۶۴بیتیها کلا. این میشه مدل LLP64
توی لینوکس و خیلی از یونیکسها (کامپایلرهاشون) از مدل LP64 استفاده میکنند: short دو بایت، int چهار بایت و long هشت بایت.
یه مدل ILP64 هست که توی اون int و دادههای بزرگتر همه ۸ بایتی هستند. و یه مدل SILP64 که توش حتی short هم ۶۴ بیتیه.
خلاصه توی هیچ کدوم از سیستمهای ۶۴ بیتی که من فعلا ممکنه باهاشون سروکار داشته باشم int هشت بایتی نیست! با توجه به این که زمان زیادی در اشتباه به سر میبردم گفتم بزنم شاید برای بقیه هم خوب باشه!!
البته کلا اگه اندازه مهمه، بهترین راه استفاده از انواع تعریفشده توی stdint.hه مثل int32_t که داده با اندازهی دقیق میده، یا int_least32_t که کوچکترین داده که حداقل ظرفیت ذکر شده رو داره میده و یا int_fast32_t که سریعترین نوعی که به عقلش میرسه با حداقل اندازه ی گفته شده رو میده. برای ذخیرهی اشاره گر ها هم توی یه متغیر عددی باید از intptr_t استفاده کرد.
عجب!
پاسخحذفواسه اين پستها آدم نميدونه چي بگه چون تو حرفش نيست:)پس سال نوتون مبارك:)))))
پاسخحذفسروش: والا! :)
پاسخحذفخانم ترکش: !! خب منم سال نو شما هم مبارک!
خوب من كلا نمي دونستم شما اينقدر محققيد
پاسخحذفپس آفرين
اما كاش يا همه رو به بيت ميگفتيد يا به بايت
ما محاسباتمون ضعيفه
دستتون درد نکنه
پاسخحذفازونجائیکه ما در کل اهل تحقیق و این بحثا نیستیم، اطلاعاتمون اینجا بیش از حد مورد انتظار شما بالا میره:دی ممنون
سال نو هم مبارک
par: :) خب دیگه این پستا کمک میکنه که محاسباتتون قوی بشه D:
پاسخحذفدختر بهار: :) سال نو شما هم مبارک!
به قول سروش، عجب!!
پاسخحذفو به قول دختر بهار، سال نو مبارک ;)
نظریه ها اگه مثل قول ها نباشه خوبه :)
پاسخحذفجالب بود
پاسخحذفایشال خدا عوضت کنه جون
نه ببخشید ایشالا خدا عوضت بده :)
:) ممنون، هر دو لطف دارین!!
پاسخحذف