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

مراجعة مؤشرات Void

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

إن void* هي طريقة لغة C لقول "مؤشر لشيء ما، لكنني لن أخبرك ما هو". يمكنه حمل عنوان أي نوع بيانات — int أو float أو struct أو أي شيء آخر. وهذا يجعله الأساس لكتابة كود عام (generic) في لغة C.

المشكلة هي أنه لا يمكنك إلغاء مرجعية (dereference) لـ void* مباشرة. فالمترجم (compiler) لا يعرف عدد البايتات التي يجب قراءتها أو كيفية تفسيرها. لاستخدام البيانات، يجب عليك تحويلها (cast) مرة أخرى إلى النوع الصحيح:

void print_int(void* data) {
    int* p = (int*)data;
    printf("%d\n", *p);
}

int main() {
    int x = 42;
    print_int(&x);
    return 0;
}

هذه المرونة تأتي مع المسؤولية. إذا قمت بالتحويل إلى نوع خاطئ، فلن يمنعك المترجم — ولكن برنامجك سينتج بيانات غير صحيحة أو سيتوقف عن العمل (crash). لهذا السبب، غالباً ما تقرن الدوال العامة void* بمؤشر نوع (مثل enum أو flag) حتى تعرف الدالة كيفية تفسير البيانات بشكل صحيح.

في الدروس القادمة، ستستخدم void* لبناء حاويات يمكنها تخزين أي نوع من البيانات، مما يتيح إنشاء هياكل بيانات قابلة لإعادة الاستخدام حقاً.

challenge icon

التحدي

سهل

اكتب دالة تسمى print_value تقبل معاملين: مؤشر void* للبيانات وعلم نوع (type flag) من نوع int. يجب أن تقوم الدالة بتفسير وطباعة البيانات بناءً على علم النوع:

  • إذا كان علم النوع هو 0، فقم بتحويل المؤشر إلى int* واطبع القيمة الصحيحة
  • إذا كان علم النوع هو 1، فقم بتحويل المؤشر إلى float* واطبع قيمة الفاصلة العائمة مع منزلتين عشريتين

سيتلقى برنامجك مدخلين:

  1. علم النوع (0 للعدد الصحيح، 1 للعدد العشري)
  2. قيمة عددية

بناءً على علم النوع، قم بتخزين القيمة في نوع المتغير المناسب، ثم استدعِ print_value مع مؤشر لهذا المتغير وعلم النوع.

مثال للمخرجات عندما تكون المدخلات 0 و 42:

42

مثال للمخرجات عندما تكون المدخلات 1 و 3.14:

3.14

مثال للمخرجات عندما تكون المدخلات 0 و -17:

-17

مثال للمخرجات عندما تكون المدخلات 1 و 99.5:

99.50

ورقة مرجعية

إن void* هو مؤشر عام يمكنه الاحتفاظ بعنوان أي نوع من أنواع البيانات. وهو يوفر المرونة لكتابة كود عام في لغة C.

لا يمكنك إلغاء مرجعية void* مباشرة — يجب عليك تحويله إلى النوع الصحيح أولاً:

void print_int(void* data) {
    int* p = (int*)data;
    printf("%d\n", *p);
}

int main() {
    int x = 42;
    print_int(&x);
    return 0;
}

غالباً ما تقرن الدوال العامة الـ void* بمؤشر نوع (مثل enum أو flag) لمعرفة كيفية تفسير البيانات بشكل صحيح. قد يؤدي التحويل إلى نوع خاطئ إلى سلوك غير محدد أو توقف البرنامج بشكل مفاجئ.

جرّب بنفسك

#include <stdio.h>

// TODO: اكتب دالة print_value الخاصة بك هنا


int main() {
    int type_flag;
    scanf("%d", &type_flag);
    
    if (type_flag == 0) {
        int int_value;
        scanf("%d", &int_value);
        
        // TODO: قم باستدعاء print_value مع مؤشر لـ int_value وعلامة النوع (type flag)
        
    } else if (type_flag == 1) {
        float float_value;
        scanf("%f", &float_value);
        
        // TODO: قم باستدعاء print_value مع مؤشر لـ float_value وعلامة النوع (type flag)
        
    }
    
    return 0;
}
quiz iconاختبر نفسك

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

جميع دروس Object Oriented Programming