وثائق C
مرجع موجز ومدعّم بأمثلة للغة C. اقرأ المفهوم، شاهد الكود، ثم تدرّب عليه في رحلة Coddy.
البداية
- ما هي لغة Cلغة C لغة صغيرة وسريعة ومترجَمة ظهرت عام 1972، وما زالت تشغّل أنظمة التشغيل وقواعد البيانات وكل جهاز مضمَّن تقريبًا. إليك ما هي، وأين تعمل، ولماذا تستحق التعلّم في 2026.
- تثبيت C (GCC)ثبّت مترجم C عاملًا على أي نظام: MinGW-w64 على ويندوز، وclang من آبل على macOS، وgcc على لينكس - إضافة إلى كيفية التحقّق من نجاح التثبيت وترجمة أول ملف لك.
- الترجمة والتشغيلحوّل ملف .c إلى برنامج يعمل: أمر gcc، وما تفعله المعالجة الأولية والترجمة والربط فعلًا، والرايات التي تستحقّ الاستخدام منذ اليوم الأول، وكيفية قراءة الأخطاء عند الفشل.
- صياغة Cلكل برنامج C الهيكل نفسه: التضمينات، ودالة main، وجمل تنتهي بفواصل منقوطة، وكتل بين أقواس معقوفة. إليك ما يفعله كل جزء والقواعد التي يفرضها المترجم فعليًا.
- التعليقاتللغة C أسلوبان للتعليق - السطر الواحد // والمتعدّد الأسطر /* */ - لكل منهما تاريخ مختلف، ومعهما فخّ تداخل واحد. إليك كيفية استخدام الاثنين، وما يستحقّ التعليق وما لا يستحقّ.
المتغيرات والأنواع
- المتغيّراتكيفية تعريف متغيّر في لغة C، والفرق بين التعريف والتهيئة، وقواعد التسمية، وتعريف عدة متغيّرات دفعة واحدة، ولماذا يكون المتغيّر غير المهيّأ أشيع أخطاء المبتدئين.
- أنواع البياناتلكل متغيّر في C نوع يثبّت حجمه وما يمكنه حمله. إليك كل الأنواع الأساسية وأحجامها الحقيقية، والموقّع مقابل غير الموقّع، وsizeof، وlimits.h، وما يحدث عند الفيضان.
- الثوابتثلاث طرق لتسمية قيمة لا تتغيّر أبدًا في C - الكلمة المفتاحية const، وماكروات #define، وثوابت enum - ما هي كل واحدة فعلًا، وأيّها تختار ومتى.
- العواملكل عامل في لغة C يستحق المعرفة - الحسابي والإسنادي والمقارنة والمنطقي والزيادة - إضافة إلى فخّ القسمة الصحيحة، وسلوك باقي القسمة مع الأعداد السالبة، وجدول أولويات يمكنك الوثوق به.
- القيم المنطقيةلم يكن للغة C نوع منطقي حتى معيار C99. الصفر خطأ وكل ما عداه صحيح، والمقارنات تُنتج int - ويضيف stdbool.h فوق ذلك bool وtrue وfalse. إضافةً إلى علّة = مقابل == التي يتيحها هذا التصميم.
- تحويل الأنواعتحوّل C بين الأنواع باستمرار - أحيانًا لأنك طلبت ذلك بتحويل صريح، وأكثر الأحيان من تلقاء نفسها. إليك قواعد الترقية، وصياغة التحويل الصريح، والتحويلات التي تفقد البيانات بصمت.
التحكم في التدفق
- if / elseكيف تقرّر لغة C: جملة if، وelse، وسلاسل else if، والتداخل، والعامل الثلاثي - إضافة إلى قاعدة الصحّة (الصفر خاطئ وكل ما عداه صحيح) وخطأ `=` مقابل `==` الذي يكسر الشروط بصمت.
- switchكيف تختار جملة switch في C فرعًا واحدًا من قائمة ثوابت - عناوين case، ولماذا تهمّ break، والانسياب المقصود وغير المقصود، وdefault، والتفريع على المحارف والتعدادات، ومتى تتفوّق switch على سلسلة else-if.
- حلقة forكيفية تكرار الشيفرة بحلقة for في لغة C - الترويسة المكوّنة من ثلاثة أجزاء، العدّ تصاعديًا وتنازليًا، المرور على المصفوفات بحيلة sizeof، الحلقات المتداخلة، الحلقات اللانهائية، وأخطاء الانزياح بمقدار واحد والأنواع غير الموقّعة التي تطال الجميع.
- حلقة whileكيف تكرّر حلقة while في C حتى يتغيّر شرط ما - قاعدة الفحص أولًا، وحلقات القيمة الحارسة، وقراءة الإدخال حتى نهاية الملف، وwhile(1)، والتحويل بين for وwhile.
- حلقة do-whileحلقة C التي تبدأ بالجسم: كيف تضمن do-while مرورًا واحدًا قبل الفحص، ولماذا تنتهي بفاصلة منقوطة، وأنماط القوائم وإعادة المحاولة التي صُنعت لها، وكيف تختلف عن حلقة while العادية.
- break وcontinueتترك break الحلقة أو جملة switch؛ وتقفز continue إلى المرور التالي. كيف تتصرّف كل منهما في for وwhile وdo-while، كيف تهرب من الحلقات المتداخلة براية أو goto، والاستخدامات الخاطئة التي تجعل متابعة الحلقات صعبة.
الدوال
- الدوالكيفية تعريف الدوال واستدعائها في لغة C - نوع الإرجاع، والوسائط، والقيم المُرجَعة، ودوال void، ولماذا يهمّ التفكيك، مع مثال كامل مبنيّ من قطع صغيرة مسمّاة.
- وسائط الدوالتمرّر C كل شيء بالقيمة - فالدوال تحصل على نسخ لا على الأصول. ماذا يعني ذلك عمليًا، وكيف تحاكي المؤشّرات التمرير بالمرجع، ولماذا تتصرّف المصفوفات على نحو مختلف، وكيف تُعيد عدة نتائج.
- نماذج الدواللماذا تحتاج C إلى رؤية شكل الدالة قبل استدعائها - كتابة النماذج، وإصلاح أخطاء التصريح الضمني، ووضع النماذج في ملفات الترويسة، والفرق الحقيقي بين f(void) وf().
- الاستدعاء الذاتيكيف تستدعي دالة C نفسها - الحالة الأساسية التي توقفها، والعاملي وفيبوناتشي مشروحين، ولماذا تكون صيغة فيبوناتشي الساذجة بطيئة إلى حدّ كارثي، وما فيضان المكدّس حقًا، ومتى تكون الحلقة هي الجواب الأفضل.
- النطاقأين يكون متغيّر C مرئيًا وكم يدوم - نطاق الكتلة، ووسائط الدوال، والمتغيّرات العامة على نطاق الملف، والمتغيّرات المحلّية static التي تبقى بين الاستدعاءات، والدوال static، والحجب، ولماذا تسبّب المتغيّرات العامة المتاعب.
المؤشرات
- المؤشّراتالمؤشّر متغيّر يخزّن عنوانًا في الذاكرة. تبني هذه الصفحة الفكرة من الأساس - العاملان & و*، وتعريف المؤشّرات ومراجعتها، ولماذا تهمّ أنواع المؤشّرات، ودالة swap() التي تُظهر سبب وجود المؤشّرات أصلًا.
- حساب المؤشّراتإضافة 1 إلى مؤشّر لا تضيف بايتًا واحدًا - بل تنتقل إلى الكائن التالي من ذلك النوع. تغطّي هذه الصفحة ptr+1، والزيادة والإنقاص، وفروق المؤشّرات، والمقارنات، والمرور على مصفوفة بمؤشّر، وقاعدة الموضع التالي للنهاية.
- المؤشّرات والمصفوفاتفي لغة C يتحوّل اسم المصفوفة إلى مؤشّر إلى عنصرها الأول في كل موضع تقريبًا تستخدمه فيه. تشرح هذه الصفحة ذلك التحوّل، ولماذا تكون arr[i] حرفيًا *(arr+i)، ولماذا يجب أن يسافر حجم المصفوفة منفصلًا إلى الدوال، وكيف يختلف المؤشّر إلى مصفوفة عن مصفوفة المؤشّرات.
- مؤشّرات الدوالللدوال عناوين أيضًا، ومؤشّر الدالة يخزّن واحدًا. تفكّ هذه الصفحة صياغة التعريف، وتبيّن كيف يجعلها typedef مقروءة، وتبني وصولًا إلى ردود النداء وqsort بمقارن مخصّص وجداول التوزيع.
- المؤشّرات الفارغةNULL هو العنوان الذي يحمله المؤشّر حين لا يشير إلى شيء. تغطّي هذه الصفحة ما NULL حقًا، ولماذا تؤدّي مراجعته إلى الانهيار، وكيف يختلف عن 0 وعن مؤشّر غير مهيّأ، والأنماط الدفاعية التي تُبقي أخطاء الفراغ خارج شيفرتك.
المصفوفات والسلاسل النصية
- المصفوفاتكيفية تعريف المصفوفات وتهيئتها في لغة C، وفهرستها من الصفر، وحساب الطول بـ sizeof، والمرور على العناصر، ولماذا تُعدّ القراءة بعد النهاية سلوكًا غير معرَّف بدل أن تكون رسالة خطأ.
- المصفوفات متعدّدة الأبعادكيفية تعريف المصفوفات ثنائية الأبعاد في C وتهيئتها والمرور عليها، وما يعنيه توزيع الصفوف أولًا فعليًا في الذاكرة، ولماذا يتطلّب تمرير مصفوفة ثنائية إلى دالة عددَ الأعمدة، ومثال معالَج على المصفوفات الرياضية.
- السلاسل النصيةلا تملك C نوعًا للسلاسل النصية - فالسلسلة مصفوفة محارف تنتهي ببايت '\0'. تبني هذه الصفحة ذلك النموذج الذهني، ثم تغطّي الثوابت النصّية والطباعة والمرور ولماذا لا تستطيع نسخ سلسلة بـ =.
- دوال السلاسل النصيةجولة عملية في <string.h>: القياس بـ strlen، والنسخ بـ strcpy وstrncpy، والدمج بـ strcat، والمقارنة بـ strcmp، والبحث بـ strchr وstrstr - وكيف تحدّد أحجام المخازن بحيث لا تفيض أيٌّ منها.
- تحويل السلاسل النصيةالتحويل بين النص والأعداد في لغة C: لماذا لا تستطيع atoi الإبلاغ عن خطأ، وكيف تستخدم strtol وstrtod استخدامًا صحيحًا مع endptr وerrno، وتحويل الأعداد إلى سلاسل بـ snprintf، وحيل الرقم المفرد مع '0'.
الذاكرة الديناميكية
- الذاكرة الديناميكيةلماذا توجد الكومة، وكيف يسلّمك malloc ذاكرة يُقرَّر حجمها أثناء التشغيل، وصيغة p = malloc(n * sizeof *p)، وفحص NULL، والتحرير مرة واحدة بالضبط، ومصفوفة ديناميكية من البداية إلى النهاية.
- calloc وreallocتمنحك calloc ذاكرة مصفّرة وتضرب الحجم بأمان؛ وتكبّر realloc كتلة ملأتها سلفًا. تغطّي هذه الصفحة الاثنتين، وصيغة المؤشّر المؤقّت التي تمنع realloc الفاشلة من التسريب، ومتى تتفوّق calloc على malloc مع memset.
- تسريبات الذاكرةما التسريب حقًا، والطرق الثلاث التي تنتجه بها برامج C، وانضباط الملكية الذي يمنعه، وكيف تجد الباقي بـ valgrind و-fsanitize=address - وتنتهي ببرنامج مسرِّب يُصلَح خطوة بخطوة.
- المكدّس مقابل الكومةأين تعيش بياناتك فعليًا: التخزين التلقائي على المكدّس، والتخزين الديناميكي على الكومة، والتخزين الساكن كمنطقة ثالثة - مع خطأ المؤشّر المعلّق الكلاسيكي الناتج عن إرجاع متغيّر محلّي، وقاعدة للاختيار.
الهياكل والاتحادات والتعدادات
- البنىكيف تجمع القيم المترابطة في نوع واحد ببنية C - تعريفها، والوصول إلى أعضائها بعامل النقطة، والمهيّئات المسمّاة، ومصفوفات البنى، والتداخل، وقاعدة النسخ عند التمرير التي تفاجئ الجميع.
- البنى والمؤشّراتكيف تشير إلى بنية في لغة C - عامل السهم، ولماذا تحتاج (*p).x إلى أقواسها، وتمرير البنى بالمؤشّر لتعديلها أو لتجنّب النسخ، وتخصيص بنية بـ malloc، وبناء عقدة قائمة مترابطة.
- typedefكيف يمنح typedef نوعًا موجودًا في C اسمًا جديدًا - اصطلاح typedef struct بوسم وبدونه، وtypedef لمؤشّرات الدوال والمصفوفات، والحالة الوحيدة التي يضرّ فيها typedef: إخفاء مؤشّر.
- الاتّحاداتكيف يخزّن اتّحاد C عدة أنواع في البايتات نفسها - لماذا يكون حجمه حجم أكبر أعضائه، ولماذا يجب أن تقرأ العضو الذي كتبته آخرًا، وكيف يجعله الاتّحاد الموسوم (تعداد زائد اتّحاد) آمنًا.
- التعداداتكيفية تعريف enum في C - الترقيم التلقائي، والقيم الصريحة، واستخدام التعدادات في switch ليلتقط المترجم الحالات الناقصة، وتحويل enum إلى سلسلة نصية، وأعراف التسمية التي تُبقيها مقروءة.
الإدخال والإخراج
- printfكيف تعمل printf فعليًا في لغة C - نموذج سلسلة التنسيق، والمحدّدات التي تستخدمها يوميًا، والعرض والدقّة لإخراج مصطفّ، وطباعة الأعداد العشرية بعقل، والقيمة المُرجَعة، ولماذا تكون printf(user_input) ثغرة أمنية.
- scanfكيف تقرأ الإدخال بـ scanf في لغة C - لماذا تلزم &، وكيف تُعالَج المسافات البيضاء، وفيضان المخزن في %s وإصلاحه بالعرض، وفحص القيمة المُرجَعة، وخطأ السطر الجديد المتبقّي، وfgets كبديل متين.
- محدّدات التنسيقكل محدّدات التنسيق في C في مكان واحد - ماذا تعني %d و%s و%c و%f و%p وما بقي، ومُعدِّلات الطول l وll وh وz، والعرض والدقّة والرايات، وأيّها يختلف بين printf وscanf.
- التعامل مع الملفاتكيفية قراءة الملفات والكتابة إليها في C - جدول أوضاع fopen، وفحص NULL، والكتابة بـ fprintf وfputc، والقراءة بـ fgets وfscanf وfgetc، وحلقة السطر سطرًا النموذجية، ومتى تستخدم الوضع الثنائي.
- وسائط سطر الأوامركيف يقرأ برنامج C سطر أوامره - تشريح argc وargv، والمرور على الوسائط، وما تحمله argv[0]، وتحويل الأعداد بـ strtol بدل atoi، وآلة حاسبة صغيرة تجمع كل ذلك.
المعالج المسبق
- المعالج المسبقيحرّر المعالج المسبق نصّ مصدرك قبل أن يراه المترجم أصلًا - فيلصق الترويسات، ويستبدل الماكرو، ويدخل الشيفرة أو يخرجها. إليك عائلة التوجيهات كاملة وكيف تنظر إلى خرجها.
- الماكروالماكرو الشبيه بالكائنات والشبيه بالدوال بـ #define - لماذا يحتاج كل وسيط والجسم كله إلى أقواس، وفخّ التقييم المتعدّد، والماكرو متعدّد الأسطر بـ do-while(0)، ومتى تكون دالة أو const هي الأداة الأفضل.
- ملفات الترويسةكيف تقسّم برنامج C على عدة ملفات: ما ينتمي إلى ملف .h، وما ينتمي إلى ملف .c، وحراس التضمين التي تمنع التضمين المزدوج، وترجمة عدة ملفات معًا، ومشاركة المتغيّرات العامة بـ extern.
- الترجمة الشرطيةترجم شيفرة مختلفة لبناءات مختلفة بـ #ifdef و#ifndef و#if و#elif و#else - مفاتيح التنقيح، وفروع المنصّات، وتعريف الماكرو من سطر الأوامر بـ -D، واستخدام #if 0 لتعطيل الشيفرة.
المكتبة القياسية
- الدوال الرياضيةجولة في math.h - sqrt وpow وfabs وfloor وceil وround وfmod وعائلتا المثلثات واللوغاريتمات وINFINITY وNAN - إضافة إلى راية الرابط -lm التي تسبّب خطأ المرجع غير المعرَّف الكلاسيكي.
- الأعداد العشوائيةكيف تولّد أعدادًا عشوائية في C بـ rand() وRAND_MAX، ولماذا تبذر بـ srand(time(NULL)) مرة واحدة بالضبط، والتحويل إلى مجال بـ % والانحياز الصغير الذي يُدخله، والأعداد العشرية العشوائية، والمتتاليات القابلة للتكرار.
- المكتبة القياسيةما تمنحه كل ترويسة قياسية - stdio.h وstdlib.h وstring.h وmath.h وtime.h وctype.h وlimits.h وstdbool.h وstdint.h وassert.h - مع مثال عملي قصير لكلٍّ منها.
الأخطاء وتصحيحها
- خطأ التجزئةخطأ التجزئة يعني أن برنامجك لمس ذاكرة لا يملكها. إليك الأسباب الخمسة التي تفسّر معظمها، كلٌّ بمثال أدنى وإصلاحه، إضافة إلى كيفية إيجاد السطر الدقيق بـ gdb وAddressSanitizer.
- الأخطاء الشائعةالأخطاء التي يرتكبها كل مبرمج C مرة واحدة على الأقل - فاصلة منقوطة ناقصة، = بدل ==، التصاريح الضمنية، scanf بلا &، مقارنة السلاسل النصية بـ ==، القسمة الصحيحة، المتغيّرات غير المهيّأة، والانزياح بمقدار واحد - كلٌّ منها كعَرَض وسبب وعلاج.
- السلوك غير المعرَّفالسلوك غير المعرَّف شيفرة لا يفرض عليها معيار C أي شروط - فقد يحدث أي شيء، بما في ذلك حذف المحسِّن لفحوصك. إليك أسبابه، ولماذا لا تثبت عبارة "إنها تعمل على جهازي" شيئًا، والرايات التي تلتقطه.