For faster navigation, this Iframe is preloading the Wikiwand page for اشاره‌گر به تابع.

اشاره‌گر به تابع

یک اشاره‌گر به تابع (یا اشاره‌گر به روال)، نوعی اشاره‌گر است که در زبان‌های برنامه‌نویسی نسل سوم (همانند فرترن[۱]، کوبول و سی) و همین‌طور زبان‌های شی گرا (همانند سی++ و دی[۲]) پشتیبانی می‌شود. این نوع اشاره‌گر، به جای اشاره کردن به مقادیر داده‌ای، به قطعه کدی قابل اجرا در حافظه اشاره می‌کند. از طریق یک اشاره‌گر به تابع، می‌توان تابع مورد اشاره را به صورت غیرمستقیم فراخوانی کرده و آرگومان‌های تابع را هم دقیقاً مانند فراخوانی مستقیم (بدون استفاده از اشاره‌گر)، به تابع ارسال کرد. به عمل فراخوانی توابع به کمک یک اشاره‌گر، معمولاً تحت عنوان «فراخوانی غیر مستقیم» یاد می‌شود، چرا که به جای فراخوانی مستقیم تابع به وسیلهٔ یک نام ثابت یا یک آدرس، تابع با استفاده از یک متغیر و به صورت غیرمستقیم فراخوانی می‌شود. به کمک اشاره‌گر به تابع، می‌توان بر اساس مقادیر زمان اجرا، تابعی خاص را برای اجرا شدن انتخاب کرد و بدین ترتیب کد را ساده‌تر کرد.

ساده‌ترین پیاده‌سازی اشاره‌گر به تابع، متغیری است که حاوی آدرس یک تابع است و این تابع در داخل حافظه قرار دارد. زبان‌های قدیمی نسل سوم همانند کوبول و همچنین زبان‌های مدرنی مانند زبان سی، اشاره‌گر به تابع را به این صورت پیاده‌سازی کرده‌اند. در زبان‌های قدیمی‌تر، اشاره‌گر به توابع معمولاً نسبت به زبان‌های مدرن‌تر از ایمنی نوع کمتری برخوردارند. در زبان‌های مدرن، معمولاً در هنگام تعریف کردن یک اشاره‌گر به تابع، اطلاعات بیشتری راجع به نوع‌داده‌ها مشخص می‌شود، از جمله نوع مقدار برگشتی تابع، تعداد و نوع پارامترهای تابع و ... .[۳]

مثال در زبان سی

[ویرایش]

در زبان برنامه‌نویسی سی، اشاره‌گر به توابع، خیلی متداول نیستند. یک اشاره‌گر به تابع به شکل زیر اعلان می‌شود:[۴]

ret-type (*name) (arg1-type, arg2-type, ..., argn-type)
double (*fp) (double)

خط اول حالت کلی را نشان می‌دهد و خط دوم هم یک مثال است. در دستور دوم، اشاره‌گری به نام fp را اعلان می‌کند. این اشاره‌گر می‌تواند به تابعی اشاره کند که پارامتری از نوع double دارد و در برگشت هم مقداری از نوع double را برمی‌گرداند. برای اینکه اشاره‌گر بالا به تابعی اشاره کند، باید آدرس تابع مورد نظر در داخل اشاره‌گر قرار گیرد. در زبان سی، نام یک تابع، آدرس ابتدای محلی از حافظه است که کدهای تابع در آنجا قرار دارند؛ بنابراین برای مقدار دهی به یک اشاره‌گر به یک تابع (مثلاً sin()‎) می‌توان به صورت زیر عمل کرد.

fp = sin;

استفاده از اشاره‌گر به تابع، می‌تواند باعث شود کد کمی غیرقابل فهم شود، برای سادگی بیشتر، استفاده از typedefها برای اعلان اشاره‌گر به توابع بسیار رایج است.

typedef float (*funcp) (int)

funcp p1, p2;

در مثال بالا، p1 و p2، اشاره گر به تابعی هستند که پارامتری از نوع int دارد و مقداری از نوع float را برمی‌گرداند. می‌توان یک اشاره‌گر به تابع را به عنوان آرگومانی برای یک تابع دیگر ارسال کرد، آرایه‌ای از اشارگر به توابع داشت و ...

