أنواع البيانات في سي
أنواع البيانات في لغة سي تكون أنواع البيانات عبارة عن إعلانات لعنواين الذاكرة، أو المتغيرات، التي تحدد خصائص البيانات التي يمكن تخزينها وأساليب (العمليات) للمعالجة المسموح بها.
توفر لغة C أنواع حسابية أساسية، مثل أنواع الأعداد الصحيحة، والأعداد الرقمية ، وبناء جمل اللغة لبناء أنواع المصفوفات والمركبات . يوجد العديد من الرؤوس (ترويسة (حوسبة)) في مكتبة سي المعيارية التي تحتوي على تعريفات للأنواع المدعومة ، التي لها خصائص إضافية ، مثل توفير مساحة تخزين ذات حجم دقيق ، مستقلة عن التنفيذ.
توفر لغة السي أربعة أنواع أساسية من أنواع البيانات char الخاص برمز واحد و int الخاص بالأرقام الصحيحة و float الخاص بالأرقام العشرية و double الخاص بالأرقام العشرية الكبيرة ، ومعدلات موقعة signed وغير موقعة unsigned وقصيرة (short) وطويلة (long) . يسرد الجدول التالي المجموعات المسموح بها لتحديد مجموعة كبيرة من الإعلانات الخاصة بحجم التخزين.
يختلف الحجم الفعلي لأنواع الأعداد الصحيحة باختلاف التنفيذ. يتطلب المعيار فقط علاقات حجم بين أنواع البيانات والحد الأدنى من الأحجام لكل نوع من البيانات:
متطلبات العلاقة هي أن "طويلة طويلة" long long ليست أصغر من "طويلة" long ، وهي ليست أصغر من "الأعداد الصحيحة" int ، وهي ليست أصغر من "قصيرة" short . نظرًا لأن حجم char "الرمز" هو دومًا الحد الأدنى من نوع البيانات المدعومة ، فلا يمكن أن تكون أي أنواع بيانات أخرى (باستثناء حقول البتات) أصغر.
الحد الأدنى لحجم char هو 8 بت ، الحد الأدنى لحجم short والint هو 16 بت ، "long" هو 32 بت و "long long" يجب أن تحتوي على 64 بت على الأقل.
يجب أن يكون النوع int هو النوع الصحيح الذي يعمل به المعالج بشكل أكثر كفاءة. يتيح ذلك مرونة كبيرة: على سبيل المثال ، يمكن أن تكون جميع الأنواع 64 بت. ومع ذلك ، هناك العديد من أنظمة عرض عدد صحيح مختلفة (طرازات البيانات) شائعة. لأن نموذج البيانات يحدد كيفية توصيل البرامج المختلفة ، يتم استخدام نموذج بيانات موحد داخل واجهة تطبيق نظام التشغيل.
عملياً ، char عادةً ثمانية بت في الحجم و short عادةً 16 بت في الحجم (كما هي نظائرها غير الموقعة). ينطبق هذا على المنصات المتنوعة مثل التسعينات SunOS 4 Unix و Microsoft MS-DOS و Linux الحديثة و Microchip MCC18 للميكروكونترولر 8 بت. و POSIX يتطلب char أن يكون حجمها ثمانية بتات.
إن القواعد المختلفة في المعيار C تجعل "char" غير الموقّع هو النوع الأساسي المستخدم في المصفوفات المناسبة لتخزين الأشياء "non-bit-field" التعسفية: افتقارها إلى بتات الحشو وتوضيحات المصائد ، وتعريف تمثيل الكائن إمكانية التعرج.
يختلف الحجم الفعلي وسلوك أنواع "floating-point" أيضًا حسب التطبيق. الضمان الوحيد هو أن "long double" ليس أصغر من "double" ، وهو ليس أصغر من "float". عادة ، يتم استخدام تنسيقات النقطة العائمة الثنائية 32 بت و 64 بت IEEE 754 ، إذا كانت مدعومة من قبل الأجهزة.
يتضمن معيار C99 أنواع float_t و double_t حقيقية جديدة "floating-point" ، ويتم تعريفها في البداية في العنوان . وهي تتوافق مع الأنواع المستخدمة للنتائج الوسيطة للتعبيرات ذات النقطة العائمة عندما تكون FLT_EVAL_METHOD هي 0 أو 1 أو 2. وقد تكون هذه الأنواع أوسع من مزدوجة طويلة.
وأضاف C99 أيضا أنواع معقدة: codice_1، codice_2، codice_3.
أضاف الC99 نوع Bool وهو عبارة عن ال ( صحيح / خطأ ) boolean . بالإضافة إلى ذلك ، يعرّف العنوان الجديد codice_4 ال Bool كاسم مستعار مناسب لهذا النوع كما يوفر وحدات الماكرو لـ true و false. وظائف ال Bool مماثلة لنوع متكامل عادي ، مع استثناء واحد: يتم تخزين أي بيان إلى _Bool التي ليست 0 (خطأ) ك 1 (صحيح). يوجد هذا السلوك لتجنب طفح عدد صحيح (integer overflows) في تضييق التحويلات الضمنية. على سبيل المثال ، في التعليمة البرمجية (code) التالية:
unsigned char b = 256;
if (b) {
قيمة الb ستساوي صفر/خطأ (false) في حالة أن يكونcodice_5 في نطاق ال8بت .. ويرجع السبب في ذلك إلى عدم احتواء نوع البيان ال 256 ، مما يؤدي إلى استخدام 8 بتات أقل منه ، مما ينتج عنه قيمة صفرية. ومع ذلك ، يؤدي تغيير نوع التعليمات البرمجية (code) السابقة إلى التصرف بشكل طبيعي
_Bool b = 256;
if (b) {
مواصفات لغة الC بالأضافة الي typedefs ( كلمة تستخدم لتكون اسم مستعار لنوع بيان جديد ) codice_6 وcodice_7 لتمثيل الكميات المتعلقة بالذاكرة. يتم تعريف حجمها وفقا للقدرات الحسابية لمعالج الهدف لا قدرات الذاكرة ، مثل مساحة العنوان المتوفرة. كل من هذه الأنواع محددة في العنوان  ( في السي++ codice_8 ) .
codice_6 هو نوع صحيح غير موقعة يستخدم لتمثيل حجم أي كائن (بما في ذلك المصفوفات) في تنفيذ معين . codice_10 المشغل ينتج قيمة من نوع codice_6 . الحجم الأكبر لcodice_6 بنتج من خلال codice_13
ثابت المايكرو الذي تم تعريفه في العنوان codice_14 .
codice_6 يضمن أن يكون علي الأقل علي نطاق 16 بايت . بالأضافة POSIX يحتوي codice_16، وهو نوع متكامل موقّع بنفس عرضه ك codice_6.
codice_7 نوع متكامل موقَّع يُستخدم لتمثيل الفرق بين المؤشرات . فقط يضمن أن تكون صالحة ضد المؤشرات التي من نفس النوع . مسح المؤشرات التي تتكون من أنواع مختلفة هو تعريف التنفيذ.
يتم توفير معلومات حول الخصائص الفعلية ، مثل الحجم ، من الأنواع الحسابية الأساسية ، عبر الثوابت الكلية في رأسين : codice_19 المسؤل عن تعريف الmacros للأرقام الصحيحة و codice_20 المسؤل عن تعريف الmacros لأنواع floating-point . القيم الحقيقية تعتمد علي التنفيذ الحقيقي.
خصائص نوع الرقم الصحيح (int)خصائص أنواع الfloating-point
يتضمن معيار C99 تعريفات لعدة أنواع جديدة جديدة لتعزيز إمكانية نقل البرامج. تعتبر الأنواع الصحيحة الأساسية المتاحة بالفعل غير كافية ،لأن أحجامها الفعلية محددة بالتطبيق وقد تختلف باختلاف الأنظمة المختلفة. تعتبر الأنواع الجديدة مفيدة بشكل خاص في البيئات المضمنة حيث لا يدعم الجهاز عادة سوى عدة أنواع ، ويتنوع الدعم بين بيئات مختلفة. جميع الأنواع الجديدة يتم تعريفها في العنوان codice_77 ويسمي في لغة السي++ codice_78 وايضا يمكن تعريفها في العنوان codice_14 . يمكن تجميع الأنواع في الفئات التالية :يلخص الجدول التالي الأنواع و الأوجه للحصول علي تفاصيل التنفيذ ( الN تدل علي عدد البتات )
العنوان codice_77 يوفر ميزات تعمل على تحسين وظائف الأنواع المحددة في العنوان codice_14 وشملت هي وحدات الماكرو التي تحدد printf format string و scanf format string المقابلة لأنواع codice_14 والدوال المتعددة التي تعمل في أنواع codice_83 وcodice_84 . هذا العنوان تم اضافته في معيار C99.وحدات الماكرو بتنسيق الcodice_85. في ال"{fmt}" يحدد تنسيق الإخراج وهي واحدة من ال codice_86 decimal، codice_87 hexadecimal، codice_88 octal، codice_89 unsigned و codice_90 integer . يعرف ال{type} نو ع الوسيط ويكون واحد من codice_91، codice_92، codice_93، codice_94، codice_95 ، حيث ال N عدد البتات.
Scanf format string
وحدات الماكرو بتنسيق الcodice_85. في ال"{fmt}" يحدد تنسيق الإخراج وهي واحدة من ال codice_86 decimal، codice_87 hexadecimal، codice_88 octal، codice_89 unsigned و codice_90 integer . يعرف ال{type} نو ع الوسيط ويكون واحد من codice_91، codice_92، codice_93، codice_94، codice_95 ، حيث ال N عدد البتات.
وعلى نحو مماثل للأنواع الصحيحة ذات العرض الثابت ، تحدد المواصفة ISO / IEC TS 18661 أنواع الفواصل العائمة لتبادل IEEE 754 والتنسيقات الموسعة في binary (الثنائيات) و decimal ( ال) :تعطي الهياكل ميزة تخزين البيانات المتعددة. مختلفة في نوع البيان. في مخزن في الذاكرة يدل علي متغير واحد ، المثال التالي يوضح هيكل معين اسم نوع البيان struct birthday الذي يحتوي علي اسم الشخص ويوم ميلاده الذي يتكون من حروف وأرقام . يتم تعريف الهيكل ويليه تعريف المتغيرات والبيانات بداخلها. 
struct birthday {
struct birthday John;
تخطيط الذاكرة للهيكل هو مشكلة في تنفيذ اللغة لكل نظام أساسي ، مع بعض القيود . عنوان الذاكرة لأول عنصر في الهيكل يجب أن يكون هو عنوان الهيكل نفسه، يمكن تهيئة الهياكل أو تعيينها لاستخدام القيم الحرفية المركبة compound literals، الدالة يمكن أن تعود بهيكل. على الرغم من أن هذا غير فعال في كثير من الأحيان في وقت التشغيل. منذ C99 ، قد ينتهي الهيكل أيضًا بعنصر من المصفوفة المرنة.
struct node {
لكل نوع T ، باستثناء أنواعا الدوال وال void ، توجد أنواع "مصفوفة عناصر N من النوع T". المصفوفة هي مجموعة من القيم ، جميعها من نفس النوع ، مخزنة بشكل متقارب في الذاكرة. يتم فهرسة (ترقيم) مصفوفة الحجم N بواسطة الأعداد الصحيحة من 0 حتى وتضم N-1. هناك أيضًا "مصفوفات ذات حجم غير محدد" ( vector ) حيث لا يعرف عدد العناصر بواسطة المبرمج أو المنفذ ( compiler ) . هنا مثال موجز:
int cat[10]; // array of 10 elements، each of type int
int bob[]; // array of an unspecified number of 'int' elements
يمكن تهيئة المصفوفات باستخدام مُهيئ مركب ، ولكن لا يتم تعيينها. يتم تمرير المصفوفات إلى دوال function بتمرير مؤشر pointer إلى العنصر الأول. يتم تعريف المصفوفات متعددة الأبعاد على أنها "مصفوفه من المصفوفات ..." ، ويجب أن يكون لجميع الأبعاد حجم ثابت وقت التجميع فيما عدا البعد الخارجي:
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 *oval;
قد يتم أيضًا الإعلان عن المؤشرات لأنواع بيانات المؤشر ، وبالتالي إنشاء عدة مؤشرات غير مباشرة ، مثل char ** و int *** ، بما في ذلك المؤشرات إلى المصفوفات . هذه الأخيرة أقل شيوعًا من مجموعة من المؤشرات ، وقد يكون انشائها مربكًا:
char *pc[10]; // array of 10 elements of 'pointer to char'
char (*pa)[10]; // pointer to a 10-element array of char
يستهلك الكمبيوتر الشخصي عشرة أجزاء من الذاكرة من حجم المؤشر char (عادة 40 أو 80 بايت على الأنظمة الأساسية الشائعة) ، ولكن عنصر pa هو مؤشر واحد فقط - حجم الpa عادة 4 أو 8 - والبيانات التي تشير إليها هي مجموعة من عشرة بايت (sizeof * سنويا = 10).
ال "union" هو بناء خاص يسمح بالوصول إلى مكان الذاكرة نفسه باستخدام خيار الأختلاف في نوع الوصف. على سبيل المثال ، قد يتم التصريح عن اتحاد (union) أنواع البيانات للسماح بقراءة نفس البيانات إما integer أو float أو أي نوع آخر تم التصريح به من قبل المستخدم:
union {
} u;
قرأه عنصر من union ليست هي نفسها مثل الصب فيه حيث أن قيمة العضو لا يتم تحويلها ، بل يتم قراءتها فقط
مؤشرات الدالة تسمح بعودة الدالة بتوقيع معين. علي سبيل المثال: تخزين عنوان معيار الدالة codice_111 في متغير codice_112:
int (*my_int_f)(int) = &abs;
// the & operator can be omitted، but makes clear that the "address of" abs is used here
مذكور سابقا أن نوع البيان يمكن أن يكون مميزا أكثر بالType qualifiers . هناك أربعة أنواع مؤهلات في C11 القياسية: const C89 ، متقلبة C89 ، وتقييد C99 و _Atomic C11 . هذا الأخير لديه اسم خاص لتجنب تعارض مع أسماء المستخدمين. ولكن الcodice_113 يمكن أن فقط يستخدم في حالة وجود العنوان codice_114 مسبقا . codice_115 الي حد بعيد هو أشهرهم وأكثرهم استخداما. تظهر في المكتبة القياسية وتوجد في أي استخدام كبير للغة C ، والتي يجب أن تلبي const-correctness ( صحة الconst ). تستخدم المؤهلات الأخرى للبرمجة ذات المستوى المنخفض ، وعلى الرغم من استخدامها على نطاق واسع ، إلا أنه نادرًا ما يستخدمها المبرمجون العاديون.