وظائف كمعلمات في C

أعمل حاليًا على مشروع من فئة C للمقدمة ، فنحن ننتج بشكل أساسي تطبيق جدول تجزئة في C لكن سؤالي الحالي يتعلق بكيفية كتابة وظيفة معينة في الهيكل العظمي الشفوي الذي قدمه أستاذي. في ما يلي تعريف الرأس لطريقة الإنشاء:

     Table* create(long (*hash)(void* key),
          bool (*equals)(void* key1, void* key2),
          void (*print)(void* key1, void* key2));

يبدو أن هذه المؤشرات إلى وظائف كمعلمات؟ لست متأكدًا من كيفية استدعاء هذا ، أو ما يحدث عندما يتم استدعائه. أنا لست متأكدا حتى من أين تأتي هذه الأساليب (التجزئة والمساواة والطباعة). أي مساعدة سيكون موضع تقدير كبير. شكر

1
عندما يكون لديك مؤشر إلى وظيفة أو صفيف ، استخدم دائمًا typedef عندما يكون لديك الخيار. قد لا تكون في هذه الحالة ، ولكن ضعها في اعتبارك في المرة القادمة التي ترى فيها فوضى كهذه.
وأضاف المؤلف Mooing Duck, مصدر

8 إجابة

نعم ، هذه هي الدالة التي تأخذ ثلاثة مؤشرات دالة كوسيطات وتقوم بإرجاع المؤشر إلى جدول. لاستخدامها ، يجب عليك تحديد ثلاث وظائف تستوفي المعايير المعطاة:

long my_hash(void *key) { ... }
bool my_equals(void *key1, void *key2) { ... }
void my_print(void *key1, void *key2) { ... }

ثم استدعاء الدالة معهم:

t = create(my_hash, my_equals, my_print);

يبدو هذا وكأنه يهدف إلى إنشاء جدول تجزئة ، ويجب أن تعطيه وظيفة هاش وظيفة مقارنة. من المحتمل أن تكون وظيفة الطباعة من أجل التصحيح فقط.

2
وأضاف

نعم ، هذه هي الدالة التي تأخذ ثلاثة مؤشرات دالة كوسيطات وتقوم بإرجاع المؤشر إلى جدول. لاستخدامها ، يجب عليك تحديد ثلاث وظائف تستوفي المعايير المعطاة:

long my_hash(void *key) { ... }
bool my_equals(void *key1, void *key2) { ... }
void my_print(void *key1, void *key2) { ... }

ثم استدعاء الدالة معهم:

t = create(my_hash, my_equals, my_print);

يبدو هذا وكأنه يهدف إلى إنشاء جدول تجزئة ، ويجب أن تعطيه وظيفة هاش وظيفة مقارنة. من المحتمل أن تكون وظيفة الطباعة من أجل التصحيح فقط.

2
وأضاف

يبدو أن هذه مؤشرات على الدالات كمعلمات؟

نعم فعلا.

لست متأكدًا من كيفية استدعاء هذا

لاستدعاء الدالة create ، قم بتمرير عناوين بعض الوظائف ذات الأنواع الصحيحة للاتصال create :

create(&f1, &f2, &f3);

أو ما يحدث عندما يتم الاتصال به.

أي مكان في نص ينشئ حيث (*) يتم استدعاء الدالة المدببة ، فإن الوظيفة الفعلية (على سبيل المثال f1 ) ينتهي بها الأمر مع الوسيطات المقدمة. يمكن أن يكون (* يساوي) (k1 ، k2) ؛ كمثال خيالي يمكن أن يحدث داخل create .

(*) أو ، في هذه الحالة ، دالة أخرى ستحصل على مؤشرات الدالة من البنية المخصصة بواسطة إنشاء حيث سيتم تخزينها


في الحقيقة C تسمح لك بكتابة create (f1، f2، f3)؛ في الحالة الأولى و يساوي (k1، k2) ؛ في الثانية ، ولكن هذا مجرد السهولة أو الراحة.

