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

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

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

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

التمرير بالقيمة ينشئ نسخة كاملة من البنية (struct) على المكدس (stack). بالنسبة لبنية صغيرة تحتوي على بضعة أعداد صحيحة، فإن هذا الأمر جيد. ولكن تخيل بنية تحتوي على مئات البايتات؛ فكل استدعاء دالة سيقوم بنسخ كل تلك البيانات:

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).

تعد نسخة المؤشر أكثر كفاءة لأنها تمرر فقط عنوان ذاكرة — عادةً ما يكون 8 بايت بغض النظر عن حجم الـ struct.

هذا هو السبب في أن مبرمجي لغة C يمررون الهياكل (structs) عبر المؤشرات (pointers) دائمًا تقريبًا. استخدم const عندما لا ينبغي للدالة تعديل البيانات، ومؤشرًا عاديًا عندما ينبغي لها ذلك. ستحصل على الكفاءة والوضوح في القصد معًا.

challenge icon

التحدي

سهل

لنقم ببناء وحدة Product توضح الفرق بين تمرير الهياكل (structs) بالقيمة (by value) وبالتأشير (by pointer). ستقوم بإنشاء دالتين للعرض—واحدة تستقبل الهيكل بالكامل كنسخة، والأخرى تستقبل مجرد مؤشر إليه.

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

  • product.h: قم بالتصريح عن هيكل Product بثلاثة أعضاء: char name[50]، و double price، و int quantity. قم أيضاً بالتصريح عن دالتين:
    • display_by_value — تأخذ Product بالقيمة وتطبع معلوماته
    • display_by_pointer — تأخذ const Product * وتطبع نفس المعلومات
    استخدم حراس التضمين (include guards) مع الرمز PRODUCT_H.
  • product.c: قم بتنفيذ كلتا الدالتين. لاحظ الفرق في الصيغة: نسخة التمرير بالقيمة تستخدم عامل النقطة (p.name)، بينما نسخة المؤشر تستخدم عامل السهم (p->name). يجب أن تطبع كلتا الدالتين بنفس التنسيق.
  • main.c: قم بإنشاء Product، ثم استدعِ كلتا دالتي العرض لتوضيح أنهما تنتجان مخرجات متطابقة على الرغم من استخدام أساليب معاملات مختلفة.

ستتلقى ثلاثة مدخلات: اسم المنتج (سلسلة نصية)، و السعر (double)، و الكمية (عدد صحيح).

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

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

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

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

على سبيل المثال، مع المدخلات 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 الخاص بـ struct
    
    // TODO: قم باستدعاء display_by_value مع Product
    
    // TODO: قم باستدعاء display_by_pointer مع مؤشر pointer إلى Product
    
    return 0;
}
quiz iconاختبر نفسك

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

جميع دروس Object Oriented Programming