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

تهيئة الـ Stack

جزء من قسم Object Oriented Programming في رحلة C على Coddy — الدرس 14 من 61.

ليس كل كائن يحتاج للعيش في الـ heap. عندما يكون الـ struct صغيراً وله عمر قصير، فإن تخصيصه على الـ stack يكون أبسط وأسرع — لا malloc، ولا free، ولا يوجد خطر من حدوث تسرب للذاكرة.

بدلاً من إرجاع pointer، يمكن لـ factory function إرجاع الـ struct بواسطة القيمة (by value). يتم نسخ الـ struct بالكامل إلى الـ caller:

typedef struct {
    int x;
    int y;
} Point;

Point create_point(int x, int y) {
    Point p;
    p.x = x;
    p.y = y;
    return p;
}

يتلقى المتصل نسخة مهيأة بالكامل:

Point origin = create_point(0, 0);
Point cursor = create_point(100, 50);
printf("Cursor: (%d, %d)\n", cursor.x, cursor.y);

لا توجد مؤشرات، ولا يلزم إجراء عملية تنظيف. عندما يخرج origin و cursor عن النطاق، يتم تدميرهما تلقائيًا.

يعمل هذا النهج بشكل أفضل مع الهياكل (structs) الصغيرة التي لا تحتوي على أعضاء مخصصة ديناميكيًا. بالنسبة للكائنات الأكبر حجمًا أو تلك التي تحتوي على مؤشرات إلى ذاكرة الكومة (heap memory)، يظل نمط المنشئ (constructor pattern) مع malloc هو الخيار الأفضل.

challenge icon

التحدي

سهل

لنقم ببناء وحدة Temperature تقوم بإنشاء قراءات لدرجة الحرارة على الـ stack باستخدام دالة مصنع (factory function). على عكس المنشئات (constructors) التي تعتمد على الـ heap في الدروس السابقة، فإن هذا النهج يعيد الـ struct بالقيمة (by value) — لا حاجة لـ malloc، ولا free، مجرد تخصيص بسيط وفعال على الـ stack.

ستقوم بإنشاء ثلاثة ملفات:

  • temperature.h: قم بالتصريح عن struct باسم Temperature يحتوي على عضوين: double celsius و char scale (لتخزين 'C' للدرجة المئوية). صرح أيضاً عن دالتين:
    • create_temperature — تأخذ قيمة double وتعيد struct من نوع Temperature بالقيمة (وليس مؤشراً!)
    • temperature_to_fahrenheit — تأخذ const Temperature * وتعيد درجة الحرارة المكافئة بالفهرنهايت كـ double
    استخدم حواجز التضمين (include guards) مع الرمز TEMPERATURE_H.
  • temperature.c: قم بتنفيذ كلتا الدالتين. يجب أن تقوم دالة المصنع بإنشاء متغير Temperature محلي، وتهيئة حقوله (تعيين scale إلى 'C')، وإعادته. صيغة التحويل هي: fahrenheit = celsius * 9.0 / 5.0 + 32.0
  • main.c: استخدم دالة المصنع لإنشاء قراءة لدرجة الحرارة وعرض قيمتي Celsius و Fahrenheit.

ستتلقى مدخلاً واحداً: درجة الحرارة بالسيلزيوس (كـ double).

في ملفك الرئيسي، استخدم create_temperature لإنشاء struct من نوع Temperature بالقيمة المعطاة. ثم اطبع قيمة Celsius الأصلية وما يعادلها بالفهرنهايت.

اطبع المخرجات بهذا التنسيق:

Celsius: {celsius}
Fahrenheit: {fahrenheit}

استخدم %.2f لكلتا القيمتين لعرض منزلتين عشريتين.

على سبيل المثال، مع مدخل 25.0، ستكون المخرجات:

Celsius: 25.00
Fahrenheit: 77.00

لاحظ مدى نظافة هذا النهج — فأنت تتلقى struct مهيأ بالكامل دون أي مخاوف تتعلق بإدارة الذاكرة. عندما يخرج متغير Temperature الخاص بك عن النطاق (scope)، يتم تنظيفه تلقائياً.

ورقة مرجعية

يمكن لدوال المصنع (Factory functions) إرجاع الهياكل (structs) بالقيمة بدلاً من المؤشرات. يقوم هذا بتخصيص الهيكل على المكدس (stack) — لا يوجد malloc، ولا free، ولا تسريبات للذاكرة.

مثال على دالة مصنع ترجع بالقيمة:

typedef struct {
    int x;
    int y;
} Point;

Point create_point(int x, int y) {
    Point p;
    p.x = x;
    p.y = y;
    return p;
}

استخدام دالة المصنع:

Point origin = create_point(0, 0);
Point cursor = create_point(100, 50);
printf("Cursor: (%d, %d)\n", cursor.x, cursor.y);

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

جرّب بنفسك

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

int main() {
    double celsius_input;
    scanf("%lf", &celsius_input);
    
    // TODO: استخدم create_temperature لإنشاء هيكل Temperature
    
    // TODO: اطبع قيمة Celsius باستخدام تنسيق %.2f
    
    // TODO: استخدم temperature_to_fahrenheit لتحويل وطباعة قيمة Fahrenheit
    
    return 0;
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس Object Oriented Programming