مراجعة المصفوفات
ما هي المصفوفة؟
المصفوفة عبارة عن بنية بيانات أساسية في لغة C++ تسمح لك بتخزين عناصر متعددة من نفس نوع البيانات تحت اسم واحد. يمكن الوصول إلى هذه العناصر باستخدام الـindex، مما يجعل المصفوفات أداة قوية للتعامل مع مجموعات البيانات بكفاءة.
الإعلان والتهيئة:
في لغة C++، يتضمن الإعلان عن المصفوفة تحديد نوع بيانات عناصرها واسم المصفوفة. يمكن إجراء التهيئة أثناء الإعلان أو لاحقًا باستخدام بيانات الدالة. دعونا نلقي نظرة على بناء الجملة:
// Declaration int myArray[5]; // Initialization during declaration int anotherArray[] = {1, 2, 3, 4, 5}; // Accessing elements cout << anotherArray[2]; // Output: 3
Array Indexing فهرسة المصفوفة:
تبدأ فهرسة المصفوفات من 0، مما يعني أنه يتم الوصول إلى العنصر الأول باستخدام الـindex 0، والثاني باستخدام الـindex 1، وهكذا. كن حذرًا حتى لا تصل إلى عناصر خارج حدود المصفوفة، حيث قد يؤدي ذلك إلى سلوك غير محدد.
التلاعب بالمصفوفات:
الدوران من خلال مصفوفة:
يعد التكرار عبر المصفوفة عملية شائعة. يمكنك استخدام حلقة for للوصول إلى كل عنصر:
for (int i = 0; i < 5; ++i) { cout << myArray[i] << " "; }
حجم المصفوفة:
يعد تحديد حجم المصفوفة أمرًا ضروريًا لتجنب أخطاء الفهرس خارج الحدود. يمكنك استخدام عامل التشغيل sizeof أو حساب الحجم باستخدام عدد العناصر وحجم نوع البيانات:
int size = sizeof(anotherArray) / sizeof(anotherArray[0]);
مثال 1:
#include <iostream> using namespace std; int main() { int arr[7]; for (int i = 0; i < 7; i++) { cin >> arr[i]; } for (int i = 0; i < 7; i++) { cout << arr[i] << " "; } return 0; }
يأخذ هذا البرنامج مدخلات لمجموعة من الأعداد الصحيحة ثم يطبع القيم المدخلة.
مثال 2:
#include <iostream> using namespace std; int main() { int arr[7]; for (int i = 0; i < 7; i++) { cin >> arr[i]; } for (int i = 0; i < 7; i++) { cout << "index" << i << " = " << arr[i]; cout << endl; } cout << endl; return 0; }
هذا البرنامج عبارة عن تطبيق بسيط للـconsole يأخذ مدخلات لمجموعة من 7 أعداد صحيحة من المستخدم ثم يعرض كل عنصر مع موقعه.
مثال 3:
#include <iostream> using namespace std; int main() { char g[5]; cin.get(g, 5); cout << g << endl; return 0; }
يوضح هذا البرنامج قراءة مصفوفة أحرف من إدخال المستخدم باستخدام cin.get().
char g[5];
يعلن هذا السطر عن مصفوفة أحرف تسمى g يمكنها استيعاب 5 أحرف.
cin.get(g, 5);
يستخدم هذا السطر cin.get() لقراءة ما يصل إلى 4 أحرف (نظرًا لأن حجم المصفوفة هو 5، يتم حجز مساحة واحدة للـnull terminator \0) من المستخدم ويخزنها في مصفوفة الأحرف g. ويتوقف عن القراءة عندما يواجه حرف السطر الجديد، أو نهاية الدفق، أو عند قراءة العدد المحدد من الأحرف.
باختصار، يطالب هذا البرنامج المستخدم بإدخال ما يصل إلى 4 أحرف (باستثناء الـnull terminator) ثم يطبع الأحرف المدخلة باستخدام cout.
The null terminator
غالبًا ما يتم تمثيله بالحرف \0 (شرطة مائلة عكسية متبوعة بصفر)، وهو حرف خاص يستخدم في C وC++ للإشارة إلى نهاية النص. من الضروري لوظائف معالجة النص تحديد مكان انتهاؤه في الذاكرة.
في الذاكرة، يتم تمثيل النص على شكل مجموعة من الأحرف. يتم وضع الـnull terminator في نهاية هذا المصفوفة للإشارة إلى حدود النص. عندما يقوم برنامج ما بمعالجة نص، يمكنه الاستمرار في قراءة الأحرف حتى يواجه الـnull terminator، مما يدل على نهاية بيانات النص.
على سبيل المثال:
const char myString[] = "Hello";
سيتم تخزين هذا في الذاكرة على النحو التالي:
H e l l o \0
هنا، يتبع الـ(null terminator) \0 أحرف النص، مما يشير إلى نهايته. تستخدم الدوال التي تعمل على النصوص، مثل تلك الموجودة في مكتبة C القياسية أو مكتبة C++ القياسية، الـ(null terminator) لتحديد طول النص والتعرف على نهايته عند إجراء العمليات.
مثال 4:
#include <iostream> using namespace std; int main() { char g1[10]; char g2[10]; cin.getline(g1, 10); cin.getline(g2, 10); cout << g1 << endl; cout << g2 << endl; return 0; }
يوضح هذا البرنامج استخدام الدالة cin.getline() لقراءة أسطر الإدخال في مصفوفات الأحرف ثم طباعتها.
char g1[10]; char g2[10];
تعلن هذه السطور عن مصفوفتين من الأحرف، g1 وg2، كل منهما قادر على استيعاب ما يصل إلى 9 أحرف بالإضافة إلى الـ( null terminator) \0.
cin.getline(g1, 10); cin.getline(g2, 10);
تستخدم هذه السطور cin.getline() لقراءة أسطر الإدخال من المستخدم في مصفوفات الأحرف g1 وg2. تأخذ الدالة 2 arguments: المصفوفة لتخزين الإدخال (g1 أو g2) والحد الأقصى لعدد الأحرف المراد قراءتها (9 في هذه الحالة، مع ترك مسافة واحدة للـnull terminator). تقوم دالة getline بقراءة الأحرف حتى تواجه حرف السطر الجديد ('\n') أو تصل إلى الحد المحدد.
باختصار، يتيح هذا البرنامج للمستخدم إدخال سطرين من النص، يصل طول كل منهما إلى 9 أحرف، ثم يقوم بطباعة الأسطر المدخلة. استخدام cin.getline() يضمن قراءة الإدخال كخط، ويتجنب البرنامج المشكلات المحتملة مع المخزن المؤقت للإدخال.
مثال 5:
#include <iostream> #include <cstring> using namespace std; int main() { char a1[] = "A"; char a2[] = "B"; cout << strcmp(a1, a2); return 0; }
يقوم برنامج C++ هذا بمقارنة نصين باستخدام الدالة strcmp من مكتبة C القياسية.
يتضمن هذا الرمز ملفات الـheader الضرورية لعمليات الإدخال/الإخراج (iostream) والدوال المرتبطة بالنص(cstring). يتم تضمين cstring للدالة strcmp.
char a1[] = "A"; char a2[] = "B";
تعلن هذه الأسطر وتهيئ مصفوفتين من الأحرف، a1 وa2. يحتوي كل مصفوفة على حرف واحد ويتم إنهاؤه تلقائيًا بواسطة المترجم. تذكر أن النص في C/C++ هو في الأساس مجموعة من الأحرف المنتهية بالحرف الفارغ ('\0').
cout << strcmp(a1, a2);
يستخدم هذا السطر الدالة strcmp لمقارنة النصوص المخزنة في a1 وa2. تتم طباعة النتيجة على شاشة المخرجات. ترجع الدالة strcmp قيمة عددية:
- إذا كانت النصوص متساوية، فإنها ترجع 0.
- إذا كانت a1 أقل من a2 من الناحية المعجمية، فإنها تُرجع قيمة سالبة.
- إذا كانت a1 أكبر من a2 من الناحية المعجمية، فإنها تُرجع قيمة موجبة.
تتم طباعة نتيجة المقارنة على شاشة المخرجات. سيكون هذا إما 0 إذا كانت النصوص متساوية، أو قيمة سالبة إذا كانت a1 أقل من a2، أو قيمة موجبة إذا كانت a1 أكبر من a2.
مصفوفات متعددة الأبعاد:
C++ supports multi-dimensional arrays, which can be thought of as arrays of arrays. A 2D array, for example, can be declared and accessed like this:
int matrix[3][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };
نقاط إضافيّة:
تمرير المصفوفات إلى الدوالّ:
عند تمرير مصفوفة إلى دالة، تحتاج إلى استخدام المؤشرات. إليك مثال سريع:
void printArray(int arr[], int size) { for (int i = 0; i < size; ++i) { cout << arr[i] << " "; } }
مصفوفات مكتبة النماذج القياسية (STL):
للحصول على المزيد من الوظائف المتقدمة، فكر في استخدام فئة المصفوفة من مكتبة النماذج القياسية C++ (STL). ويوفر ميزات إضافية وفحوصات السلامة.
#include <array> std::array<int, 5> stlArray = {1, 2, 3, 4, 5};
مثال 6:
#include <iostream> #include <cstring> using namespace std; void search(int arr[], int s, int k) { bool g = false; for (size_t i = 0; i < s; i++) { if (arr[i] == k) g = true; } if (g) cout << "Found\n"; else cout << "Not Found\n"; } int main() { int arr[] = {22, 55, 88, 99, 1, 0, 7}; search(arr, 7, 55); return 0; }
يحدد هذا البرنامج دالة تسمى search تبحث عن قيمة محددة في مصفوفة أعداد صحيحة. تقوم الدالة الرئيسية بعد ذلك باستدعاء دالة search هذه للتحقق من وجود قيمة معينة في المصفوفة المحددة.
تأخذ الدالة المسماة search ثلاث( parameters): arr (مصفوفة أعداد صحيحة)، s (حجم المصفوفة)، وk (القيمة المطلوب البحث عنها).
يقوم بتهيئة المتغير المنطقي g إلى false، والذي سيتم استخدامه لتتبع ما إذا كانت القيمة k موجودة في المصفوفة.
ثم تتكرر الدالة عبر المصفوفة باستخدام حلقة for. إذا كان العنصر الحالي يساوي القيمة المستهدفة k، فإنه يضبط g على true.
بعد تنفيذ الحلقة، تتحقق من قيمة g وتطبع إما “Found” أو “Not Found” بناءً على ما إذا تم العثور على القيمة المستهدفة في المصفوفة.
تقوم الدالة الرئيسية بتهيئة مصفوفة عددية تحتوي على قيم.
ثم يستدعي دالة search، ويمرر المصفوفة، وحجم المصفوفة (7)، والقيمة المطلوب البحث عنها (55).
اعتمادًا على ما إذا كانت القيمة 55 موجودة في المصفوفة، سيقوم البرنامج بإخراج إما "Found" أو "Not Found".
مثال 7:
#include <iostream> using namespace std; void sort(int arr[], int s) { int t; for (size_t i = 0; i < s - 1; i++) { for (size_t j = 0; j < s - 1; j++) { if (arr[j] > arr[j+1]) { t = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = t; } } } } int main() { int t; int arr[] = {22, 55, 88, 99, 1, 0, 7}; sort(arr, 7); for (size_t i = 0; i < 7; i++) { cout << arr[i] << " "; } return 0; }
يطبق هذا البرنامج خوارزمية فرز بسيطة تُعرف باسم Bubble Sort.
تطبق دالة الفرز خوارزمية فرز الفقاعات لفرز مجموعة من الأعداد الصحيحة.
يأخذ (two parameters): arr (المصفوفة الصحيحة التي سيتم فرزها) وs (حجم المصفوفة).
تستخدم الدالة حلقات for متداخلة للتكرار عبر المصفوفة. تقارن الحلقة الداخلية العناصر المتجاورة وتتبادلها إذا كانت في ترتيب خاطئ، مما يدفع العنصر الأكبر نحو نهاية المصفوفة.
تتكرر العملية حتى يتم فرز المصفوفة بأكملها بترتيب تصاعدي.
تقوم الدالة الرئيسية بتهيئة مصفوفة عددية تحتوي على قيم.
ثم تقوم بعد ذلك باستدعاء وظيفة الفرز، وتمرير المصفوفة وحجمها (7)، والتي تقوم بفرز المصفوفة باستخدام خوارزمية فرز الفقاعات.
وأخيرًا، تتم طباعة المصفوفة التي تم فرزها باستخدام حلقة for.
سيقوم البرنامج بإخراج المصفوفة التي تم فرزها: 0 1 7 22 55 88 99
الخلاصة:
يعد إتقان المصفوفات في لغة C++ خطوة حاسمة لكي تصبح مبرمجًا ماهرًا. إنها بمثابة اللبنات الأساسية لهياكل البيانات والخوارزميات الأكثر تعقيدًا. إذا وجدت هذه المراجعة مفيدة، فلا تنس مراجعة مقاطع الفيديو التعليمية الخاصة بنا على [Adel Nasim] للحصول على أمثلة عملية وأفكار عملية.