Menu
flag Ar iconالعربيةdown icon

المكتبة القياسية في لغة C: خريطة للترويسات الجديرة بالمعرفة

ما تمنحه كل ترويسة قياسية - stdio.h وstdlib.h وstring.h وmath.h وtime.h وctype.h وlimits.h وstdbool.h وstdint.h وassert.h - مع مثال عملي قصير لكلٍّ منها.

تحتوي هذه الصفحة على محررات قابلة للتشغيل - حرّر، شغّل، وشاهد النتيجة فوراً.

لغة C نفسها ضئيلة - أنواع وعوامل وتدفّق تحكّم ودوال ومؤشّرات. وهي لا تستطيع الطباعة ولا قراءة ملف ولا مقارنة سلسلة نصية ولا تخصيص ذاكرة. وكل ذلك هو المكتبة القياسية: مجموعة ترويسات يوفّرها كل تطبيق مطابق.

وهذه الصفحة خريطة. يقول كل قسم فيمَ تُستخدم ترويسة، ويعرض مثالًا عمليًا قصيرًا واحدًا، ويشير إلى الصفحة الأوفى حيث توجد.

stdio.h - الإدخال والإخراج

الترويسة التي تضمّنها أولًا في كل برنامج تقريبًا. وهي تحمل printf وscanf، والنوع FILE ودوال الملفات، ودوال الإدخال الأكثر أمانًا الموجَّهة بالأسطر.

الأساسيات: printf وfprintf وsprintf وsnprintf للإخراج؛ وscanf وfscanf وsscanf وfgets وgetchar للإدخال؛ وfopen وfclose وfread وfwrite وfseek للملفات. والتغطية الأعمق في printf وscanf والتعامل مع الملفات.

وقاعدة واحدة تستحق الحمل: لا تستخدم gets() أبدًا. فلا سبيل لها إلى معرفة حجم مخزنك وقد أُزيلت من المعيار في C11. وfgets(buf, sizeof buf, stdin) هي البديل.

stdlib.h - الأدوات العامة

الجامعة لكل شيء: الذاكرة والتحويلات والعشوائية والتحكّم في العملية والفرز.

أبرزها: malloc وcalloc وrealloc وfree (انظر الذاكرة الديناميكية)؛ وatoi وatof وstrtol وstrtod للتحويلات - وفضّل عائلة strto* التي تستطيع الإبلاغ عن الفشل حيث تُرجِع atoi صفرًا بصمت؛ وrand وsrand (انظر الأعداد العشوائية)؛ وexit وabort وgetenv وsystem؛ وqsort/bsearch.

string.h - السلاسل النصية وكتل الذاكرة

سلاسل C النصية مصفوفات من char تنتهي بـ '\0'، وكل عملية عليها استدعاء دالة.

وعادتان تمنعان هذه الترويسة من أن تصبح مصدرًا لفيضانات المخازن: اعرف دائمًا حجم الوجهة، وتذكّر أن strcmp تُرجِع 0 عند التساوي - فـ if (strcmp(a, b)) صحيحة حين تختلف السلسلتان. وتغطّي دوال السلاسل النصية أنماط strncpy/snprintf الأكثر أمانًا بالتفصيل.

math.h - الرياضيات

sqrt وpow وfabs وfloor وceil وround وfmod وعائلتا المثلثات واللوغاريتمات وINFINITY وNAN.

وهذه الترويسة الوحيدة التي قد تحتاج راية رابط: فعلى لينكس، أضف -lm في آخر أمر الترجمة وإلا أبلغ الرابط عن "undefined reference to sqrt". والجولة الكاملة في الدوال الرياضية.

time.h - الساعات والتواريخ

والإزاحتان في struct tm توقعان بالجميع: فـ tm_year تُعدّ من 1900، وtm_mon تبدأ من الصفر. وtime(NULL) هي أيضًا البذرة المعتادة لـ srand.

ctype.h - تصنيف المحارف

صغيرة، وأنفع مما تبدو. تأخذ كل دالة محرفًا وتجيب عن سؤال بنعم أو لا، أو تحوّل حالة الحرف.

المجموعة الكاملة: isalpha وisdigit وisalnum وisspace وisupper وislower وispunct وisxdigit وisprint، إضافةً إلى toupper وtolower.

ولاحظ التحويل (unsigned char). فهذه الدوال معرَّفة للقيم القابلة للتمثيل كـ unsigned char إضافةً إلى EOF؛ وchar العادي موقّع على معظم الأنظمة، فيصل بايت فوق 127 كعدد سالب ويصبح الاستدعاء سلوكًا غير معرَّف. والتحويل لا يكلّف شيئًا ويزيل هذا الصنف من المشكلات بأكمله.

وفضّل هذه على الفحوص المكتوبة يدويًا. فـ c >= '0' && c <= '9' تصادف أن تعمل، لكن isdigit(c) تقول ما تعنيه وتبقى صحيحة في كل مكان.

limits.h وfloat.h - حدود الأنواع

إلى أي حدّ يمكن أن يكبر int على هذا الجهاز؟ تجيب هاتان الترويستان عن ذلك، والإجابات هي سبب سؤال الشيفرة القابلة للنقل بدل الافتراض.

