۱۳۸۹ فروردین ۷, شنبه

اندازه‌ی int در سی/سی++!

شما میدونین اندازه‌ی 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 استفاده کرد.

۱۱ نظر:

  1. واسه اين پستها آدم نميدونه چي بگه چون تو حرفش نيست:)پس سال نوتون مبارك:)))))

    پاسخحذف
  2. سروش: والا! :)
    خانم ترکش: !! خب منم سال نو شما هم مبارک!

    پاسخحذف
  3. خوب من كلا نمي دونستم شما اينقدر محققيد

    پس آفرين


    اما كاش يا همه رو به بيت ميگفتيد يا به بايت

    ما محاسباتمون ضعيفه

    پاسخحذف
  4. دستتون درد نکنه
    ازونجائیکه ما در کل اهل تحقیق و این بحثا نیستیم، اطلاعاتمون اینجا بیش از حد مورد انتظار شما بالا میره:دی ممنون
    سال نو هم مبارک

    پاسخحذف
  5. par: :) خب دیگه این پستا کمک میکنه که محاسباتتون قوی بشه D:

    دختر بهار: :) سال نو شما هم مبارک!

    پاسخحذف
  6. به قول سروش، عجب!!
    و به قول دختر بهار، سال نو مبارک ;)

    پاسخحذف
  7. نظریه ها اگه مثل قول ها نباشه خوبه :)

    پاسخحذف
  8. جالب بود
    ایشال خدا عوضت کنه جون
    نه ببخشید ایشالا خدا عوضت بده :)

    پاسخحذف