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

التعليقات في لغة C: شرح // و/* */

للغة C أسلوبان للتعليق - السطر الواحد // والمتعدّد الأسطر /* */ - لكل منهما تاريخ مختلف، ومعهما فخّ تداخل واحد. إليك كيفية استخدام الاثنين، وما يستحقّ التعليق وما لا يستحقّ.

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

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

الصيغتان

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

// يمتدّ حتى نهاية السطر المادّي. ولا يمكن أن يتبعه شيء في ذلك السطر، لذا فإن هذا لا يعمل بالشكل الذي يبدو عليه:

int x = 5;  // set x to five  int y = 6;   /* y is never declared */

/* ... */ ينتهي عند أول */، أينما كانت. ويمكن أن يبدأ وينتهي في منتصف السطر، وهو أمر مفيد أحيانًا:

int total = price /* before tax */ + shipping;

لماذا يوجد أسلوبان

/* */ هي C الأصلية، من عام 1972. أما // فجاءت من C++ ولم تُضَف رسميًا إلى C إلا في C99. ويفسّر ذلك التاريخ شيئًا ستلاحظه وأنت تقرأ شيفرات أقدم: المكتبات المكتوبة لتكون محمولة إلى C89 تستخدم /* */ حتى للتعليقات ذات السطر الواحد، لأن // كانت ستفشل في الترجمة على سلاسل الأدوات القديمة التي كانت تدعمها.

واليوم يقبل كل مترجم يُرجَّح أن تستخدمه كليهما. استخدم // للملاحظات العادية و/* */ عندما يمتدّ التعليق على أسطر فعلًا. وإن كنت تستهدف مترجمًا مضمّنًا قديمًا جدًا، فتحقّق قبل الاعتماد على //.

التعليقات لا تتداخل

هذا هو الفخّ الحقيقي الوحيد:

/* Disable this section for now
   int a = compute();
   /* the classic helper - keep an eye on it */
   int b = a * 2;
*/

ينتهي تعليق الكتلة عند أول */، وهي التي في السطر الثالث. فيعود السطران الرابع والخامس شيفرة حيّة، وتصبح */ الذيلية في السطر السادس خطأً صياغيًا. ورسالة المترجم تشير إلى السطر الأخير ولا تفيد إطلاقًا في بيان السبب.

والحلّ هو استخدام المعالج الأولي بدلًا من ذلك، فهو يتعامل مع التداخل:

#if 0
    int a = compute();
    /* the classic helper - keep an eye on it */
    int b = a * 2;
#endif

#if 0 غير محقّق أبدًا، فيحذف المعالج الأولي كل شيء حتى #endif قبل أن يراه المترجم. وهو ينجو من التعليقات وعلامات الاقتباس وكتل #if الأخرى بالداخل، ويسهل البحث عنه عند التنظيف.

تعطيل الشيفرة أثناء التنقيح

الإزالة المؤقّتة لسطر هي الاستخدام اليومي الأشيع للتعليقات. فحين يسيء برنامج التصرّف، يخبرك تعطيل جملة واحدة في كل مرة أيّها المهمّة.

أزل التعليق عن printf وشغّل مجددًا لترى الحلقة تبني إجابتها. التتبّع بالطباعة ليس أنيقًا، لكنه في C سريع وينجح دائمًا - المنقّح يخبرك أكثر، وprintf يخبرك شيئًا فورًا.

وعادتان تمنعان هذا من أن يصير فوضى. احذف الشيفرة المعطّلة قبل أن تودعها؛ فنظام التحكّم بالإصدارات يتذكّر النسخة القديمة نيابةً عنك. وحين تترك سطرًا معطّلًا عن قصد، فاذكر السبب في ملاحظة بجواره.

تعليقات التوثيق

تعليق الكتلة فوق الدالة هو حيث تشرح ما تفعله، وماذا تعني وسائطها، وأي شيء مفاجئ فيها.

