void*
المؤشر العام (Generic Pointer) void*
void* مؤشر لا يرتبط بأي نوع بيانات محدّد — يستطيع الإشارة لأي شيء، لكن لازم تحوّله لنوع حقيقي قبل قراءة ما يشير إليه.
المترجم لا يعرف حجم أو نوع البيانات التي يشير إليها void*، لذلك لا يمكن الاشتقاق منه (*p) مباشرة ولا إجراء حساب مؤشّرات (p + 1) عليه قبل تحويله لنوع محدّد أولًا. هذا بالضبط ما يجعله مفيدًا: دوال المكتبة القياسية مثل malloc وqsort وmemcpy تتعامل مع void* لتقبل أي نوع بيانات دون تكرار نفس الدالة لكل نوع.
كل مؤشّر (int*، char*، struct Point*...) يتحوّل ضمنيًا إلى void* والعكس صحيح في C (بعكس C++ التي تتطلّب تحويلًا صريحًا بالاتجاه الآخر). هذا يسهّل كتابة malloc دون الحاجة لـ (int*) قبل النتيجة في C تحديدًا.
الصياغة
void *name = address; Type *typed = (Type *)name; // تحويل قبل الاشتقاق
📄 مثال
#include <stdio.h>
#include <stdlib.h>
int main(void) {
void *raw = malloc(sizeof(int));
int *num = (int *)raw; // تحويل صريح قبل الاستخدام
*num = 42;
printf("%d\n", *num);
free(raw);
return 0;
}أهم النقاط
| العنصر | الوظيفة |
|---|---|
| malloc/calloc | تُرجع void* لأنها لا تعرف نوع البيانات التي ستُخزَّن |
| qsort/bsearch | تستقبل مصفوفة كـ void* لتعمل مع أي نوع عناصر |
| التحويل الضمني | في C فقط: أي مؤشّر يتحوّل تلقائيًا إلى/من void* بدون cast صريح |
💡 نصائح عملية
- حوّل void* إلى النوع الصحيح فورًا بعد استلامه لتفادي أخطاء منطقية صامتة
- استخدمه في دوالك الخاصة لو أردت دالة عامة تعمل مع أكثر من نوع بيانات
⚠️ أخطاء شائعة
- محاولة الاشتقاق (*p) من void* مباشرة دون تحويل — خطأ ترجمة
- إجراء حساب مؤشّرات (p++) على void* — غير قياسي وغير مضمون بكل المترجمات
خصائص ذات صلة
🎓 تريد فهم الصورة الكاملة خطوة بخطوة؟ ابدأ من مسار C الكامل بالعربي.