نوع Vector قابل لإعادة الاستخدام
غلّف الحجم والسعة
نوع Vector قابل لإعادة الاستخدام درس مجاني في C Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C Academy 4 دروس في المجموع.
من الشيفرة المتفرقة إلى نوع
إن تمرير مؤشر وعدد وسعة في ثلاثة متغيرات منفصلة يعرّض الشيفرة للأخطاء.
لنجمعها في struct واحد: مصفوفة ديناميكية قابلة لإعادة الاستخدام تُسمّى غالبًا متجهًا. فهي تجمع البيانات ومعلومات إدارتها معًا.
بنية المتجه
يحتاج المتجه إلى ثلاثة حقول: مؤشر إلى البيانات، وعدد العناصر المستخدمة (len)، وعدد العناصر التي يمكن استيعابها قبل تغيير الحجم (cap).
typedef struct {
int *data;
size_t len;
size_t cap;
} Vec;تهيئة المتجه
يحتوي المتجه الفارغ على مؤشر بيانات يساوي NULL، وطول وسعة يساويان صفرًا. وتجعل دالة تهيئة صغيرة الغرض واضحًا.
void vec_init(Vec *v) {
v->data = NULL;
v->len = 0;
v->cap = 0;
}عملية الإضافة
تضيف vec_push عنصرًا واحدًا إلى النهاية. وإذا كان المتجه ممتلئًا، فإنها تضاعف السعة أولًا.
تعيد الدالة 0 عند النجاح و-1 عند فشل التخصيص، حتى يتمكن المستدعي من التصرف وفقًا لذلك.
int vec_push(Vec *v, int value) {
if (v->len == v->cap) {
size_t nc = v->cap ? v->cap * 2 : 4;
int *tmp = realloc(v->data, nc * sizeof(*v->data));
if (!tmp) return -1;
v->data = tmp;
v->cap = nc;
}
v->data[v->len++] = value;
return 0;
}قراءة العناصر
بما أن len يتتبع عدد العناصر المستخدمة، فإنك تكرّر من 0 إلى len - 1. قد تكون السعة أكبر، لكن تلك الخانات لم تصبح جزءًا من بياناتك بعد.
for (size_t i = 0; i < v->len; i++)
printf("%d\n", v->data[i]);تحرير المتجه
يمتلك المتجه مخزنه المؤقت في الذاكرة المُدارة، لذلك يحتاج إلى دالة تنظيف مقابلة. بعد التحرير، أعد ضبط الحقول حتى لا يُساء استخدام البنية.
void vec_free(Vec *v) {
free(v->data);
v->data = NULL;
v->len = v->cap = 0;
}جمع الأجزاء
ينشئ هذا البرنامج الكامل متجهًا، ويضيف إليه خمس قيم، ويطبعها، ثم يحرره بطريقة سليمة.
#include <stdio.h>
#include <stdlib.h>
typedef struct { int *data; size_t len, cap; } Vec;
int vec_push(Vec *v, int value) {
if (v->len == v->cap) {
size_t nc = v->cap ? v->cap * 2 : 4;
int *tmp = realloc(v->data, nc * sizeof(*v->data));
if (!tmp) return -1;
v->data = tmp; v->cap = nc;
}
v->data[v->len++] = value;
return 0;
}
int main(void) {
Vec v = {0};
for (int i = 0; i < 5; i++) vec_push(&v, i * 10);
for (size_t i = 0; i < v.len; i++) printf("%d\n", v.data[i]);
free(v.data);
return 0;
}التهيئة إلى الصفر باستخدام {0}
يؤدي كتابة Vec v = {0}; إلى ضبط كل حقل على الصفر، بما في ذلك مؤشر البيانات الذي يصبح NULL.
هذا اختصار مفيد يجعل المتجه جاهزًا لاستخدام vec_push من دون استدعاء دالة تهيئة صريحة.
Vec v = {0}; /* data=NULL, len=0, cap=0 */
vec_push(&v, 42);دالة get آمنة
يُعد الوصول إلى فهرس يتجاوز len خطأً. ويمكن لدالة وصول صغيرة التحقق من الحدود والإبلاغ عن الأخطاء، مقابل خسارة قدر بسيط من السرعة لتحقيق الأمان.
int vec_get(const Vec *v, size_t i, int *out) {
if (i >= v->len) return -1; /* out of range */
*out = v->data[i];
return 0;
}لماذا نتابع len وcap بشكل منفصل
تمثل cap مقدار الذاكرة المخصّصة، بينما تمثل len المقدار الذي تستخدمه فعليًا.
ويعني الاحتفاظ بسعة احتياطية أن معظم عمليات الإضافة لا تستدعي realloc. وهذا الفصل هو ما يجعل المتجه سريعًا ومرنًا في آن واحد.
تعميم النوع
يخزّن هذا المتجه قيمًا من النوع int. ولحفظ أنواع أخرى، يمكنك تغيير نوع العنصر أو تخزين void * مع حجم العنصر.
يبقى النمط نفسه، أي التهيئة والإضافة والتحرير، بغض النظر عما تخزّنه.
typedef struct {
double *data;
size_t len, cap;
} DVec; /* same shape, different element type */تحقّق سريع
اختبر مدى فهمك لنوع المتجه.
مراجعة
يجمع المتجه مؤشر البيانات وlen وcap في بنية واحدة.
تضاعف vec_push السعة عندما يمتلئ المتجه، وتحرر vec_free المخزن المؤقت وتعيد ضبط الحقول، بينما تهيّئ {0} المتجه بطريقة سليمة. ويتفوق هذا النمط القابل لإعادة الاستخدام على إدارة المتغيرات المتفرقة. التالي: التحرير بطريقة صحيحة وتجنّب التسريبات.
الأسئلة الشائعة
هل درس «نوع Vector قابل لإعادة الاستخدام» مجاني؟
نعم — نص درس «نوع Vector قابل لإعادة الاستخدام» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C Academy 4 دروس في المجموع.
ماذا ستتعلم في «نوع Vector قابل لإعادة الاستخدام»؟
غلّف الحجم والسعة تتمرن على C Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ C Academy؟
لا تُشترط خبرة سابقة. C Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «نوع Vector قابل لإعادة الاستخدام»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس C Academy هذا؟
نعم. كل درس في C Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- تخصيص مصفوفة
- التوسعة باستخدام realloc
- نوع Vector قابل لإعادة الاستخدام
- تحرير الذاكرة وتجنّب التسريبات