2
وأضاف
DanielMoody مؤشرات الدالة هي غريبة في C ، لأنها تحول تلقائيًا في كلا الاتجاهين. لا أعرف ما إذا كان يجب أن أخبرك بذلك ، ولكن انظر إلى المثال 4 في cs.berkeley.edu/~necula/cil/cil016.html . على أي حال ، ما عليك سوى اختيار نمط واحد أنت مرتاح بين create (& f1…/(* equal)) (k1 ... و create (f1 .../equals (k1 ... ومحاولة التمسك بها ، ولكن لا تفاجأ إذا لم تحصل على تحذيرات مترجم عند نسيان & أو * لمؤشر دالة أو وظيفة.
وأضاف المؤلف Pascal Cuoq, مصدر
نعم ، شكرا لك هذا يجعل الأمر أكثر منطقية. بناء جملة هذه النظرة غريبة جدا لم أكن أفعل معها ، أو حتى كيفية البحث عنها
وأضاف المؤلف Daniel Moody, مصدر

يبدو أن هذه مؤشرات على الدالات كمعلمات؟

نعم فعلا.

لست متأكدًا من كيفية استدعاء هذا

لاستدعاء الدالة create ، قم بتمرير عناوين بعض الوظائف ذات الأنواع الصحيحة للاتصال create :

create(&f1, &f2, &f3);

أو ما يحدث عندما يتم الاتصال به.

أي مكان في نص ينشئ حيث (*) يتم استدعاء الدالة المدببة ، فإن الوظيفة الفعلية (على سبيل المثال f1 ) ينتهي بها الأمر مع الوسيطات المقدمة. يمكن أن يكون (* يساوي) (k1 ، k2) ؛ كمثال خيالي يمكن أن يحدث داخل create .

(*) أو ، في هذه الحالة ، دالة أخرى ستحصل على مؤشرات الدالة من البنية المخصصة بواسطة إنشاء حيث سيتم تخزينها


في الحقيقة C تسمح لك بكتابة create (f1، f2، f3)؛ في الحالة الأولى و يساوي (k1، k2) ؛ في الثانية ، ولكن هذا مجرد السهولة أو الراحة.

2
وأضاف
DanielMoody مؤشرات الدالة هي غريبة في C ، لأنها تحول تلقائيًا في كلا الاتجاهين. لا أعرف ما إذا كان يجب أن أخبرك بذلك ، ولكن انظر إلى المثال 4 في cs.berkeley.edu/~necula/cil/cil016.html . على أي حال ، ما عليك سوى اختيار نمط واحد أنت مرتاح بين create (& f1…/(* equal)) (k1 ... و create (f1 .../equals (k1 ... ومحاولة التمسك بها ، ولكن لا تفاجأ إذا لم تحصل على تحذيرات مترجم عند نسيان & أو * لمؤشر دالة أو وظيفة.
وأضاف المؤلف Pascal Cuoq, مصدر
نعم ، شكرا لك هذا يجعل الأمر أكثر منطقية. بناء جملة هذه النظرة غريبة جدا لم أكن أفعل معها ، أو حتى كيفية البحث عنها
وأضاف المؤلف Daniel Moody, مصدر

يبدو أن هذه مؤشرات على الدالات كمعلمات؟

نعم فعلا. هذا صحيح.

لست متأكدًا من كيفية استدعاء هذا ، أو ما يحدث عندما يتم الاتصال به.

ستحتاج إلى استخدام الوظائف التي تلبي التوقيع ures من المعلمات والاتصال إنشاء باستخدام هذه الوظائف. مثال:

long myHashFunction(void* key) {...}
bool myEqualsFunction(void* key1, void* key2) {...}
void myPrintFunction(void* key1, void* key2)) {...}


Table* table = create(myHashFunction, myEqualsFunction, myPrintFunction);

ما يمكن إنشاء يفعل مع هذه الدالة يعتمد فقط. ليس لدي أي فكرة عما يفعله معهم.

1
وأضاف

يبدو أن هذه مؤشرات على الدالات كمعلمات؟

نعم فعلا. هذا صحيح.

لست متأكدًا من كيفية استدعاء هذا ، أو ما يحدث عندما يتم الاتصال به.

ستحتاج إلى استخدام الوظائف التي تلبي التوقيع ures من المعلمات والاتصال إنشاء باستخدام هذه الوظائف. مثال:

long myHashFunction(void* key) {...}
bool myEqualsFunction(void* key1, void* key2) {...}
void myPrintFunction(void* key1, void* key2)) {...}


Table* table = create(myHashFunction, myEqualsFunction, myPrintFunction);

ما يمكن إنشاء يفعل مع هذه الدالة يعتمد فقط. ليس لدي أي فكرة عما يفعله معهم.

1
وأضاف

يجب أن يكون هذا تعليقًا - غبي جدًا للملاءمة

Those are function pointers:
          long (*hash)(void* key),  <- returns a long, uses a void * as input
          bool (*equals)(void* key1, void* key2), <- return 0 or 1            (True/False)
          void (*print)(void* key1, void* key2)); <- no return

بما أن هذه هي مؤشرات ، فإن أسماء الدوال الفعلية هي أسماء تقوم بإنشائها (أو ربما قام الأستاذ بإنشائها لك بأي اسم ، بما في ذلك التجزئة ، والمساواة ، والطباعة).

لكن "هاش" يعيد إزاحة إلى جدول تجزئة (ربما صفيف). "يساوي" اختبارات ما إذا كانت قيمتي إدخال هي نفس التجزئة - قد تكون التشابه ذاتية بحتة. اسأل أستاذك. تعرض الطباعة إدخال تجزئة ، بمعنى أفترض ، فإنه يعثر على إدخال وطباعة المعلومات في مجموعة أو كائن هاشم لقيمة المفتاح. ابحث عن "مجموعة النقابي" لمعرفة ما أقصده.

1
وأضاف
لا ينبغي عادةً نشر التعليقات كإجابات ، ولكن هذا ليس سيئًا كإجابة ، لذلك لم يتم الإبلاغ عنه أو تخفيضه.
وأضاف المؤلف Mooing Duck, مصدر

يجب أن يكون هذا تعليقًا - غبي جدًا للملاءمة

Those are function pointers:
          long (*hash)(void* key),  <- returns a long, uses a void * as input
          bool (*equals)(void* key1, void* key2), <- return 0 or 1            (True/False)
          void (*print)(void* key1, void* key2)); <- no return

بما أن هذه هي مؤشرات ، فإن أسماء الدوال الفعلية هي أسماء تقوم بإنشائها (أو ربما قام الأستاذ بإنشائها لك بأي اسم ، بما في ذلك التجزئة ، والمساواة ، والطباعة).

لكن "هاش" يعيد إزاحة إلى جدول تجزئة (ربما صفيف). "يساوي" اختبارات ما إذا كانت قيمتي إدخال هي نفس التجزئة - قد تكون التشابه ذاتية بحتة. اسأل أستاذك. تعرض الطباعة إدخال تجزئة ، بمعنى أفترض ، فإنه يعثر على إدخال وطباعة المعلومات في مجموعة أو كائن هاشم لقيمة المفتاح. ابحث عن "مجموعة النقابي" لمعرفة ما أقصده.

1
وأضاف
لا ينبغي عادةً نشر التعليقات كإجابات ، ولكن هذا ليس سيئًا كإجابة ، لذلك لم يتم الإبلاغ عنه أو تخفيضه.
وأضاف المؤلف Mooing Duck, مصدر