C Academy · درس

وحدات الماكرو stdarg

va_list وva_start وva_arg

الدرس 1 من 413 خطوة

وحدات الماكرو stdarg درس مجاني في C Academy على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C Academy 4 دروس في المجموع.

ما هي الدوال متغيرة الوسائط؟

تقبل الدالة متغيرة الوسائط عددًا متغيرًا من الوسائط. لقد استخدمتم واحدة من قبل: يمكن للدالة printf أن تستقبل أي عدد من القيم.

تتيح لكم C كتابة دوالكم الخاصة باستخدام وحدات الماكرو في <stdarg.h>.

#include <stdio.h>

int main(void) {
    printf("%d %d %d\n", 1, 2, 3);
    printf("%s\n", "any count of args");
    return 0;
}

علامة الحذف

تعرّفون الدالة متغيرة الوسائط باستخدام ... (علامة الحذف) بوصفها الوسيط الأخير.

يجب أن يسبقها وسيط واحد مسمّى على الأقل، حتى تعرف الدالة موضع بداية الجزء المتغير.

#include <stdio.h>
#include <stdarg.h>

void demo(int count, ...) {
    printf("This function takes %d extra args\n", count);
}

int main(void) {
    demo(3, 10, 20, 30);
    return 0;
}

تضمين stdarg.h

لقراءة الوسائط المتغيرة، تحتاجون إلى #include <stdarg.h>.

يعرّف هذا الملف النوع va_list ووحدات الماكرو va_start وva_arg وva_end.

#include <stdio.h>
#include <stdarg.h>

void show(int n, ...) {
    va_list args;
    va_start(args, n);
    va_end(args);
    printf("set up and cleaned up\n");
}

int main(void) {
    show(2, 5, 6);
    return 0;
}

va_list وva_start

عرّفوا متغيرًا من النوع va_list لتتبع الموضع الحالي. ثم استدعوا va_start(list, last) مع تمرير آخر وسيط مسمّى.

يوجّه ذلك القائمة إلى أول وسيط متغير.

#include <stdio.h>
#include <stdarg.h>

void first(int count, ...) {
    va_list args;
    va_start(args, count);
    int value = va_arg(args, int);
    printf("first variadic arg = %d\n", value);
    va_end(args);
}

int main(void) {
    first(1, 99);
    return 0;
}

va_arg: قراءة القيم

تعيد va_arg(list, type) الوسيطة التالية وتقدّم القائمة. يجب أن تحددوا لها النوع الدقيق المراد قراءته.

ينقل كل استدعاء الموضع إلى الأمام بمقدار وسيطة واحدة.

#include <stdio.h>
#include <stdarg.h>

void three(int n, ...) {
    va_list args;
    va_start(args, n);
    int a = va_arg(args, int);
    int b = va_arg(args, int);
    int c = va_arg(args, int);
    printf("%d %d %d\n", a, b, c);
    va_end(args);
}

int main(void) {
    three(3, 7, 8, 9);
    return 0;
}

va_end: التنظيف

استدعِ va_end(list) دائمًا عند الانتهاء من القراءة. فهو ينفّذ أي عمليات تنظيف تحتاج إليها المنصة.

يؤدي نسيان ذلك إلى سلوك غير محدد في بعض الأنظمة.

#include <stdio.h>
#include <stdarg.h>

int add_two(int dummy, ...) {
    va_list args;
    va_start(args, dummy);
    int sum = va_arg(args, int) + va_arg(args, int);
    va_end(args);
    return sum;
}

int main(void) {
    printf("%d\n", add_two(0, 4, 6));
    return 0;
}

معرفة عدد الوسائط

لا تستطيع وحدات الماكرو معرفة عدد الوسائط التي تم تمريرها. يجب أن توفّر هذه المعلومة بنفسك.

من الأساليب الشائعة إضافة وسيط عدد في البداية، كما في sum(3, a, b, c).

#include <stdio.h>
#include <stdarg.h>

int sum(int count, ...) {
    va_list args;
    va_start(args, count);
    int total = 0;
    for (int i = 0; i < count; i++)
        total += va_arg(args, int);
    va_end(args);
    return total;
}

