C++ / الأساسي / الدرس 1
بناء برنامج C++20 وفهم طريقة عمله
تتبّع النص المصدري أثناء الترجمة والربط، وميّز النتيجة القابلة للتكرار من رسالة التشخيص أو الميزة غير المدعومة.
في هذه الصفحة
أهداف الدرس
- ترجمة وحدة كاملة مع اختيار وضع C++20 صراحة.
- شرح الترويسات وmain والتعبيرات والإخراج القياسي وحالة انتهاء العملية.
- تصنيف أخطاء الترجمة والربط والتنفيذ والمنطق.
من الملف المصدري إلى البرنامج التنفيذي
لغة C++ مترجمة ولها مكتبة قياسية منفصلة. يحوّل المترجم وحدة ترجمة تضم الملف المصدري والترويسات المضمّنة فيه. ثم يجمع الرابط ملفات الكائنات ويحل الإشارات إلى الدوال ومكوّنات المكتبة. يعمل الملف التنفيذي بعد ذلك كعملية. قد يلوّن المحرر الشيفرة دون ترجمتها؛ لذلك لا يدل مؤشر نجاح في المحرر على إعادة بناء البرنامج. احتفظ بالملف وأمر البناء واسم الملف التنفيذي أمامك أثناء التعلّم.
برنامج صغير مكتمل
احفظ المثال باسم main.cpp. تصرّح الترويسة iostream بمكوّنات التدفقات، وتشير std:: إلى نطاق أسماء المكتبة القياسية. تمثل main نقطة البداية في البيئة المستضافة. يكتب إدراج سلسلة في std::cout محارف على الإخراج القياسي، وتنهي محرفة السطر الجديد السطر. تعني إعادة صفر نجاح العملية بالنسبة إلى البيئة. النص المطبوع وحالة الانتهاء قناتان مختلفتان؛ فطباعة المحرف صفر لا تحدّد حالة نجاح العملية.
#include <iostream>
int main() {
std::cout << "C++20 ready\n";
return 0;
}
C++20 ready
يكتب البرنامج سطرًا واحدًا بالضبط، ولا يحتاج إلى ملفات خارجية أو إدخال أو واجهات خاصة بمنصة.
اختيار أساس للغة والمكتبة
مع أدوات GCC استخدم g++ -std=c++20 -Wall -Wextra -Wpedantic main.cpp -o lesson، ثم شغّل ./lesson في صدفة شبيهة بيونكس. تعتمد هذه الأوامر على الأدوات والصدفة المثبتتين، ولذلك فهي تعليمات تشغيل وليست شيفرة C++ محمولة. يختار العلم قواعد اللغة ولا يضمن توافر كل ميزات المكتبة. راجع جدولي دعم المترجم والمكتبة كلًا على حدة. يعتمد المقرر C++20 ويتجنب المكوّنات الأحدث مثل std::expected، ويبيّن المقاطع التي تحتاج إلى اعتماد خارجي.
الحساب قبل الطباعة
ينتج التعبير قيمة أو ينفّذ فعلًا. هنا تُقيّم عملية الضرب باستخدام عددين صحيحين قبل إدراج الناتج في التدفق. تصف الثوابت المسماة الكميات وتجعل الحساب قابلًا للمراجعة. المثالان برنامجان مكتملان ويجب ترجمة كل منهما منفصلًا لأن كليهما يعرّف main. توقّع الناتج قبل التشغيل كي تفصل العملية الحسابية عن تنسيق الإخراج. إذا غيّرت boxes إلى أربعة يصبح الناتج اثني عشر، ويبقى الإخراج سطرًا واحدًا.
#include <iostream>
int main() {
const int boxes{3};
const int items_per_box{3};
std::cout << boxes * items_per_box << " items\n";
}
9 items
ثلاثة صناديق في كل منها ثلاثة عناصر تعطي تسعة عناصر، ويوضح النص معنى العدد المجرّد.
قراءة الأدلة بالترتيب المناسب
عند فشل البناء ابدأ بأول رسالة مفيدة وموقعها في الملف؛ فقد تكون الرسائل اللاحقة نتيجة لقوس أو تصريح مفقود. يعني فشل الربط غالبًا قبول التصريحات مع غياب تعريف مطلوب. قد ينجح البناء بينما يخالف البرنامج الحساب المقصود أو ينفّذ سلوكًا غير معرّف؛ فالترجمة فحص واحد فقط. دوّن إدخالًا صغيرًا والناتج المتوقع، وأعد البناء بعد التعديل ثم قارن السلوك المرصود. لا تنسب ناتجًا مضمونًا إلى برنامج ينفّذ عمليات غير معرّفة.
الأخطاء الشائعة وإصلاحها
رفض ميزة من C++20.
- لماذا يحدث؟
- يستخدم البناء وضع لغة أقدم أو تطبيقًا لا يدعم الميزة.
- كيف تصلحه؟
- اختر -std=c++20 وافحص جدولي الدعم.
- كيف تتجنب تكراره؟
- احفظ أمر المترجم الفعلي مع المشروع.
البرنامج التنفيذي يطبع الرسالة القديمة.
- لماذا يحدث؟
- لم يُعَد بناء المصدر المعدّل أو شُغّل ملف تنفيذي آخر.
- كيف تصلحه؟
- أعد البناء بنجاح وشغّل الملف الناتج باسمه الصريح.
- كيف تتجنب تكراره؟
- اجعل البناء والتشغيل قابلين للتكرار وتحقق من الفشل.
اسم مثل cout غير مصرّح به.
- لماذا يحدث؟
- تنقص الترويسة اللازمة أو تحديد نطاق الاسم.
- كيف تصلحه؟
- ضمّن iostream واستخدم std::cout.
- كيف تتجنب تكراره؟
- ضمّن مباشرة الترويسة التي تصرّح بكل مكوّن تستخدمه.
اختبر فهمك
1. عدّل برنامج الصناديق إلى خمس رزم في كل منها ثماني بطاقات. توقّع السطر كاملًا، واشرح هل يغيّر تبديل الوحدة المطبوعة الحساب.
اعرض الحل المشروح
استخدم الثابتين packs{5} وcards_per_pack{8} واضربهما ثم ألحق " cards\n". يصبح السطر "40 cards" متبوعًا بسطر جديد. تغيير التسمية وحدها إلى "tickets" يغيّر المعنى المعروض للقارئ ولا يغيّر الضرب الصحيح. أعد البناء قبل فحص الإخراج.
2. فسّر نجاح الترجمة ثم ظهور undefined reference لدالة مساعدة مصرّح بها. أي مرحلة تحتاج إلى إصلاح، وما الدليل على نجاحه؟
اعرض الحل المشروح
لا يجد الرابط تعريف الدالة المساعدة. وفّر تعريفًا مطابقًا واربط الملف المصدري أو ملف الكائن الذي يحتويه. ينبغي أن ينتهي البناء دون خطأ الربط وينتج الملف التنفيذي المقصود. ثم يفحص تشغيله ومقارنة النتيجة السلوك؛ فنجاح الترجمة وحده لا يثبت الصحة.
أهم ما تعلمته
- اختر C++20 صراحة واحتفظ بأوامر قابلة للتكرار.
- افصل صحة المصدر عن نجاح الربط وعن سلوك التنفيذ.
- توقّع الإخراج فقط للبرامج ذات العمليات المعرّفة.