مراجعة: المصفوفة العامة
جزء من قسم البرمجة كائنية التوجه في رحلة C على Coddy. الدرس 53 من 61.
التحدي
سهللنَبْنِ حاوية GenericArray: بنية بيانات مرنة يمكنها احتواء مزيج من الأعداد الصحيحة والسلاسل النصية في المجموعة نفسها باستخدام مؤشرات void*.
ستنظّم التعليمات البرمجية عبر ثلاثة ملفات:
generic_array.h: عرّف البنيةGenericArrayبثلاثة أعضاء: مصفوفةvoid**لاحتواء المؤشرات، وintللعدد الحالي، وintللسعة. صرّح بنماذج الدوال اللازمة لإنشاء الـ array، وإضافة العناصر، واسترداد العناصر حسب الفهرس، وتحرير الـ array.generic_array.c: نفّذ وظائف الحاوية:create_array: تخصّص ذاكرة لـ GenericArray بسعة ابتدائية معطاة، وتُهيّئ count إلى 0add_element: تخزّن مؤشرvoid*في الخانة التالية المتاحة وتزيد count (افترض أن السعة كافية)get_element: تُرجع قيمةvoid*عند الفهرس المحددfree_array: تحرّر مصفوفة items وبنية GenericArray نفسها
main.c: اعرض كيفية استخدام الـ generic array من خلال تخزين أعداد صحيحة وسلاسل نصية. اقرأ عدد العناصر المراد إضافتها، ثم اقرأ لكل عنصر مؤشر نوع (iللعدد الصحيح، وsللسلسلة النصية) متبوعًا بالقيمة. بعد إضافة جميع العناصر، Iterate عبر الـ array واطبع كل قيمة. بالنسبة للأعداد الصحيحة، اطبع الرقم مباشرةً. وبالنسبة للسلاسل النصية، اطبع النص مباشرةً.
سيستقبل برنامجك:
- عدد العناصر المراد إضافتها
- لكل عنصر: مؤشر نوع (
iأوs) متبوعًا بالقيمة
عند إضافة أعداد صحيحة، خصّص ذاكرة للعدد الصحيح وخزّن المؤشر. وعند إضافة سلاسل نصية، خصّص ذاكرة وانسخ السلسلة. وعند الاسترداد، أعد Cast إلى النوع appropriate للطباعة.
مهم: لتتبّع الأنواع بغرض الطباعة، يمكنك استخدام array متوازية بسيطة من مؤشرات النوع في main، أو تخزين محرف مؤشر النوع بجانب كل عنصر.
مثال على المخرجات عندما تكون المدخلات 3، ثم i 42، وs Hello، وi 100:
42
Hello
100مثال على المخرجات عندما تكون المدخلات 4، ثم s World، وs Generic، وi -5، وs Arrays:
World
Generic
-5
Arraysتذكّر استخدام include guards في ملف الترويسة. لا تحتاج الحاوية نفسها إلى معرفة الأنواع التي تخزّنها؛ فهي تحتفظ فقط بمؤشرات void*. وتقع مسؤولية معرفة النوع على عاتق التعليمات البرمجية التي تضيف العناصر وتستردها.
جرّب بنفسك
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "generic_array.h"
int main() {
int n;
scanf("%d", &n);
// TODO: أنشئ GenericArray بسعة n
// TODO: أنشئ مصفوفة متوازية لتتبع الأنواع (مصفوفة char بحجم n)
// TODO: لكل عنصر:
// - اقرأ مؤشر النوع (i أو s)
// - اقرأ القيمة
// - إذا كان عددًا صحيحًا: خصص ذاكرة لـ int، خزّن القيمة، أضف إلى المصفوفة
// - إذا كانت سلسلة نصية: خصص ذاكرة للسلسلة، انسخ القيمة، أضف إلى المصفوفة
// - خزّن مؤشر النوع في مصفوفتك المتوازية
// TODO: مرّ عبر المصفوفة واطبع كل عنصر
// - تحقق من النوع من مصفوفتك المتوازية
// - حوّل void* مرة أخرى إلى النوع المناسب واطبع
// TODO: حرّر كل الذاكرة المخصصة (الأعداد الصحيحة والسلاسل النصية والمصفوفة)
return 0;
}
جميع دروس البرمجة كائنية التوجه
1أساسيات البرمجة التركيبية
ملفات الترويسةحواجز التضمينملفات المصدرالدوال الساكنةمراجعة: آلة حاسبة تركيبية4التغليف (Encapsulation)
مفهوم الـ Opaque Pointersتعريف الـ Opaque Structsالـ Getters والـ Settersالتحقق من البيانات في الـ Settersملخص: الصندوق السري2الكائنات والأساليب
الـ Structs ككائناتمؤشر 'Self'صحة استخدام Constالمؤشر مقابل القيمةالأساليب المساعدةملخص: Point Manager5مشروع: حساب بنكي بسيط
إعداد المشروعتنفيذ الحساب3دورة حياة الكائن
نمط المنشئ (Constructor Pattern)نمط الهادم (Destructor Pattern)تهيئة الـ Stackالنسخ العميق (Deep Copy)مراجعة: String Wrapper6الوراثة عبر التركيب
تضمين الـ Structقاعدة العضو الأولالوصول إلى أعضاء الأبعملية الـ Upcastingمراجعة: هرمية الأشكال9مشروع: رسّام الأشكال
نظرة عامة على المشروعتنفيذ الدائرةتنفيذ المستطيلاستخدام تعدد الأشكالحاوية الأشكالتدرّب بنفسك: مترجم C عبر الإنترنت