C++: أساسيات التصحيح والأخطاء الشائعة
آخر تحديث: 2026-08-26
لا يمكنك كتابة كود مثالي من المحاولة الأولى — الأخطاء هي القاعدة.
الخبير الحقيقي ليس من "لا يخطئ أبدًا"، بل من يستطيع "العثور على الأخطاء وإصلاحها بسرعة".
في هذا الدرس، سنتعلم كيفية تصحيح أخطاء برامج C++.
1. ثلاثة أنواع من الأخطاء
برامج C++ بها ثلاثة أنواع من الأخطاء، لكل منها توقيت اكتشاف وصعوبة إصلاح مختلفان.
| نوع الخطأ | وقت الاكتشاف | صعوبة الإصلاح | مثال |
|---|---|---|---|
| خطأ تجميع | وقت التجميع | ⭐ (الأسهل) | فاصلة منقوطة مفقودة، أقواس غير متطابقة |
| خطأ وقت التشغيل | وقت التشغيل | ⭐⭐ (متوسط) | القسمة على صفر، تجاوز حدود المصفوفة |
| خطأ منطقي | بعد التشغيل (نتيجة خاطئة) | ⭐⭐⭐ (الأصعب) | خوارزمية خاطئة، شرط معكوس |
2. أخطاء التجميع (Compiler Error)
(1) 2.1 الخصائص
- وقت الاكتشاف: وقت التجميع (عند إدخال
g++ xxx.cpp) - العرض: يُبلغ المترجم عن خطأ مباشرة ولا يُنشئ ملفًا تنفيذيًا
- الإصلاح: اتبع رسالة الخطأ للعثور على السطر المقابل وإصلاح مشكلة الصياغة
(2) 2.2 أخطاء التجميع الشائعة
الخطأ 1: فاصلة منقوطة مفقودة
▶ مثال 2: تمرين برمجة أساسي (الصعوبة ⭐)
#include <iostream>
int main() {
int x = 5 // ❌ فاصلة منقوطة مفقودة
std::cout << x << std::endl;
return 0;
}
الخرج:
(خرج البرنامج)
رسالة خطأ المترجم:
error: expected ';' before 'std'
💡 نصيحة: يقول المترجم "فاصلة منقوطة مفقودة قبل std"، لكن الفاصلة المفقودة فعليًا في السطر السابق (السطر 4).
الخطأ 2: أقواس غير متطابقة
#include <iostream>
int main() {
if (5 > 3 { // ❌ قوس إغلاق مفقود
std::cout << "5 > 3" << std::endl;
}
return 0;
}
رسالة خطأ المترجم:
error: expected ')' before '{' token
💡 نصيحة: استخدم ميزة مطابقة الأقواس في VS Code (ضع المؤشر على قوس وسيُسلط الضوء على القسم المقابل).
الخطأ 3: متغير غير معرّف
#include <iostream>
int main() {
x = 5; // ❌ x غير معرّف
std::cout << x << std::endl;
return 0;
}
رسالة خطأ المترجم:
error: 'x' was not declared in this scope
الخطأ 4: عدم تطابق الأنواع
#include <iostream>
int main() {
int x = 3.14; // ⚠️ تحذير: تعيين double لـ int، الجزء الكسري يُفقد
std::cout << x << std::endl;
return 0;
}
رسالة تحذير المترجم:
warning: narrowing conversion of '3.1400000000000001e+0' from 'double' to 'int'
💡 نصيحة: عامل التحذيرات كأخطاء! جمّع بـ g++ -Wall -Wextra -Werror لتحويل التحذيرات إلى أخطاء.
3. أخطاء وقت التشغيل (Runtime Error)
(1) 3.1 الخصائص
- وقت الاكتشاف: ينجح التجميع، لكن يتحطم البرنامج عند التشغيل
- العرض: البرنامج يخرج فجأة أو يُخرج بيانات غير صحيحة
- الإصلاح: يتطلب التصحيح للعثور على سطر الكود الذي سبب التحطم
(2) 3.2 أخطاء وقت التشغيل الشائعة
الخطأ 1: القسمة على صفر
#include <iostream>
int main() {
int x = 5;
int y = 0;
std::cout << x / y << std::endl; // ❌ قسمة على صفر، تحطم وقت التشغيل
return 0;
}
نتيجة التشغيل:
Floating point exception (core dumped) // Linux
أو
Process ended, exit code -1073741676 // Windows
💡 الإصلاح: تحقق مما إذا كان المقسوم عليه صفرًا قبل إجراء القسمة.
الخطأ 2: تجاوز حدود المصفوفة
#include <iostream>
int main() {
int arr[5] = {1, 2, 3, 4, 5};
std::cout << arr[10] << std::endl; // ❌ الوصول إلى عنصر غير موجود
return 0;
}
نتيجة التشغيل:
0 // يُخرج قيمة غير صحيحة، أو يتحطم البرنامج
💡 نصيحة: C++ لا يتحقق تلقائيًا من حدود المصفوفة! هذا أحد أسباب سرعة C++، لكنه أيضًا مصدر شائع للأخطاء.
الخطأ 3: متغير غير مهيأ
#include <iostream>
int main() {
int x; // ❌ غير مهيأ
std::cout << x << std::endl; // يُخرج قيمة غير صحيحة
return 0;
}
نتيجة التشغيل:
32767 // يُخرج قيمة غير صحيحة (قد تختلف كل مرة)
💡 الإصلاح: مهّئ المتغيرات عند تعريفها.
4. الأخطاء المنطقية (Logic Error)
(1) 4.1 الخصائص
- وقت الاكتشاف: البرنامج يعمل، لكن ينتج نتائج خاطئة
- العرض: لا توجد رسالة خطأ واضحة — تحتاج لمقارنة النتائج المتوقعة بالفعلية بنفسك
- الإصلاح: الأصعب! يتطلب فحص منطق الكود بعناية
(2) 4.2 الأخطاء المنطقية الشائعة
الخطأ 1: شرط معكوس
#include <iostream>
int main() {
int age;
std::cout << "Please enter your age: ";
std::cin >> age;
if (age < 18) { // ❌ معكوس! يجب أن يكون age >= 18
std::cout << "You are an adult" << std::endl;
} else {
std::cout << "You are not yet an adult" << std::endl;
}
return 0;
}
💡 نصيحة تصحيح: استخدم cout لإخراج قيم المتغيرات الرئيسية لترى أين يذهب البرنامج.
الخطأ 2: شرط حلقة خاطئ
#include <iostream>
int main() {
// ❌ يريد إخراج 1-10، لكن الشرط i < 10، يُخرج فقط 1-9
for (int i = 1; i < 10; i++) {
std::cout << i << " ";
}
std::cout << std::endl;
return 0;
}
الخطأ 3: = مقابل == معكوس
#include <iostream>
int main() {
int x = 5;
if (x = 10) { // ❌ هذا تعيين، ليس مقارنة! x يصبح 10، الشرط صحيح دائمًا
std::cout << "x is 10" << std::endl;
}
return 0;
}
💡 نصيحة تجنب الأخطاء: ضع الثابت على اليسار: if (10 = x) سيسبب خطأ تجميع.
5. طرق التصحيح
(1) 5.1 التصحيح بـ cout (الأبسط)
أضف cout في مواقع رئيسية لإخراج قيم المتغيرات لترى ما إذا كان البرنامج ينفذ كما هو متوقع.
#include <iostream>
int main() {
int x = 5;
int y = 10;
std::cout << "[DEBUG] x = " << x << std::endl; // خرج تصحيح
std::cout << "[DEBUG] y = " << y << std::endl;
int sum = x + y;
std::cout << "[DEBUG] sum = " << sum << std::endl;
std::cout << "Result: " << sum << std::endl;
return 0;
}
💡 نصيحة: بعد التصحيح، تذكر إزالة (أو التعليق على) خرج التصحيح.
(2) 5.2 استخدام مصحح أخطاء بيئة التطوير (الأقوى)
VS Code + إضافة C/C++ تتضمن مصحح أخطاء يمكنه:
- تعيين نقاط توقف (إيقاف البرنامج مؤقتًا عند سطر معين)
- التنقل خطوة بخطوة (تشغيل سطرًا بسطر)
- مراقبة المتغيرات (رؤية قيم المتغيرات في الوقت الفعلي)
الخطوات:
- في VS Code، انقر على المنطقة يسار رقم السطر لتعيين نقطة توقف (ستظهر نقطة حمراء)
- اضغط
F5(أو انقر "تشغيل وتصحيح")، ثم اختر "C++ (GDB/LLDB)" - سيعمل البرنامج ويتوقف عند نقطة التوقف
- اضغط
F10للتخطي، أوF11للدخول - في لوحة "المتغيرات" على اليسار، يمكنك رؤية جميع قيم المتغيرات
💡 نصيحة: مصحح الأخطاء هو الأداة المطلقة، لكنه قد يبدو معقدًا للمبتدئين. نوصي بتعلم تصحيح cout أولاً، ثم مصحح الأخطاء.
6. ملخص الأخطاء الشائعة
(1) 6.1 مرجع سريع لأخطاء التجميع
| رسالة الخطأ | السبب | الإصلاح |
|---|---|---|
expected ';' before ... |
فاصلة منقوطة مفقودة | أضف فاصلة منقوطة في نهاية السطر السابق |
expected ')' before ... |
قوس إغلاق مفقود | أضف القوس المفقود |
was not declared in this scope |
متغير غير معرّف | عرّف المتغير أولاً |
undefined reference to ... |
دالة غير معرّفة | تحقق من الأخطاء المطبعية في اسم الدالة |
(2) 6.2 مرجع سريع لأخطاء وقت التشغيل
| العرض | السبب | الإصلاح |
|---|---|---|
| البرنامج يخرج فجأة | القسمة على صفر | تحقق من المقسوم عليه قبل القسمة |
| خرج غير صحيح | تجاوز حدود المصفوفة | تحقق من نطاق فهرس المصفوفة |
| أرقام كبيرة غريبة | متغير غير مهيأ | مهّئ عند التعريف |
(3) 6.3 مرجع سريع للأخطاء المنطقية
| العرض | السبب | الإصلاح |
|---|---|---|
| نتيجة خاطئة | شرط معكوس | تحقق بعناية من الشروط |
| عدد تكرارات خاطئ | شرط حلقة خاطئ | حاكي تنفيذ الحلقة على الورق |
| لا ينفذ أبدًا | كتبت = بدلاً من == |
ضع الثوابت على اليسار |
7. تمرين: تصحيح برنامج به أخطاء
▶ مثال 1: اعثر على الأخطاء في البرنامج (الصعوبة ⭐⭐)
برنامج به أخطاء:
#include <iostream>
int main() {
int arr[5] = {1, 2, 3, 4, 5};
// يريد حساب مجموع جميع عناصر المصفوفة
int sum = 0;
for (int i = 0; i <= 5; i++) { // ❌ خطأ 1: i <= 5 يسبب وصول خارج الحدود
sum += arr[i];
}
std::cout << "Sum of array elements: " << sum << std::endl;
int x = 5;
if (x = 10) { // ❌ خطأ 2: = يجب أن تكون ==
std::cout << "x is 10" << std::endl;
}
return 0;
}
الخرج:
Sum of array elements: 15
x not 10
عملية التصحيح:
- التشغيل الأول: البرنامج يتحطم (تجاوز حدود المصفوفة)
- افحص حلقة
forبعناية، اكتشف أنi <= 5يجب أن تكونi < 5
- التشغيل الثاني: البرنامج يُخرج "x is 10" (رغم أن x تساوي 5)
- اكتشف أن
if (x = 10)تعيين، غيّرها إلىif (x == 10)
البرنامج المُصلح:
#include <iostream>
int main() {
int arr[5] = {1, 2, 3, 4, 5};
int sum = 0;
for (int i = 0; i < 5; i++) { // ✅ إصلاح: i < 5
sum += arr[i];
}
std::cout << "Sum of array elements: " << sum << std::endl;
int x = 5;
if (x == 10) { // ✅ إصلاح: ==
std::cout << "x is 10" << std::endl;
} else {
std::cout << "x not 10" << std::endl;
}
return 0;
}
▶ مثال 3: تقنية طباعة التصحيح (الصعوبة ⭐)
#include <iostream>
int main() {
int sum = 0;
for (int i = 1; i <= 5; i++) {
sum += i;
// طباعة تصحيح: عرض القيم في كل تكرار
std::cout << "[DEBUG] i=" << i << ", sum=" << sum << std::endl;
}
std::cout << "Final Result: " << sum << std::endl;
return 0;
}
الخرج:
[DEBUG] i=1, sum=1
[DEBUG] i=2, sum=3
[DEBUG] i=3, sum=6
[DEBUG] i=4, sum=10
[DEBUG] i=5, sum=15
Final Result: 15
الخرج المتوقع:
[DEBUG] i=1, sum=1
[DEBUG] i=2, sum=3
[DEBUG] i=3, sum=6
[DEBUG] i=4, sum=10
[DEBUG] i=5, sum=15
Final Result: 15
❓ أسئلة شائعة
.exe يسبب وميضًا وإغلاقًا — هذا طبيعي. شغّله من طرفية بدلاً من ذلك؛ ② البرنامج في حلقة لا نهائية — اضغط Ctrl+C لإنهائه قسرًا، ثم تحقق من شرط الحلقة.launch.json تلقائيًا. أشياء مهمة للتحقق: هل gdb مثبت، وهل مسار program في launch.json صحيح.std::endl أو std::flush لفرض تفريغ المخزن المؤقت.📖 ملخص
- برامج C++ بها ثلاثة أنواع من الأخطاء: أخطاء تجميع، أخطاء وقت تشغيل، وأخطاء منطقية
- أخطاء التجميع هي الأسهل في الإصلاح (فقط اتبع رسالة الخطأ)
- أخطاء وقت التشغيل تتطلب فحصًا دقيقًا (القسمة على صفر، تجاوز حدود المصفوفة)
- الأخطاء المنطقية هي الأصعب في العثور عليها (استخدم
coutأو مصحح أخطاء) - تقنيات التصحيح:
- استخدم
coutلإخراج قيم المتغيرات الرئيسية - استخدم مصحح أخطاء بيئة التطوير لتعيين نقاط التوقف والتنقل خطوة بخطوة
- عامل التحذيرات كأخطاء (
-Wall -Wextra -Werror)
- استخدم
📝 تمارين
- أساسي (الصعوبة ⭐): أصلح البرنامج التالي (به 5 أخطاء):
#include <iostream>
int main() {
int x = 5
int y = 10;
if (x = y) {
std::cout << "x and y are equal" << std::endl;
}
for (int i = 0; i <= 10; i++) {
std::cout << i << " ";
}
return 0;
}
-
متوسط (الصعوبة ⭐⭐): اكتب برنامجًا يتيح للمستخدم إدخال 10 أعداد صحيحة ويجد القيم القصوى والدنيا.
-
استخدم تصحيح
coutلإخراج قيم المتغيرات في كل تكرار -
أدخل خطأً متعمدًا (مثلاً استخدام قيمة خاطئة لتهيئة القيمة القصوى)، ثم استخدم التصحيح للعثور على المشكلة
-
متقدم (الصعوبة ⭐⭐⭐): تعلم استخدام مصحح أخطاء VS Code:
-
عيّن نقاط توقف في كود لعبة تخمين الأرقام من
practice-branch-loop.md -
اضغط
F5لبدء التصحيح -
استخدم "التنقل خطوة بخطوة" لتشغيل سطرًا بسطر، مراقبًا قيم
secretNumberوguessوattempts -
التقط لقطة شاشة وأرني!
- ثلاثة أنواع من الأخطاء: أخطاء تجميع، أخطاء وقت تشغيل، أخطاء منطقية
- أخطاء التجميع هي الأسهل في الإصلاح — فقط اتبع رسالة الخطأ
- أخطاء وقت التشغيل: القسمة على صفر، تجاوز حدود المصفوفة
- الأخطاء المنطقية هي الأصعب في العثور — استخدم cout أو مصحح أخطاء للتحقيق خطوة بخطوة
- جمّع بـ -Wall -Wextra لتفعيل جميع التحذيرات
8. 🚀 الخطوات التالية
تهانينا! لقد أكملت جميع دروس المرحلة 1 (المقدمة). لقد أتقنت الآن أساسيات C++ — المتغيرات، أنواع البيانات، العوامل، العبارات الشرطية، الحلقات، والتصحيح.
بعد ذلك، سندخل المرحلة 2 (الدوال)، تعلم كيفية تغليف الكود في وحدات قابلة لإعادة الاستخدام لجعل برامجك أنظف وأسهل في الصيانة!