int main(void) {
    printf("%d\n", sum(4, 1, 2, 3, 4));
    return 0;
}

استخدام قيمة حارسة

هناك طريقة أخرى لتحديد النهاية، وهي استخدام قيمة حارسة: قيمة خاصة لإنهاء القائمة يجب على المستدعي تضمينها، مثل -1 أو NULL.

كرّر الحلقة حتى تقرأ القيمة الحارسة.

#include <stdio.h>
#include <stdarg.h>

int sum_until_neg(int first, ...) {
    va_list args;
    va_start(args, first);
    int total = first, v;
    while ((v = va_arg(args, int)) != -1)
        total += v;
    va_end(args);
    return total;
}

int main(void) {
    printf("%d\n", sum_until_neg(10, 20, 30, -1));
    return 0;
}

ترقيات الوسائط الافتراضية

تخضع الوسائط المتغيرة لـترقيات افتراضية: تتحول char وshort إلى int، ويتحول float إلى double.

لذلك اقرأ الأعداد الصحيحة الصغيرة دائمًا باعتبارها int، والأعداد العشرية باعتبارها double باستخدام va_arg.

#include <stdio.h>
#include <stdarg.h>

void show_double(int n, ...) {
    va_list args;
    va_start(args, n);
    double d = va_arg(args, double);
    printf("%.2f\n", d);
    va_end(args);
}

int main(void) {
    show_double(1, 3.5f);
    return 0;
}

نسخ va_list

إذا احتجت إلى اجتياز الوسائط مرتين، فاستخدم va_copy(dest, src) لنسخ القائمة قبل القراءة.

لا يمكنك إعادة استخدام va_list بعد va_end من دون إعادة البدء باستخدام va_start.

#include <stdio.h>
#include <stdarg.h>

void twice(int n, ...) {
    va_list a, b;
    va_start(a, n);
    va_copy(b, a);
    printf("%d %d\n", va_arg(a, int), va_arg(b, int));
    va_end(a);
    va_end(b);
}

int main(void) {
    twice(1, 42);
    return 0;
}

حساب المتوسط

بدمج نمط العد مع قراءة الأعداد العشرية، يمكننا حساب متوسط قائمة من الأعداد الممررة كوسائط متغيرة.

#include <stdio.h>
#include <stdarg.h>

double average(int count, ...) {
    va_list args;
    va_start(args, count);
    double sum = 0;
    for (int i = 0; i < count; i++)
        sum += va_arg(args, double);
    va_end(args);
    return sum / count;
}

int main(void) {
    printf("%.2f\n", average(3, 2.0, 4.0, 6.0));
    return 0;
}

اختبار سريع

اختبر مدى فهمك لوحدات الماكرو الخاصة بـ stdarg.

مراجعة

لقد تعلمت آلية الوسائط المتغيرة:

  • صرّح بها باستخدام ... بعد وسيط مسمّى واحد على الأقل.
  • يبدأ va_start(list, last) العملية، ويقرأ va_arg(list, type)، وينفّذ va_end(list) عملية التنظيف.
  • لا تعرف وحدات الماكرو العدد — استخدم وسيط عدد أو قيمة حارسة.
  • انتبه إلى الترقيات الافتراضية: اقرأ الأعداد الصحيحة الصغيرة باعتبارها int، والأعداد العشرية باعتبارها double.
البدء مجانًا

تعلم C مع معلم ذكاء اصطناعي — مجانًا

اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.

الدورات
39
الدروس
144

الأسئلة الشائعة

هل درس «وحدات الماكرو stdarg» مجاني؟

نعم — نص درس «وحدات الماكرو stdarg» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C Academy 4 دروس في المجموع.

ماذا ستتعلم في «وحدات الماكرو stdarg»؟

va_list وva_start وva_arg تتمرن على C Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ C Academy؟

لا تُشترط خبرة سابقة. C Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.

كم من الوقت يستغرق درس «وحدات الماكرو stdarg»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس C Academy هذا؟

نعم. كل درس في C Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. وحدات الماكرو stdarg
  2. كتابة دوال شبيهة بـprintf
  3. مخاوف سلامة الأنواع
  4. أمثلة عملية
← العودة إلى C Academy