C++: المصفوفات متعددة الأبعاد
آخر تحديث: 2026-08-26
إذا كانت المصفوفة أحادية البعد مثل "صف من صناديق البريد"، فماذا عن تمثيل بيانات جدولية (مثل جداول Excel، رقعة الشطرنج، المصفوفات)؟
هنا تأتي المصفوفات متعددة الأبعاد — مصفوفات من مصفوفات.
1. المصفوفات ثنائية الأبعاد
(1) 1.1 ما هي المصفوفة ثنائية الأبعاد؟
المصفوفة ثنائية الأبعاد هي "مصفوفة من مصفوفات" — كل عنصر هو نفسه مصفوفة.
| التشبيه من الواقع | المكافئ البرمجي |
|---|---|
| جدول Excel (صفوف × أعمدة) | مصفوفة ثنائية الأبعاد |
| رقعة شطرنج (8 × 8) | مصفوفة ثنائية الأبعاد |
| مصفوفة (3 × 3) | مصفوفة ثنائية الأبعاد |
(2) 1.2 تعريف مصفوفة ثنائية الأبعاد
الصيغة:
▶ مثال 2: مثال على الكود (الصعوبة ⭐)
Type arrayName[Rows][Cols];
الخرج:
(خرج البرنامج)
مثال:
int matrix[3][4]; // مصفوفة ثنائية الأبعاد: 3 صفوف، 4 أعمدة
تخطيط الذاكرة:
matrix[0][0] matrix[0][1] matrix[0][2] matrix[0][3] ← الصف 0
matrix[1][0] matrix[1][1] matrix[1][2] matrix[1][3] ← الصف 1
matrix[2][0] matrix[2][1] matrix[2][2] matrix[2][3] ← الصف 2
💡 نقطة رئيسية: في المصفوفة ثنائية الأبعاد، الفهرس الأول هو الصف، والثاني هو العمود.
2. تهيئة مصفوفة ثنائية الأبعاد
(1) 2.1 التهيئة عند التعريف
#include <iostream>
int main() {
// الطريقة 1: التهيئة حسب الصف
int matrix[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
// الطريقة 2: التهيئة المتسلسلة (غير موصى بها، قابلية القراءة ضعيفة)
int matrix2[3][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
return 0;
}
(2) 2.2 التهيئة الجزئية
#include <iostream>
int main() {
int matrix[3][4] = {
{1, 2}, // الصف الأول: أول اثنين فقط مهيآن، الباقي يصبح 0
{5}, // الصف الثاني: الأول فقط مهيأ، الباقي يصبح 0
{} // الصف الثالث: الكل يصبح 0
};
return 0;
}
💡 نصيحة: الصفوف أو الأعمدة المحذوفة تُهيأ تلقائيًا إلى 0.
3. الوصول إلى عناصر المصفوفة ثنائية الأبعاد
(1) 3.1 قراءة العناصر
#include <iostream>
int main() {
int matrix[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
std::cout << "Row 1, Col 1: " << matrix[0][0] << std::endl; // 1
std::cout << "Row 2, Col 3: " << matrix[1][2] << std::endl; // 7
std::cout << "Row 3, Col 4: " << matrix[2][3] << std::endl; // 12
return 0;
}
(2) 3.2 تعديل العناصر
#include <iostream>
int main() {
int matrix[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
matrix[1][2] = 100; // تغيير الصف 2، العمود 3 إلى 100
std::cout << "Modified element: " << matrix[1][2] << std::endl; // 100
return 0;
}
4. اجتياز مصفوفة ثنائية الأبعاد
(1) 4.1 استخدام حلقات for المتداخلة
#include <iostream>
int main() {
int matrix[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
// الحلقة الخارجية: التكرار على الصفوف
for (int i = 0; i < 3; i++) {
// الحلقة الداخلية: التكرار على الأعمدة
for (int j = 0; j < 4; j++) {
std::cout << matrix[i][j] << "\t";
}
std::cout << std::endl; // سطر جديد
}
return 0;
}
💡 نقطة رئيسية: الحلقة الخارجية تتحكم في الصفوف، والحلقة الداخلية تتحكم في الأعمدة.
5. تمرين: جمع المصفوفات
▶ مثال 1: جمع مصفوفتين 3×3 (الصعوبة ⭐⭐)
#include <iostream>
int main() {
int A[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
int B[3][3] = {
{9, 8, 7},
{6, 5, 4},
{3, 2, 1}
};
int C[3][3]; // مصفوفة النتيجة
// جمع المصفوفات
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
C[i][j] = A[i][j] + B[i][j];
}
}
// إخراج النتيجة
std::cout << "Matrix C = A + B: " << std::endl;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
std::cout << C[i][j] << "\t";
}
std::cout << std::endl;
}
return 0;
}
الخرج:
Matrix C = A + B:
10 10 10
10 10 10
10 10 10
6. المصفوفات ثلاثية الأبعاد (اختياري)
(1) 6.1 ما هي المصفوفة ثلاثية الأبعاد؟
المصفوفة ثلاثية الأبعاد هي "مصفوفة من مصفوفات ثنائية الأبعاد".
| التشبيه من الواقع | المكافئ البرمجي |
|---|---|
| عدة جداول ثنائية الأبعاد مكدسة معًا | مصفوفة ثلاثية الأبعاد |
| مكعب (طول × عرض × ارتفاع) | مصفوفة ثلاثية الأبعاد |
(2) 6.2 التعريف والوصول
#include <iostream>
int main() {
int cube[2][3][4]; // طبقتان، 3 صفوف، 4 أعمدة
// التهيئة
cube[0][1][2] = 5; // الطبقة 0، الصف 1، العمود 2
cube[1][2][3] = 10; // الطبقة 1، الصف 2، العمود 3
return 0;
}
💡 نصيحة: المصفوفات ثلاثية الأبعاد صعبة التصور وعادة تُستخدم فقط في الحوسبة العلمية والرسوميات. في المشاريع الحقيقية، يُفضّل std::vector (الذي سنتعلمه لاحقًا).
7. الأخطاء الشائعة
(1) 7.1 تبديل ترتيب الفهارس
مثال على خطأ:
#include <iostream>
int main() {
int matrix[3][4];
matrix[1][2] = 5; // ✅ صحيح: الصف 1، العمود 2
matrix[2][1] = 10; // ✅ صحيح: الصف 2، العمود 1
// ❌ خطأ: تبديل الصف والعمود
// أراد الوصول إلى الصف 1، العمود 2، لكنه وصل إلى الصف 2، العمود 1
std::cout << matrix[2][1] << std::endl;
return 0;
}
(2) 7.2 تجاوز حدود المصفوفة
مثال على خطأ:
#include <iostream>
int main() {
int matrix[3][4];
matrix[3][0] = 5; // ❌ تجاوز الحدود! أقصى فهرس للصف هو 2
matrix[0][4] = 10; // ❌ تجاوز الحدود! أقصى فهرس للعمود هو 3
return 0;
}
💡 نصيحة: للمصفوفة ثنائية الأبعاد matrix[m][n]، نطاقات الفهارس هي:
- الصفوف: من
0إلىm-1 - الأعمدة: من
0إلىn-1
▶ مثال 3: اجتياز مصفوفة ثنائية الأبعاد لحساب المجموع (الصعوبة ⭐)
#include <iostream>
int main() {
int scores[3][4] = {
{85, 90, 78, 92},
{88, 76, 95, 80},
{70, 85, 88, 90}
};
int total = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
total += scores[i][j];
}
}
std::cout << "Total: " << total << std::endl;
std::cout << "Average: " << total / 12 << std::endl;
return 0;
}
الخرج:
Total: 967
Average: 80
❓ أسئلة شائعة
س: كيف تُخزن المصفوفات ثنائية الأبعاد في الذاكرة؟ ج: تستخدم مصفوفات C++ ثنائية الأبعاد الترتيب حسب الصف — تُخزن جميع عناصر الصف الأول أولاً، ثم الصف الثاني، وهكذا. > > تخطيط ذاكرة matrix[3][4]: > [0][0] [0][1] [0][2] [0][3] [1][0] [1][1] ... [2][3] > س: كيف أمرر مصفوفة ثنائية الأبعاد إلى دالة؟ ج: يجب تمرير اسم المصفوفة وعدد الصفوف وعدد الأعمدة. > > void printMatrix(int arr[4], int rows) { // يجب تحديد عدد الأعمدة! > for (int i = 0; i < rows; i++) { > for (int j = 0; j < 4; j++) { > std::cout << arr[i][j] << "\t"; > } > std::cout << std::endl; > } > } > س: هل يمكن أن تكون أحجام المصفوفات ثنائية الأبعاد ديناميكية؟ ج: لا مع المصفوفات العادية (يجب تحديد الحجم وقت التجميع).
الحلول:
- استخدم
std::vector<std::vector<int>>>` (موصى به، سنتعلمه لاحقًا)- استخدم تخصيص الذاكرة الديناميكي (سنتعلم المؤشرات و
newلاحقًا)
س: ما أهم شيء عن المصفوفات متعددة الأبعاد؟ ج: افهم المفاهيم الأساسية أولاً، ثم عززها من خلال أمثلة عملية.
س: كيف أتدرب على المصفوفات متعددة الأبعاد بكفاءة؟ ج: ابدأ بأمثلة بسيطة، وزد الصعوبة تدريجيًا، واختبر كودك دائمًا.
📖 ملخص
- المصفوفات ثنائية الأبعاد هي "مصفوفات من مصفوفات"، مناسبة لتمثيل البيانات الجدولية
- التعريف:
Type arrayName[Rows][Cols]; - الوصول:
arrayName[RowIndex][ColIndex] - الاجتياز: استخدم حلقات for المتداخلة (الخارجية للصفوف، الداخلية للأعمدة)
- مصفوفات C++ ثنائية الأبعاد تُخزن بترتيب الصفوف
- عند تمرير مصفوفة ثنائية الأبعاد كمعامل، يجب تحديد عدد الأعمدة
📝 تمارين
- أساسي (الصعوبة ⭐): عرّف مصفوفة ثنائية الأبعاد 2×3، مهيأة كـ:
1 2 3
4 5 6
ثم أخرج المصفوفة.
- متوسط (الصعوبة ⭐⭐):
اكتب دالة
void transpose(int arr[3], int rows)تحسب منقولة مصفوفة 3×3 (تبديل الصفوف والأعمدة).
المصفوفة الأصلية:
1 2 3
4 5 6
7 8 9
المنقولة:
1 4 7
2 5 8
3 6 9
- متقدم (الصعوبة ⭐⭐⭐): اكتب برنامجًا ينفذ لعبة "إكس-أو":
- استخدم مصفوفة ثنائية الأبعاد 3×3 لتمثيل اللوحة
- لاعبان يتناوبان (أحدهما يستخدم
X، والآخر يستخدمO) - تحقق مما إذا كان لاعب قد كوّن خطًا (أفقيًا، عموديًا، أو قطريًا)
- المصفوفات ثنائية الأبعاد: تخزين حسب الصف، صيغة التعريف: Type arrayName[Row][Col]
- حلقات for المتداخلة تجتاز المصفوفات ثنائية الأبعاد
- حالات الاستخدام الشائعة للمصفوفات متعددة الأبعاد: المصفوفات، الجداول، الصور
- يجب تحديد عدد الأعمدة عند تمرير مصفوفة ثنائية الأبعاد كمعامل دالة
- يمكن تنفيذ المصفوفات ثنائية الأبعاد غير المنتظمة باستخدام مصفوفات المؤشرات
8. 🚀 الخطوات التالية
الآن بعد أن تعلمت المصفوفات متعددة الأبعاد، سندرس بعد ذلك سلاسل C (الدرس 18) — تمثيل السلاسل بمصفوفات الأحرف وفهم المبادئ الأساسية لسلاسل C++.