سؤال

لدي مكتبة قمت بإنشائها،

mylib.c:

#include <mylib.h>
int
testlib() {
    printf("Hello world\n");
    return (0);
}

mylib.h:

#include <stdio.h>
extern int testlib();

لقد حاولت في برنامجي استدعاء وظيفة المكتبة هذه:

myprogram.c:

#include <mylib.h>

int
main (int argc, char *argv[]) {
    testlib();
    return (0);
}

عندما أحاول ترجمة هذا البرنامج أحصل على الخطأ التالي:

In file included from myprogram.c:1
mylib.h:2 warning: function declaration isn't a prototype

أنا استخدم: gcc (GCC) 3.4.5 20051201 (Red Hat 3.4.5-2)

سؤالي هو: ما هي الطريقة الصحيحة للإعلان عن النموذج الأولي للوظيفة؟

هل كانت مفيدة؟

المحلول

شركة int foo() و int foo(void) هي وظائف مختلفة. int foo() يقبل عددًا عشوائيًا من الوسائط، بينما int foo(void) يقبل 0 وسيطة.في C++ يقصدون نفس الشيء.أقترح عليك استخدام void باستمرار عندما لا تقصد أي حجج.

إذا كان لديك متغير a, extern int a; هي طريقة لإخبار المترجم بذلك a هو رمز قد يكون موجودًا في وحدة ترجمة مختلفة (مترجم C يتحدث عن الملف المصدر)، لا تحله حتى وقت الارتباط.من ناحية أخرى، يتم حل الرموز التي هي أسماء الوظائف على أي حال في وقت الارتباط.معنى محدد فئة التخزين في دالة (extern, static) يؤثر فقط على رؤيتها و extern هو الافتراضي، لذلك extern غير ضروري في الواقع.

أقترح إزالة extern, ، فهو غريب وعادة ما يتم حذفه.

نصائح أخرى

جواب سريع:يتغير int testlib() ل int testlib(void) لتحديد أن الوظيفة لا تأخذ أي وسائط.

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

إعلان وظيفة غير النموذج الأولي مثل

int foo();

هو إعلان ذو نمط قديم لا يحدد عدد أو أنواع الوسائط.(قبل معيار ANSI C لعام 1989، كان هذا هو النوع الوحيد من إعلان الوظائف المتاح في اللغة.) يمكنك استدعاء مثل هذه الوظيفة مع أي عدد عشوائي من الوسائط، ولا يُطلب من المترجم تقديم شكوى - ولكن إذا كان المكالمة غير متوافقة مع تعريف, ، برنامجك لديه سلوك غير محدد.

بالنسبة للدالة التي تأخذ وسيطة واحدة أو أكثر، يمكنك تحديد نوع كل وسيطة في الإعلان:

int bar(int x, double y);

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

int foo(void); /* foo takes no arguments */

وظيفة تعريف (والذي يتضمن رمزًا لما تفعله الوظيفة بالفعل) يوفر أيضًا ملف تصريح.في حالتك، لديك شيء مشابه لما يلي:

int testlib()
{
    /* code that implements testlib */
}

يوفر هذا إعلانًا غير نموذجي لـ testlib.كتعريف، هذا يخبر المترجم بذلك testlib لا يحتوي على معلمات، ولكن كإعلان، فهو يخبر المترجم فقط بذلك testlib يأخذ بعض الأرقام والأنواع (الأنواع) غير المحددة ولكن الثابتة من الوسائط.

إذا قمت بالتغيير () ل (void) يصبح الإعلان نموذجًا أوليًا.

ميزة النموذج الأولي هي أنه إذا اتصلت عن طريق الخطأ testlib باستخدام وسيطة واحدة أو أكثر، سيقوم المترجم بتشخيص الخطأ.

(لدى C++ قواعد مختلفة قليلاً.لا تحتوي لغة C++ على إعلانات دوال ذات نمط قديم، والأقواس الفارغة تعني على وجه التحديد أن الدالة لا تأخذ أي وسائط.تدعم لغة C++ (void) بناء الجملة من أجل الاتساق مع C.ولكن ما لم تكن بحاجة إلى التعليمات البرمجية الخاصة بك على وجه التحديد لتجميعها كـ C وC++، فمن المحتمل أن تستخدم ملف () في C++ و (void) بناء الجملة في C.)

يحاول:

extern int testlib(void);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top