دليل C++ Vector: فهم std::vector في CPP مع أمثلة عملية

دقائق القراءة: 6

يُعد Vector في لغة C++ من أهم البنى القياسية لتخزين البيانات الديناميكية بطريقة مرنة ومنظمة. وهو حل عملي يتفوق في كثير من الحالات على المصفوفات التقليدية arrays ذات الحجم الثابت، خصوصاً عندما يكون حجم البيانات غير معروف مسبقاً أو يتغير أثناء تشغيل البرنامج.

في هذا الدليل، ستتعرف على مفهوم std::vector في C++، وأسباب استخدامه، وطريقة إنشائه، وكيفية إضافة العناصر وحذفها والوصول إليها من خلال أمثلة واضحة ومناسبة للمبتدئين.

ما هو Vector في C++؟

تحتاج البرامج غالباً إلى تخزين مجموعات من البيانات، مثل:

  • قائمة بأسماء المستخدمين.
  • مجموعة أسعار المنتجات.
  • خيارات الدفع داخل تطبيق أو نظام.
  • سجل لنتائج أو قراءات أو قيم رقمية.

هنا يأتي دور std::vector، وهو template class ضمن مكتبة STL أو Standard Template Library. يوفّر هذا النوع من الحاويات وسيلة حديثة ومرنة لتخزين العناصر بترتيب متسلسل، مع إمكانية التوسع أو التقليص تلقائياً حسب الحاجة.

على عكس arrays في C وC++ التي يكون حجمها ثابتاً بعد تعريفها، فإن vector يدعم الحجم الديناميكي، ما يجعله مناسباً للتطبيقات التي تتغير فيها البيانات باستمرار.

لماذا يُفضّل استخدام std::vector؟

يُستخدم vector عندما تحتاج إلى التعامل مع بيانات تتغير أثناء التنفيذ، سواء بالإضافة أو الحذف أو إعادة التنظيم. وهو خيار مناسب عندما لا تعرف عدد العناصر مسبقاً عند كتابة البرنامج.

أهم مزايا Vector في C++

  • يدعم تغيير الحجم تلقائياً.
  • يُسهّل إدارة البيانات مقارنة بالمصفوفات التقليدية.
  • يسمح بالوصول إلى العناصر عبر الفهرسة indexing.
  • يوفّر دوال جاهزة ومفيدة مثل .size() و.push_back() و.pop_back().
  • يُعد جزءاً أساسياً من مكتبة STL القياسية.

إذا كان مشروعك يتطلب إضافة عناصر أو حذفها باستمرار، فغالباً سيكون std::vector أكثر ملاءمة من array.

كيفية إنشاء Vector في C++

لإنشاء vector، يجب أولاً تضمين المكتبة الخاصة به داخل الملف:

#include <vector>

وغالباً توضع بعد #include <iostream> أو مع بقية ملفات الترويسات header files.

الصيغة العامة لإنشاء vector هي:

std::vector<data_type> name(items);

شرح الصيغة العامة

  • std::vector: الكلمة المفتاحية المستخدمة لإنشاء الحاوية.
  • <data_type>: نوع البيانات التي سيخزنها vector مثل int أو double أو string أو char.
  • name: اسم المتغير.
  • (items): عدد العناصر الابتدائي، وهو جزء اختياري.

من المهم معرفة أن نوع البيانات داخل vector لا يمكن تغييره بعد تعريفه.

مثال على إنشاء vector فارغ

#include <iostream>
#include <vector>

int main() {
    // بدون تحديد عدد العناصر
    // تعريف vector باسم prices لتخزين أعداد عشرية
    std::vector<double> prices;
}

مثال على إنشاء vector بحجم ابتدائي

#include <iostream>
#include <vector>

int main() {
    // مع تحديد عدد العناصر
    // إنشاء vector باسم prices
    // سيخزن أعداداً عشرية
    // الحجم الابتدائي هو 10
    std::vector<double> prices(10);
}

استخدام using namespace std;

يمكنك الاستغناء عن كتابة std:: قبل vector إذا استخدمت:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<double> prices;
}

لكن من الناحية التنظيمية، يفضّل كثير من المطورين استخدام std:: بشكل صريح لتجنب تعارض الأسماء في المشاريع الكبيرة.

كيفية معرفة حجم Vector في C++

لمعرفة عدد العناصر الموجودة داخل vector، استخدم الدالة .size(). وهي من أكثر الدوال استخداماً عند التعامل مع الحاويات الديناميكية.

#include <iostream>
#include <vector>

int main() {
    std::vector<double> prices;

    // إرجاع حجم الـ vector
    std::cout << prices.size() << std::endl;
    // الناتج: 0
}

في هذا المثال، النتيجة ستكون 0 لأن vector لا يحتوي على أي عنصر عند إنشائه بشكل فارغ.

كيفية إضافة عناصر إلى Vector في C++

