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

المؤشر مقابل القيمة

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

عندما تمرّر struct إلى function، تمنحك C خيارين: تمريرها بالقيمة (نسخ struct بالكامل) أو تمريرها بواسطة pointer (نسخ address فقط). يؤثر هذا الاختيار بشكل كبير في الأداء.

التمرير بالقيمة ينشئ نسخة كاملة من البنية على المكدس. بالنسبة إلى بنية صغيرة تحتوي على بضعة أعداد صحيحة، فهذا مناسب. لكن تخيّل بنية تحتوي على مئات البايتات: every استدعاء function ينسخ كل تلك البيانات:

typedef struct {
    char name[100];
    int scores[50];
    double average;
} Student;

// بالقيمة: ينسخ ~308 بايت في كل استدعاء
void print_by_value(Student s) {
    printf("%s: %.2f\n", s.name, s.average);
}

// بالمؤشر: ينسخ فقط 8 بايت (العنوان)
void print_by_pointer(const Student *s) {
    printf("%s: %.2f\n", s->name, s->average);
}

تختلف الصياغة أيضًا. باستخدام معلمة قيمة، تستعمل عامل النقطة (s.name). وباستخدام مؤشر، تستعمل عامل السهم (s->name).

إصدار pointer أكثر كفاءة لأنه يمرر only عنوان address في الذاكرة، وعادةً ما يكون حجمه 8 bytes بغض النظر عن حجم البنية.

لهذا السبب يمرر مبرمجو C الهياكل دائمًا تقريبًا باستخدام pointer. استخدم const عندما لا ينبغي لـ function تعديل البيانات، واستخدم pointer عاديًا عندما ينبغي لها ذلك. ستحصل على الكفاءة والنية الواضحة معًا.

challenge icon

التحدي

سهل

لنبنِ وحدة Product توضّح الفرق بين تمرير البُنى بالقيمة وبواسطة pointer. ستنشئ اثنتين من function باسم display: واحدة تستقبل البنية كاملةً كنسخة، وأخرى تستقبل pointer إليها فقط.

ستنشئ ثلاثة ملفات:

  • product.h: Declare بنية Product تحتوي على ثلاثة members: char name[50] وdouble price وint quantity. Declare أيضًا اثنتين من function:
    • display_by_value: تستقبل Product بالقيمة وتطبع معلوماته
    • display_by_pointer: تستقبل const Product * وتطبع المعلومات نفسها
    استخدم حواجز التضمين بالرمز PRODUCT_H.
  • product.c: Implement كلتا function. لاحظ اختلاف الصياغة: إصدار التمرير بالقيمة يستخدم dot operator (p.name)، بينما يستخدم إصدار pointer arrow operator (p->name). يجب أن تطبع كلتا function بالتنسيق نفسه.
  • main.c: أنشئ Product، ثم استدعِ كلتا display function لإظهار أنهما تنتجان مخرجات متطابقة رغم استخدام أسلوبي معاملات مختلفين.

ستتلقى ثلاث inputs: اسم product (سلسلة نصية)، وprice (قيمة من النوع double)، وquantity (عدد صحيح).

في ملفك الرئيسي، قم بتهيئة Product بهذه القيم، ثم استدعِ display_by_value متبوعًا بـ display_by_pointer.

يجب أن تطبع كلتا function بهذا التنسيق:

Product: {name}, Price: {price}, Qty: {quantity}

استخدم %.2f من أجل price لعرض منزلتين عشريتين.

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

Product: Laptop, Price: 999.99, Qty: 5
Product: Laptop, Price: 999.99, Qty: 5

جرّب بنفسك

#include <stdio.h>
#include <string.h>
#include "product.h"

int main() {
    char name[50];
    double price;
    int quantity;
    
    // اقرأ المدخلات
    scanf("%s", name);
    scanf("%lf", &price);
    scanf("%d", &quantity);
    
    // TODO: أنشئ متغير Product وقم بتهيئته بقيم المدخلات
    // تلميح: استخدم strcpy لنسخ name إلى حقل name في الـ struct
    
    // TODO: استدعِ display_by_value مع الـ Product
    
    // TODO: استدعِ display_by_pointer مع مؤشر إلى الـ Product
    
    return 0;
}
quiz iconاختبر نفسك

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

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

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