انواع داده در سی
در زبان برنامه‌نویسی سی، انواع داده اشاره به یک سیستم گسترده و وسیع برای اعلان متغیرها از انواع مختلف دارد. خود زبان سی تنها چند نوع داده ساده محاسباتی و قواعدی برای ایجاد آرایه‌ها و داده‌های ترکیبی ارائه می‌دهد. چند فایل هدر در کتابخانه استاندارد سی دربرگیرنده نوع داده‌های بیشتری، با ویژگی‌های بیشتر مانند اندازه دقیق تضمین شده هستند.
زبان سی تعدادی زیادی نوع داده پایه‌ای ارائه می‌دهد. خیلی از این نوع داده‌ها از ترکیب انواع محاسباتی ساده (مانند عدد صحیح، کاراکتری، ممیز شناور) به همراه تعدادی اصلاح‌کننده (short, long, signed, unsigned) تشکیل می‌شوند. تمام این انواع داده در جدول زیر آورده شده‌است:
نوع بولی (درست/نادرست) به صورت _Bool اعلان می‌شود. در فایل هدر stdbool.h هم چند شناسه مفید به عنوان ماکرو برای کار با مقادیر بولی تعریف شده‌است. در این هدر ماکرویی به نام bool از نوع _Bool تعریف شده‌است. true به عنوان ۱ تعریف شده‌است. false هم به صورت ۰ تعریف شده‌است. به علاوه __bool_true_false_are_defined هم به صورت ۱ تعریف شده‌است. نوع _Bool و هدر stdbool.h در استانداردهای ماقبل C99 وجود نداشتند.
زبان سی برای نمایش دادن کمیت‌های مرتبط با حافظه از انواع size_t و ptrdiff_t استفاده می‌کند. انواع داده موجود غیر کافی دانسته می‌شد، زیرا اندازه آن‌ها بر طبق قابلیت‌های محاسباتی پردازنده مقصد تعریف می‌شد، نه بر اساس قابلیت‌های حافظه، مانند فضای آدرس موجود. هر دو نوع size_t و ptrdiff_t در فایل stddef.h تعریف شده‌اند.
size_t برای نمایش اندازه هر گونه شیئی به کار می‌رود. حتی برای نمایش اندازه آرایه‌ها. از نوع size_t به عنوان مقدار برگشتی عملگر sizeof استفاده می‌شود. بیشترین مقداری که یک متغیر از نوع size_t می‌تواند داشته باشد در ماکرویی به نام SIZE_MAX تعریف شده‌است. این ماکرو در فایل stdint.h تعریف شده‌است. توجه داشته باشید که size_t یک نوع داده بدون علامت است. برای اندازه‌های علامت‌دار نوع ssize_t در نظر گرفته شده‌است.
ptrdiff_t هم برای نمایش تفاوت میان اشاره‌گرها استفاده می‌شود.
اطلاعات مربوط به ویژگی‌های واقعی هر نوع داده به صورت ماکروهایی در فایل‌های limits.h و float.h تعریف شده‌اند. limits.h دربرگیرنده ماکروهایی برای انواع عدد صحیح و float.h دربرگیرنده ماکروهای مربوط به انواع ممیز شناور است. مقادیر واقعی این ماکروها وابسته به پیاده‌سازی است.
CHAR_BIT - اندازه نوع char بر حسب بیت (حداقل ۸ بیت)
SCHAR_MIN, SHRT_MIN و INT_MIN, LONG_MIN, LLONG_MIN - کوچکترین مقدار ممکن برای انواع عدد صحیح علامت دار:signed char, signed short, signed int, signed long, signed long long
SCHAR_MAX, SHRT_MAX, INT_MAX, LONG_MAX, LLONG_MAX - بیشترین مقدار ممکن برای انواع عدد صحیح علامت‌دار: signed char, signed short, signed int, signed long, signed long long
UCHAR_MAX, USHRT_MAX, UINT_MAX, ULONG_MAX, ULLONG_MAX - بیشترین مقدار ممکن برای انواع عدد صحیح بدون علامت
CHAR_MIN کوچکترین مقدار ممکن برای نوع char
CHAR_MAX - بیشترین مقدار ممکن برای نوع char
MB_LEN_MAX – بیشترین تعداد بایتها در یک کاراکتر چندبایتی
ساختار یک نوع داده ترکیبی است. ساختارها روشی برای ذخیره کردن چندین قلم داده در یک نوع متغیر هستند. برای مثال فرض کنید ما می‌خواهیم نام و تاریخ تولد یک شخص را در یک متغیر به صورت رشته ذخیره کنیم. برای ذخیره آن اطلاعات می‌توانیم از یک ساختار به شکل زیر استفاده کنیم: struct birthday
ساختارها می‌توانند دربرگیرنده اشاره‌گری به یک ساختار از نوع خودشان باشند. اینگونه ساختارها در طراحی لیست‌های پیوندی بسیار متداول هستند. همچنین هر ساختار می‌تواند دربرگیرنده ساختاری از نوع دیگر باشد.
برای هر نوع "T"، به جز نوع void و تابع، یک نوع داده به شکل «آرایه‌ای متشکل از "N" عنصر از نوع "T"» وجود دارد. یک آرایه مجموعه‌ای از مقادیر است که همه این مقادیر از یک نوع هستند و به صورت پشت سر هم در حافظه ذخیره شده‌اند. آرایه‌ای با اندازه N، دارای اندیس‌هایی با شماره 0 تا N-1 است.
هم چنین آرایه‌هایی هم وجود دارد که تعداد عناصر آن‌ها برای کامپایلر نامعلوم است. به عنوان مثال:
int cat[10]; // array of 10 elements, each of type int int bob[]; // array of an unspecified number of 'int' elements. می‌توان آرایه‌ها را در زمان اعلان مقداردهی هم کرد. برای ارسال یک آرایه به یک تابع، می‌توان اشاره‌گری به اولین عنصر آرایه را به تابع ارسال کرد. می‌توانند چند بعدی هم باشند.
int a[10][8]; // array of 10 elements, each of type 'array of 8 int elements' float f[][32]; // array of unspecified number of 'array of 32 float elements' برای هر نوع "T"، «اشاره‌گری از نوع "T" وجود دارد»
اشاره گر متغیری است که آدرس یک شی دیگر را نگه میدارد. آن‌ها مانند متغیرهای معمولی اعلان می‌شوند با این تفاوت که قبل از نام آن‌ها باید کاراکتر * قرار گیرد. مثل:
char *square; long *circle; اشاره‌گرها می‌توانند چند سطحی باشند. می‌توان اشاره‌گری به یک اشاره‌گر دیگر تعریف کرد. مثلاً int** اشاره‌گری به نوع int* است. همچنین «اشاره‌گر به آرایه» هم وجود دارد. اما آن‌ها نسبت به «آرایه‌ای از اشاره‌گرها» کمتر رایج هستند.
char *pc[10]; // array of 10 elements of 'pointer to char' char (*pa)[10]; // pointer to a 10-element array of char