تهيئة الـ Stack
جزء من قسم البرمجة كائنية التوجه في رحلة C على Coddy. الدرس 14 من 61.
ليست كل الكائنات بحاجة إلى أن تعيش في الكومة. عندما يكون struct صغيرًا وعمره قصيرًا، فإن تخصيصه على المكدس يكون أبسط وأسرع: لا malloc، ولا free، ولا خطر حدوث تسرّبات في الذاكرة.
بدلًا من إرجاع مؤشر، يمكن لدالة factory إرجاع البنية بالقيمة. يتم نسخ البنية بأكملها إلى المستدعي:
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 عن النطاق، يتم تدميرهما تلقائيًا.
يعمل هذا الأسلوب بشكل أفضل مع البنى الصغيرة التي لا تحتوي على أعضاء مخصّصة ديناميكيًا. أما بالنسبة إلى الكائنات الأكبر أو تلك التي تحتوي على مؤشرات إلى ذاكرة الكومة، فيظل نمط المُنشئ باستخدام malloc هو الخيار الأفضل.
التحدي
سهللنَبْنِ وحدة Temperature تُنشئ قراءات Temperature على المكدس باستخدام factory function. بخلاف المُنشئات المعتمدة على الكومة من الدروس السابقة، يعيد هذا الأسلوب الـ struct بالقيمة: لا يوجد malloc ولا free، بل تخصيص بسيط وفعّال على المكدس.
ستُنشئ ثلاثة ملفات:
temperature.h: Declare struct من نوعTemperatureيضم عضوين:double celsiusوchar scale(لتخزين'C'من أجل Celsius). كما Declare دالتين:create_temperature: تأخذ قيمة من النوع double وتُعيد struct من نوعTemperatureبالقيمة (وليس pointer!)temperature_to_fahrenheit: تأخذconst Temperature *وتُعيد درجة الحرارة المكافئة بوحدة Fahrenheit كقيمة من النوع double
TEMPERATURE_H.temperature.c: Implement كلتا الدالتين. يجب أن تُنشئ factory function متغيرTemperatureمن النوع local، وتُهيّئ حقوله (اضبطscaleعلى'C')، ثم تُعيده. صيغة التحويل هي:fahrenheit = celsius * 9.0 / 5.0 + 32.0main.c: استخدم factory function لإنشاء قراءة لدرجة الحرارة وعرض قيمتي Celsius وFahrenheit.
ستتلقى input واحدًا: درجة الحرارة بوحدة Celsius (كقيمة من النوع double).
في ملف main، استخدم create_temperature لإنشاء struct من نوع Temperature بالقيمة المُعطاة. ثم اطبع قيمة Celsius الأصلية وما يعادلها بوحدة Fahrenheit.
اطبع الناتج بهذا التنسيق:
Celsius: {celsius}
Fahrenheit: {fahrenheit}استخدم %.2f لكلتا القيمتين لعرض منزلتين عشريتين.
على سبيل المثال، عند إدخال 25.0، سيكون الناتج:
Celsius: 25.00
Fahrenheit: 77.00لاحظ مدى نظافة هذا الأسلوب. تحصل على struct مهيّأ بالكامل من دون أي مخاوف متعلقة بإدارة الذاكرة. عندما يخرج متغير Temperature من النطاق، تُنظَّف الذاكرة تلقائيًا.
جرّب بنفسك
#include <stdio.h>
#include "temperature.h"
int main() {
double celsius_input;
scanf("%lf", &celsius_input);
// TODO: استخدم create_temperature لإنشاء هيكل Temperature
// TODO: اطبع قيمة السيلسيوس باستخدام تنسيق %.2f
// TODO: استخدم temperature_to_fahrenheit للتحويل وطباعة قيمة الفهرنهايت
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 عبر الإنترنت