تقرأ أدوات مثل Doxygen تعليقات مهيكلة كهذه وتولّد منها وثائق مرجعية. وأسلوب Doxygen الخاص يستخدم /** ... */ مع وسمي @param و@return:

/**
 * Converts Celsius to Fahrenheit.
 * @param c temperature in Celsius
 * @return the same temperature in Fahrenheit
 */
double celsius_to_fahrenheit(double c);

وأيّ منهما مناسب لشيفرتك. والمهمّ أن يعيش التعليق بجوار التصريح الذي يقرؤه الناس - في ملف الترويسة عادةً - بدل أن يُدفَن في التنفيذ.

ما الذي يستحقّ تعليقًا

القاعدة التي تصمد أمام قواعد الشيفرة الحقيقية: علّق على السبب، لا على الفعل.

i++;  // increment i          <- لا يقول شيئًا لم تقله الشيفرة
/* Skip the BOM: files exported by the old system start with
   three bytes that are not part of the data. */
offset += 3;

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

وأمور تستحقّ تعليقًا فعلًا في C تحديدًا:

  • من يملك هذه الذاكرة. إن أعادت دالة مؤشّرًا يجب على المستدعي تحريره بـ free، فقل ذلك. فلا سبيل في C للتعبير عن ذلك في النوع.
  • الوحدات والمدَيات. int timeout; غامضة - ثوانٍ أم أجزاء من الألف؟
  • صحّة غير بديهية. لماذا تتوقّف الحلقة عند n - 1، ولماذا هذا التحويل آمن، ولماذا المخزن 256 بايت.
  • غرابة مقصودة. الشيفرة التي تبدو كعلّة وليست كذلك تجتذب "إصلاحات" من القرّاء المستقبليين ما لم تُوسَم.

ذلك التعليق يستحقّ مكانه: فالسطر الذي تحته يبدو زائدًا وهو ليس كذلك.

التعليقات داخل السلاسل النصية ليست تعليقات

تفصيلة أخيرة. ليس لعلامات التعليق أي معنى خاص داخل سلسلة نصية أو ثابت محرفي:

يُطبع السطران كاملين. فالمترجم يقطّع السلاسل النصية إلى رموز قبل أن يبحث عن التعليقات، فتكون // داخل علامتي الاقتباس مجرّد محرفين. (و%% في السطر الأول هي كيفية طباعة علامة نسبة مئوية حرفية بـ printf - فـ % وحدها تبدأ محدّد تنسيق.)

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

كيف تكتب تعليقًا في لغة C؟

بطريقتين. // هذا تعليق يمتدّ حتى نهاية السطر. و/* هذا تعليق */ يمكن أن يمتدّ على أي عدد من الأسطر وينتهي عند */ الخاتمة. وكلاهما يُزال قبل الترجمة، فلا يؤثّر في البرنامج أبدًا.

هل تدعم لغة C تعليقات //؟

نعم، منذ C99. وقد اقتُبست من C++ وصارت مدعومة عالميًا اليوم. ولا يرفضها إلا مترجمات C89 القديمة جدًا، ولهذا تستخدم الشيفرات العتيقة جدًا /* */ لكل شيء، حتى للتعليقات ذات السطر الواحد.

هل يمكن تداخل التعليقات في لغة C؟

لا. /* outer /* inner */ still outer */ ينتهي عند أول */، فيبقى still outer */ شيفرة معطوبة. ولتعطيل كتلة تحتوي أصلًا على تعليقات /* */، استخدم #if 0 ... #endif بدلًا من ذلك، فهي تتداخل بشكل صحيح.

كيف تعطّل كتلة من الشيفرة في لغة C؟

غلّفها بـ /* */ إن لم تكن تحوي تعليقات كتلة بداخلها، أو ضع // في بداية كل سطر. والخيار المتين للمناطق الكبيرة هو #if 0 قبلها و#endif بعدها - فالمعالج الأولي يزيل كل ما بينهما، وهو ينجو من التعليقات وعلامات الاقتباس بالداخل.

Coddy programming languages illustration

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

ابدأ الآن