برنامه زیر، در داخل تابعی به نام compute_sum، از یک اشاره‌گر برای فراخوانی یکی از دو تابع sin یا cos استفاده می‌کند. اولین پارامتر تابع compute_sum یک اشاره‌گر به تابع است. برنامه زیر در داخل تابع main()‎، دو بار تابع compute_sum را فراخوانی می‌کند و در بار اول اشاره‌گری به sin()‎ و در بار دوم اشاره‌گری به cos()‎ برای compute_sum ارسال می‌کند. تابع compute_sum هم یکی از این دو تابع را به روشی غیرمستقیم و با داشتن اشاره‌گری به آن‌ها فراخوانی می‌کند.

# include <math.h>
# include <stdio.h>

/* Function taking a function pointer as an argument */
double compute_sum(double (*funcp)(double), double lo, double hi)
{
    double  sum = 0.0;

    /* Add values returned by the pointed-to function '*funcp' */
    for (int i = 0;  i <= 100;  i++)
    {
        double  x, y;

        /* Use the function pointer 'funcp' to invoke the function */
        x = i/100.0 * (hi - lo) + lo;
        y = (*funcp)(x);
        sum += y;
    }
    return (sum/100.0);
}

int main(void)
{
    double  (*fp)(double);      /* Function pointer */
    double  sum;

    /* Use 'sin()' as the pointed-to function */
    fp = sin;
    sum = compute_sum(fp, 0.0, 1.0);
    printf("sum(sin): %f\n", sum);

    /* Use 'cos()' as the pointed-to function */
    fp = cos;
    sum = compute_sum(fp, 0.0, 1.0);
    printf("sum(cos): %f\n", sum);
    return 0;
}

منابع

[ویرایش]
  1. Andrew J. Miller. "Fortran Examples". http://www.esm.psu.edu/~ajm138/fortranexamples.html. Retrieved 2013-09-14. ((cite web)): External link in |location= (help)نگهداری CS1: موقعیت (link)
  2. "The Function Pointer Tutorials". http://www.newty.de/: logo. Archived from the original on 16 May 2011. Retrieved 2011-04-13. Function Pointers are pointers, i.e. variables, which point to the address of a function ((cite web)): External link in |location= (help)
  3. "The Function Pointer Tutorials". http://www.newty.de/: logo. Archived from the original on 16 May 2011. Retrieved 2011-04-13. Important note: A function pointer always points to a function with a specific signature! Thus all functions, you want to use with the same function pointer, must have the same parameters and return-type! ((cite web)): External link in |location= (help)
  4. "Advanced Pointer Topics". Cs.cf.ac.uk. Retrieved 2013-10-09.
{{bottomLinkPreText}} {{bottomLinkText}}
اشاره‌گر به تابع
Listen to this article

This browser is not supported by Wikiwand :(
Wikiwand requires a browser with modern capabilities in order to provide you with the best reading experience.
Please download and use one of the following browsers:

This article was just edited, click to reload
This article has been deleted on Wikipedia (Why?)

Back to homepage

Please click Add in the dialog above
Please click Allow in the top-left corner,
then click Install Now in the dialog
Please click Open in the download dialog,
then click Install
Please click the "Downloads" icon in the Safari toolbar, open the first download in the list,
then click Install
{{::$root.activation.text}}

Install Wikiwand

Install on Chrome Install on Firefox
Don't forget to rate us

Tell your friends about Wikiwand!

Gmail Facebook Twitter Link

Enjoying Wikiwand?

Tell your friends and spread the love:
Share on Gmail Share on Facebook Share on Twitter Share on Buffer

Our magic isn't perfect

You can help our automatic cover photo selection by reporting an unsuitable photo.

This photo is visually disturbing This photo is not a good choice

Thank you for helping!


Your input will affect cover photo selection, along with input from other users.

X

Get ready for Wikiwand 2.0 🎉! the new version arrives on September 1st! Don't want to wait?