استخدام sizeof() للتخصيص
جزء من قسم Logic & Flow في رحلة 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 أعداد عشرية (doubles)
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() لجعل تخصيص الذاكرة الديناميكي الخاص بك قابلاً للنقل (portable) وسهل الصيانة، حيث يقوم تلقائياً بحساب العدد الصحيح من البايتات المطلوبة لأي نوع بيانات على أي نظام.
ورقة مرجعية
استخدم عامل sizeof() مع malloc() لتحديد العدد الصحيح من البايتات المراد تخصيصها لأي نوع بيانات:
// تخصيص ذاكرة محمول (Portable)
int *ptr = (int*)malloc(sizeof(int));
// تخصيص المصفوفات
int *arr = (int*)malloc(10 * sizeof(int));
double *values = (double*)malloc(5 * sizeof(double));يعيد عامل 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;
}يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس Logic & Flow
1أساسيات المؤشرات
ما هو المؤشر؟الإعلان عن المؤشراتعامل العنوان (&)عامل إلغاء المرجعية (*)مؤشرات NULLمراجعة: أساسيات المؤشرات4مشروع: أداة نصوص بسيطة
نظرة عامة على المشروععد الأحرف2المؤشرات والمصفوفات
أسماء المصفوفات كمؤشراتعناصر المصفوفة - المؤشراتالعمليات الحسابية على المؤشراتمقارنة المؤشراتمراجعة: التنقل في المصفوفة باستخدام المؤشرات5المؤشرات والدوال
التمرير بالقيمةتمرير المؤشرات إلى الدوالتعديل المتغيرات عبر المؤشراتمثال كلاسيكي: التبديلتمرير المصفوفات إلى الدوالملخص: وسائط المؤشرات في الدوال8الهياكل والمؤشرات
المؤشرات إلى الهياكلعامل السهم (->)تمرير الهياكل بالقيمةتمرير مؤشرات الهياكلالتخصيص الديناميكي للهياكلمراجعة: تعديل الهياكل باستخدام المؤشرات11تحديات المراجعة النهائية
مراجعة: دمج السلاسل النصية الديناميكيمراجعة: مصفوفة من الـ Structsمراجعة: عداد تكرار الكلمات3مصفوفات الأحرف والسلاسل النصية
السلاسل النصية كمصفوفات charالمُنهي الصفري (Null Terminator)إدخال السلاسل النصية باستخدام scanfاستخدام strlen()استخدام strcpy()استخدام strcat()استخدام strcmp()مراجعة: دوال السلاسل النصية الأساسية6إدارة الذاكرة
ذاكرة Stack مقابل Heapالتخصيص الديناميكي - malloc()استخدام sizeof() للتخصيصالتحقق من فشل التخصيصتحرير الذاكرة باستخدام free()التخصيص باستخدام calloc()ملخص: المصفوفة الديناميكية