استخدام sizeof() للتخصيص
جزء من قسم المنطق وتدفق التنفيذ في رحلة C على Coddy. الدرس 33 من 63.
مع أن malloc() تتيح لك تخصيص الذاكرة ديناميكيًا، فهناك ممارسة مهمة تُحسّن قابلية نقل الشيفرة وصيانتها: استخدام العامل sizeof() لتحديد عدد البايتات المراد تخصيصها.
يعيد العامل sizeof() عدد البايتات المطلوبة لتخزين نوع بيانات معيّن على نظامك. بدلًا من ترميز أحجام البايتات بشكل ثابت، يمكنك ترك sizeof() يحسب المقدار الصحيح تلقائيًا:
// بدلًا من تخمين الأحجام بالبايت:
int *ptr = (int*)malloc(4); // يفترض أن int حجمه 4 بايت
// استخدم sizeof() لضمان قابلية النقل:
int *ptr = (int*)malloc(sizeof(int)); // صحيح دائمًايصبح هذا النهج مفيدًا بشكل خاص عند تخصيص مصفوفات. لتخصيص مساحة لعدة عناصر، اضرب عدد العناصر في حجم كل عنصر:
// احجز مساحة لـ 10 أعداد صحيحة
int *arr = (int*)malloc(10 * sizeof(int));
// احجز مساحة لـ 5 قيم من نوع double
double *values = (double*)malloc(5 * sizeof(double));يضمن استخدام sizeof() عمل شفرتك بشكل صحيح على الأنظمة المختلفة، حيث قد تختلف أحجام أنواع البيانات، كما يوضح بجلاء قصدك بتخصيص مساحة لعدد محدد من العناصر من نوع معين.
التحدي
سهلاكتب برنامجًا بلغة C يوضّح الاستخدام الصحيح لـ sizeof() مع malloc() لتخصيص الذاكرة ديناميكيًا. ينبغي أن يقوم برنامجك بما يلي:
- قراءة عدد صحيح
nمن المستخدم يمثّل عدد العناصر المطلوب تخصيصها - استخدام
malloc()معsizeof()لتخصيص الذاكرة ديناميكيًا لمصفوفة تحتوي علىnقيم من النوع double - تحويل مؤشر void المُعاد إلى مؤشر double
- قراءة
nقيمة من النوع double من المستخدم وتخزينها في المصفوفة المخصّصة - حساب إجمالي الذاكرة المخصّصة بالبايت وطباعته بالتنسيق:
Memory allocated: [bytes] bytes - حساب متوسط جميع القيم وطباعته بدقتين عشريتين بالضبط بالتنسيق:
Average: [value] - العثور على أكبر قيمة وطباعتها بدقتين عشريتين بالضبط بالتنسيق:
Largest: [value]
تذكّر تضمين الترويسة <stdlib.h> لاستخدام malloc(). ينبغي أن يوضّح برنامجك كيف تضمن sizeof() تخصيص الذاكرة بشكل صحيح بغض النظر عن أحجام أنواع البيانات في النظام.
على سبيل المثال، إذا كان الإدخال:
3
2.5 7.8 4.1فينبغي أن يكون الناتج:
Memory allocated: 24 bytes
Average: 4.80
Largest: 7.80يعزّز هذا التحدي أهمية استخدام sizeof() لجعل تخصيص الذاكرة الديناميكي قابلًا للنقل وسهل الصيانة، إذ يحسب تلقائيًا العدد الصحيح من البايتات اللازمة لأي نوع بيانات على أي نظام.
جرّب بنفسك
#include <stdio.h>
#include <stdlib.h>
int main() {
// اقرأ عدد العناصر
int n;
scanf("%d", &n);
// TODO: اكتب الكود الخاص بك أدناه
// 1. خصّص ذاكرة لـ n من القيم من النوع double باستخدام malloc() وsizeof()
// 2. حوّل المؤشر المُعاد إلى النوع double*
// 3. اقرأ n من القيم من النوع double وخزّنها في المصفوفة المخصّصة
// 4. احسب حجم الذاكرة المخصّصة بالبايت واطبعه
// 5. احسب المتوسط واطبعه بمنزلتين عشريتين
// 6. اعثر على أكبر قيمة واطبعها بمنزلتين عشريتين
return 0;
}يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس المنطق وتدفق التنفيذ
1أساسيات المؤشرات
ما هو المؤشر؟الإعلان عن المؤشراتعامل العنوان (&)عامل إلغاء المرجعية (*)مؤشرات NULLمراجعة: أساسيات المؤشرات4مشروع: أداة نصوص بسيطة
نظرة عامة على المشروععد الأحرف2المؤشرات والمصفوفات
أسماء المصفوفات كمؤشراتعناصر المصفوفة - المؤشراتالعمليات الحسابية على المؤشراتمقارنة المؤشراتمراجعة: التنقل في المصفوفة باستخدام المؤشرات5المؤشرات والدوال
التمرير بالقيمةتمرير المؤشرات إلى الدوالتعديل المتغيرات عبر المؤشراتمثال كلاسيكي: التبديلتمرير المصفوفات إلى الدوالملخص: وسائط المؤشرات في الدوال8الهياكل والمؤشرات
المؤشرات إلى الهياكلعامل السهم (->)تمرير الهياكل بالقيمةتمرير مؤشرات الهياكلالتخصيص الديناميكي للهياكلمراجعة: تعديل الهياكل باستخدام المؤشرات11تحديات المراجعة النهائية
مراجعة: دمج السلاسل النصية الديناميكيمراجعة: مصفوفة من الـ Structsمراجعة: عداد تكرار الكلمات3مصفوفات الأحرف والسلاسل النصية
السلاسل النصية كمصفوفات charالمُنهي الصفري (Null Terminator)إدخال السلاسل النصية باستخدام scanfاستخدام strlen()استخدام strcpy()استخدام strcat()استخدام strcmp()مراجعة: دوال السلاسل النصية الأساسية6إدارة الذاكرة
ذاكرة Stack مقابل Heapالتخصيص الديناميكي - malloc()استخدام sizeof() للتخصيصالتحقق من فشل التخصيصتحرير الذاكرة باستخدام free()التخصيص باستخدام calloc()ملخص: المصفوفة الديناميكيةتدرّب بنفسك: مترجم C عبر الإنترنت