ما الذي يجب أن تُرجعه main() في C++؟ مقارنة مع C والمعايير

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة: السؤال الرئيسي الذي يطرحه حتى المحترفون

\n\n

هل تساءلت يومًا لماذا يبدأ كل برنامج في C++ بـ int main()، وليس بـ void main()؟ وماذا يحدث في الواقع عندما تكتب return 0؟ هذا السؤال هو من أشهر الأسئلة على Stack Overflow، حيث حصد آلاف المشاهدات ومئات التعليقات. قد يبدو موضوعًا بسيطًا، لكنه يخفي في طياته طبقة كاملة من التفاصيل الدقيقة التي تفصل بين C و C++، وكذلك بين المبتدئين والمطورين ذوي الخبرة.

\n\n

في هذه المقالة، لن نقدم إجابة جافة فحسب. بل سنقوم بمقارنة المنهجيات في C و C++، ونحلل المعايير، ونعرض أمثلة حقيقية على الكود، ونشرح كيفية التعامل بشكل صحيح مع القيمة المُرجعة من main()، ليكون كودك ليس فقط قابلاً للعمل، بل أيضًا قابلاً للنقل. إذا كنت تدرس C++ أو تكتب به يوميًا، فهذه المقالة لك.

\n\n

إجابة مختصرة: ما الذي يجب أن تُرجعه main() في C++؟

\n\n

إذا كنت في عجلة من أمرك، إليك الجوهر: يجب أن تُرجع الدالة main() في C++ قيمة من نوع int. هذا مطلب صارم من المعيار (بدءًا من C++98 وحتى C++23). تُعلم القيمة المُرجعة نظام التشغيل ما إذا كان البرنامج قد اكتمل بنجاح أم لا.

\n\n

إليك الكود الصحيح الأدنى:

\n\n
#include <iostream>\n\nint main() {\n    std::cout << "Hello, World!" << std::endl;\n    return 0; // اكتمال ناجح\n}
\n\n

لكن هذا مجرد غيض من فيض. دعنا نتعمق أكثر.

\n\n

لماذا int بالتحديد، وليس void؟ لمحة تاريخية

\n\n

في الإصدارات المبكرة جدًا من C (قبل معيار ANSI C)، لم يكن نوع main() محددًا بدقة. كانت العديد من المترجمات تسمح بكتابة void main()، وكان ذلك يعمل. ومع ذلك، مع ظهور التوحيد القياسي (C89/C90 لـ C و C++98 لـ C++)، تقرر أن main() يجب أن تُرجع رمز الإنهاء لنظام التشغيل.

\n\n

لماذا؟ لأن البرامج النصية، وملفات Makefile، والبرامج الأخرى غالبًا ما تتحقق من كيفية انتهاء عمليتك. رمز الإرجاع 0 يعني "نجاح"، وأي قيمة غير صفرية تعني "خطأ" (أو نوع معين من الخطأ). إذا كانت main() من نوع void، فلن تتمكن من نقل هذه المعلومات.

\n\n

في C++، الوضع أكثر صرامة. ينص معيار C++ (القسم [basic.start.main]) مباشرة: يجب أن يكون نوع main() هو int. أي إعلان آخر (مثل void main()) هو امتداد للمترجم ويجعل الكود غير قابل للنقل.

\n\n

مقارنة C و C++: ما الفرق؟

\n\n

على الرغم من أن كلا اللغتين تتطلبان int main()، إلا أن هناك عدة اختلافات رئيسية:

\n\n
    \n
  • الإرجاع الضمني للصفر في C++: إذا لم تكتب return في نهاية main()، فسيقوم C++ تلقائيًا بإدراج return 0. في C (بدءًا من C99) يعمل هذا أيضًا، لكن في المعايير القديمة (C89) كان غياب return يؤدي إلى سلوك غير محدد.
  • \n
  • وسائط سطر الأوامر: في C++ يمكنك تعريف int main(int argc, char* argv[]) أو int main(). في C يوجد أيضًا خيار ثالث مع البيئة (char* envp[])، لكنه غير موحد في C++ (على الرغم من أن العديد من المترجمات تدعمه).
  • \n
  • void main(): في C، قد تسمح بعض المترجمات (مثل تلك الخاصة بالأنظمة المدمجة) بـ void main(). في C++، هذا خطأ فادح، ولن يتم تجميع الكود في الوضع الصارم.
  • \n
\n\n

مثال لـ C++ (يعمل دائمًا):

\n\n
int main() {\n    std::cout << "C++ سيعيد 0 تلقائيًا" << std::endl;\n    // return 0; // يمكنك عدم كتابتها\n}
\n\n

مثال لـ C (يتطلب return صريحًا في المعايير القديمة):

\n\n
#include <stdio.h>\n\nint main() {\n    printf("في C89، يجب إرجاع 0 بشكل صريح\\n");\n    return 0; // إلزامي\n}
\n\n

ماذا تعني رموز الإرجاع؟ تحليل مع الأمثلة

\n\n

رمز الإرجاع هو

المدونات

توصيات الكتب