وINT_MAX هي كيف تفحص الفيضان قبل وقوعه، وهذا يهمّ لأن فيضان الموقّع سلوك غير معرَّف لا التفاف تستطيع فحصه بعد وقوعه.

stdbool.h وstdint.h - أنواع أفضل

لم تملك C نوعًا منطقيًا حتى C99. وتوفّر <stdbool.h> واحدًا:

bool وtrue وfalse ماكرو لـ _Bool و1 و0، لكنها تجعل القصد واضحًا. (وفي C23 صارت كلمات مفتاحية ولم تعد الترويسة مطلوبة.)

وتمنح <stdint.h> أنواعًا بعروض مضمونة - وهي جوهرية لصيغ الملفات وبروتوكولات الشبكات وكل ما هو مضمَّن، حيث لا يكفي "الأرجح أن int هو 32 بتًا":

وماكرو من طراز PRId32 في <inttypes.h> يتمدّد إلى محدّد printf الصحيح لكل نوع ثابت العرض على المنصّة الحالية - وهذه الطريقة القابلة للنقل لطباعتها، إذ إن %d صحيح لـ int32_t على بعض الأنظمة وخاطئ على غيرها.

assert.h - فحص افتراضاتك

assert(expr) لا تفعل شيئًا حين يكون التعبير صحيحًا وتُنهي البرنامج برسالة حين يكون خاطئًا.

والترجمة بـ -DNDEBUG تزيل كل توكيد، فلا تكلّف شيئًا في بناء الإصدار. وهذا أيضًا التحذير: لا تضع أبدًا أثرًا جانبيًا داخل assert. فـ assert(read_next() > 0) تتوقّف عن القراءة كليًا في بناء الإصدار، ويظهر الخطأ الناتج في الإنتاج وحده.

والتوكيدات لأخطائك أنت - أي الشروط التي ينبغي أن تكون مستحيلة إن كانت الشيفرة صحيحة. أما إدخال المستخدم السيّئ فليس توكيدًا؛ بل جملة if ورسالة خطأ.

الباقي باختصار

  • <stddef.h> - size_t وptrdiff_t وNULL وoffsetof
  • <stdarg.h> - الدوال متغيّرة الوسائط، وهي الآلية وراء printf
  • <errno.h> - errno إضافةً إلى perror وstrerror للإبلاغ عن سبب فشل استدعاء
  • <signal.h> - التعامل مع الإشارات مثل Ctrl-C
  • <setjmp.h> - القفزات غير المحلّية؛ ونادرًا ما تكون الجواب الصحيح
  • <locale.h> و<wchar.h> و<wctype.h> - الإعدادات المحلّية والمحارف العريضة
  • <stdnoreturn.h> و<stdalign.h> و<threads.h> و<stdatomic.h> - إضافات C11

وعادتان تجعلان استخدام المكتبة ممتعًا. اقرأ صفحة الدليل قبل تخمين توقيع دالة - فـ man 3 strtol على macOS ولينكس مرجعية وسريعة. وافحص القيم المُرجَعة: فـ malloc وfopen وstrtol كلها تبلّغ عن الفشل، والبرنامج الذي يتجاهلها يفشل متأخّرًا كثيرًا وبوضوح أقلّ كثيرًا.

الأسئلة الشائعة

ما المكتبة القياسية في لغة C؟

مجموعة الدوال والأنواع والماكرو التي يوفّرها كل تطبيق مطابق للغة C، مجمّعة في نحو 30 ترويسة. وهي تغطّي الإدخال والإخراج (<stdio.h>)، والذاكرة والتحويلات (<stdlib.h>)، والسلاسل النصية (<string.h>)، والرياضيات (<math.h>)، والوقت، وتصنيف المحارف، وحدود الأنواع العددية. ولا تملك C إدخالًا وإخراجًا مدمجًا ولا معالجة نصوص - فكل ذلك يأتي من هنا.

ما الفرق بين stdio.h وstdlib.h؟

<stdio.h> للإدخال والإخراج: printf وscanf وfopen وfgets وFILE. و<stdlib.h> للأدوات العامة: malloc وfree، وatoi وstrtol، وrand وsrand، وexit وqsort وbsearch. ويضمّن البرنامج النموذجي كلتيهما.

ماذا تفعل ctype.h؟

تصنّف المحارف المفردة وتحوّلها: isdigit وisalpha وisalnum وisspace وisupper وislower وispunct، إضافةً إلى toupper وtolower. واستخدامها بدل مقارنات مكتوبة يدويًا مثل c >= '0' && c <= '9' أوضح وصحيح لكل إعداد محلّي وكل مجموعة محارف.

هل أحتاج إلى ربط شيء لاستخدام المكتبة القياسية في C؟

لا، باستثناء واحد: الدوال الرياضية. فمكتبة C القياسية تُربَط تلقائيًا، لكن تنفيذات <math.h> على لينكس تعيش في مكتبة منفصلة، فتحتاج sqrt وأخواتها إلى -lm في آخر أمر الترجمة. وكل ما عدا ذلك يحتاج #include الصحيح فقط.

Coddy programming languages illustration

تعلّم البرمجة مع Coddy

ابدأ الآن