Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

نظرة عامة على المشروع

جزء من قسم البرمجة كائنية التوجه في رحلة C على Coddy. الدرس 44 من 61.

challenge icon

التحدي

سهل

لنضع الأساس لمشروع Shape Drawer من خلال إنشاء Shape struct الأساسي: واجهة تحدد ما يمكن لأي شكل القيام به عبر مؤشرات إلى functions.

ستنشئ ملفين لإعداد هذا النظام متعدد الأشكال:

  • shape.h: عرّف الواجهة الأساسية هنا. أولًا، أنشئ forward declaration لـ Shape struct. ثم عرّف نوعين من مؤشرات functions:
    • DrawFunc: يأخذ const Shape* parameter ولا يعيد شيئًا
    • AreaFunc: يأخذ const Shape* parameter ويعيد double
    أخيرًا، عرّف Shape struct نفسه، بحيث يحتوي على مؤشري functions: draw (من النوع DrawFunc) وarea (من النوع AreaFunc). يعمل هذا struct كواجهة فقط. فهو لا يحتوي على أي بيانات خاصة بالشكل، بل على السلوك فقط.
  • main.c: أثبت أن واجهتك تعمل من خلال إنشاء شكل اختبار بسيط. Implement دالتين:
    • test_draw: تطبع Drawing test shape
    • test_area: تعيد 42.0
    أنشئ instance من Shape، واربطه بـ test functions هذه، ثم استدعِ كليهما عبر الواجهة. اطبع نتيجة area بمنزلة عشرية واحدة.

يجب أن يوضح ناتجك أن مؤشرات functions تعمل بشكل صحيح:

Drawing test shape
Area: 42.0

لماذا نحتاج إلى forward declaration؟ قد تتساءل عن سبب ظهور typedef struct Shape Shape; قبل تعريف struct بالكامل. هذا ضروري لأن DrawFunc وAreaFunc يشيران إلى const Shape* في أنواع parameter الخاصة بهما، ولكن في تلك النقطة من الملف، لم يرَ compiler تعريف struct الكامل بعد. يخبر forward declaration الـ compiler بأن: "a struct named Shape exists"، وهذا يكفي لاستخدام pointer إليه. يأتي التعريف الكامل لاحقًا. هذا النمط شائع في C عندما يحتاج struct إلى الإشارة إلى نفسه، سواء مباشرةً أو عبر مؤشرات functions.

الفكرة الأساسية هنا هي أن Shape لا يعرف أي شيء عن الدوائر أو المستطيلات. إنه يعرف فقط أن أي شكل يجب أن يكون قادرًا على draw نفسه وحساب area الخاصة به. في الدروس القادمة، ستنشئ أشكالًا ملموسة تدمج هذا struct الأساسي وتوفر Implement الخاصة بها. تذكّر استخدام include guards في ملف الرأس الخاص بك.

جرّب بنفسك

#include <stdio.h>
#include "shape.h"

// TODO: نفّذ دالة test_draw
// - تأخذ معامل const Shape*
// - Prints "Drawing test shape"
void test_draw(const Shape* shape) {
    // TODO: اطبع الرسالة المطلوبة
}

// TODO: نفّذ دالة test_area
// - تأخذ معامل const Shape*
// - تُرجع 42.0
double test_area(const Shape* shape) {
    // TODO: أرجع قيمة مساحة الاختبار
}

int main() {
    // TODO: أنشئ نسخة من Shape
    
    // TODO: اربط الشكل بدالتي test_draw و test_area
    
    // TODO: استدعِ draw عبر الواجهة
    
    // TODO: استدعِ area عبر الواجهة واطبع بقيمة عشرية واحدة
    // التنسيق: "Area: %.1f\n"
    
    return 0;
}

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم C عبر الإنترنت