شرح - programiz c




وظيفة العودة نفسها (6)

بمعنى آخر ، هل من الممكن أن تعيد إحدى الوظائف نفسها؟

يعتمد ذلك على ما تعنيه بـ "نفسها" ؛ إذا كنت تقصد المؤشر لنفسه فإن الإجابة هي نعم! على الرغم من أنه من غير الممكن أن تقوم دالة ما بإرجاع نوعها ، يمكن أن تقوم الدالة بإرجاع المؤشر إلى نفسه ويمكن بعد ذلك تحويل هذا المؤشر إلى النوع المناسب قبل الاتصال.

يتم شرح التفاصيل في السؤال comp.lang.c faq: الدالة التي يمكنها إرجاع مؤشر إلى دالة من نفس النوع.

تحقق من answer للحصول على التفاصيل.

هل من الممكن أن تعلن بعض الوظائف func_t التي ترجع هذا النوع ، func_t ؟

بمعنى آخر ، هل من الممكن أن تعيد إحدى الوظائف نفسها؟

// func_t is declared as some sort of function pointer
func_t foo(void *arg)
{
  return &foo;
}

أو هل علي استخدام void * و typecasting؟


إذا كنت تستخدم C ++ ، يمكنك إنشاء نوع كائن State (افتراض استخدام مثال آلة الحالة) حيث تقوم بتعريف operator() الذي يقوم بإرجاع نوع عنصر State حسب المرجع أو المؤشر. يمكنك بعد ذلك تعريف كل حالة على أنها فئة مشتقة من State التي تقوم بإرجاع كل أنواع مشتقة أخرى مناسبة من تطبيق operator() .


حل ممكن مع البنيات:

struct func_wrap
{
    struct func_wrap (*func)(void);
};

struct func_wrap func_test(void)
{
    struct func_wrap self;

    self.func = func_test;
    return self;
}

تجميع مع دول gcc -Wall أعطى أي تحذيرات ، لكنني لست متأكدا ما إذا كان هذا هو 100 ٪ المحمولة.


لا ، لا يمكنك تعريف أنواع الدالة العودية في C. باستثناء داخل بنية (أو اتحاد) ، لا يمكن تعريف نوع متكرر في C.

الآن لحل void * ، لا يتم ضمان void * فقط لعقد المؤشرات على الكائنات وليس المؤشرات على الوظائف. القدرة على تحويل مؤشرات الدالة و void * متاح فقط كملحق.


ماذا عن شيء كهذا:

typedef void* (*takesDoubleReturnsVoidPtr)(double);

void* functionB(double d)
{
    printf("here is a function %f",d);
    return NULL;
}

takesDoubleReturnsVoidPtr functionA()
{
    return functionB;
}

int main(int argc, const char * argv[])
{
    takesDoubleReturnsVoidPtr func = functionA();
    func(56.7);
    return 0;
}

هناك طريقة ، يمكنك فقط محاولة هذا:

typedef void *(*FuncPtr)();

void *f() { return f; }

int main() {
    FuncPtr f1 = f();
    FuncPtr f2 = f1();
    FuncPtr f3 = f2();
    return 0;
}




function