بما أن vector حاوية ديناميكية، فيمكنك إضافة عناصر إليه أثناء تشغيل البرنامج. ولإضافة عنصر في نهاية الحاوية، استخدم الدالة .push_back().

#include <iostream>
#include <vector>

int main() {
    std::vector<std::string> names;

    // إضافة عناصر باستخدام .push_back()
    names.push_back("Dionysia");
    names.push_back("Dimitra");
    names.push_back("George");
}

متى تكون .push_back() مفيدة؟

تكون هذه الدالة مثالية عندما تتلقى البيانات تدريجياً، مثل إدخال المستخدم أو قراءة بيانات من ملف أو API، حيث لا يكون العدد النهائي للعناصر معروفاً من البداية.

كيفية حذف عنصر من Vector في C++

لحذف آخر عنصر داخل vector، استخدم الدالة .pop_back(). هذه الدالة لا تحتاج إلى أي معاملات داخل الأقواس.

#include <iostream>
#include <vector>

int main() {
    std::vector<std::string> names;

    // إضافة عناصر باستخدام .push_back()
    names.push_back("Dionysia");
    names.push_back("Dimitra");
    names.push_back("George");

    // التحقق من الحجم
    std::cout << names.size() << std::endl;
    // الناتج: 3

    // حذف آخر عنصر
    names.pop_back();

    // التحقق من الحجم مرة أخرى
    std::cout << names.size() << std::endl;
    // الناتج: 2
}

تُستخدم .pop_back() عادة عندما تحتاج إلى إزالة العنصر الأخير فقط. وإذا كنت تريد حذف عناصر من منتصف vector أو من بدايته، فهناك دوال أخرى مثل .erase()، لكنها خارج نطاق هذا الدليل التمهيدي.

الفهرسة Indexing في Vectors

يخزن vector عناصره بترتيب متسلسل، ولذلك يمكن الوصول إلى كل عنصر من خلال فهرسه index. تبدأ الفهرسة من 0، أي أن:

  • العنصر الأول فهرسه 0.
  • العنصر الثاني فهرسه 1.
  • العنصر الثالث فهرسه 2.

إسناد القيم باستخدام الفهرسة

#include <iostream>
#include <vector>

int main() {
    std::vector<std::string> names;

    names[0] = "Dionysia"; // إضافة النص في الموضع الأول
    names[1] = "Dimitra";  // إضافة النص في الموضع الثاني
    names[2] = "George";   // إضافة النص في الموضع الثالث
}

ملاحظة تقنية مهمة: هذا الأسلوب يبدو مباشراً، لكنه غير آمن إذا كان vector فارغاً ولم يتم تهيئة حجمه مسبقاً. لاستخدام الفهرسة بهذه الطريقة، يجب أن يكون vector قد أُنشئ بحجم مناسب أولاً، مثل std::vector<std::string> names(3);. أما إذا كان فارغاً، فالأفضل استخدام .push_back().

الوصول إلى العناصر وطباعتها

#include <iostream>
#include <vector>

int main() {
    std::vector<std::string> names(3);

    names[0] = "Dionysia";
    names[1] = "Dimitra";
    names[2] = "George";

    // طباعة كل عنصر في وحدة الإخراج
    std::cout << names[0] << std::endl; // Dionysia
    std::cout << names[1] << std::endl; // Dimitra
    std::cout << names[2] << std::endl; // George
}

مقارنة سريعة بين array وvector

الجانب array vector
الحجم ثابت ديناميكي
إضافة عناصر بعد الإنشاء محدودة سهلة عبر .push_back()
حذف العناصر أقل مرونة مدعوم بدوال مخصصة
الملاءمة للمشاريع الحديثة أقل في البيانات المتغيرة أفضل في معظم الحالات الديناميكية

أفضل الممارسات عند استخدام std::vector

  • استخدم .push_back() عندما لا يكون حجم البيانات معروفاً مسبقاً.
  • استخدم .size() قبل الوصول إلى العناصر عند الحاجة إلى التحقق من الحدود.
  • تجنب الكتابة إلى فهرس غير موجود داخل vector.
  • اختر vector بدلاً من array عندما تحتاج إلى مرونة أعلى.
  • احرص على أن يكون نوع البيانات مناسباً منذ البداية، لأن نوع vector لا يتغير بعد تعريفه.

الخلاصة التقنية

يُعتبر std::vector من أكثر الأدوات الأساسية أهمية في C++، لأنه يجمع بين سهولة الاستخدام والمرونة والكفاءة في إدارة البيانات المتغيرة. وإذا كنت تتعلم C++ أو تبني تطبيقاً يحتاج إلى تخزين عناصر يزيد عددها أو ينقص باستمرار، فإن فهم vector واستخدامه بشكل صحيح سيمنحك أساساً قوياً لكتابة كود أنظف وأكثر قابلية للتوسع. ومن الناحية العملية، يظل vector الخيار الافتراضي الأفضل في كثير من سيناريوهات البرمجة الحديثة مقارنة بالمصفوفات التقليدية.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *