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

    يک اشاره گر به تابع حاوی آدرس آن تابع در حافظه می باشد . همانطور که می دانيد نام يک آرايه در واقع آدرس اولين عنصر آرايه در حافظه می باشد. مشابهاً ، نام يک تابع ، آدرس ابتدای کدهای يک تابع ، در حافظه می باشد . اشاره گر به يک تابع می تواند به عنوان آرگومان به توابع ارسال شود ، به عنوان خروجی تابعی برگردانده شود، در آرايه قرار گيرد و يا به تابعی ديگر اشاره داده شود.

   برای آشنايی با نحوه کاربرد اشاره گرهای توابع، برنامه مرتب کردن حبابی عناصر آرايه را بازنويسی می کنيم. اين برنامه دارای توابع ascending ، swap ،bubble و descending می باشد . تابع bubble يک اشاره گر تابع را به عنوان آرگومان ، همراه با آرايه و عدد ثابتی به عنوان طول آرايه ، دريافت می کند .

   اين اشاره گر به تابع ، اشاره گری به يکی از توابع ascending يا descending می باشد که اين دو تابع نحوه مرتب شدن آرايه را از نظر صعودی يا نزولی بودن تشخيص می دهند. برنامه در ابتدا از کاربر نحوه مرتب کردن عناصر را که به صورت صعودی مرتب شوند يا نزولی ، می پرسد . اگر کاربر عدد 1 را وارد کند ، يک اشاره گر به تابع ascending به عنوان آرگومان، به تابع bubble ارسال می شود که باعث می شود عناصر آرايه به صورت صعودی مرتب شوند. و اگر کاربر عدد 2 را وارد کند ، يک اشاره گر به تابع descending به عنوان آرگومان، به تابع bubble ارسال می گردد که باعث می شود عناصر آرايه به صورت نزولی مرتب شوند. به کدهای اين برنامه توجه کنيد :

#include <iostream.h>
 
void bubble( int [], const int, int (*)( int, int ) );
void swap( int * const, int * const );
int ascending( int, int );
int descending( int, int );
 
void main()
{
  const int arraySize = 10;
  int order;
  int counter;
  int a[ arraySize ] = { 2, 6, 4, 8, 10,
                         12, 89, 68, 45, 37 };
 
  cout << "Enter 1 to sort in ascending order,\n"
       << "Enter 2 to sort in descending order: ";
  cin >> order;
  cout << "\nData items in original order\n";
 
  for ( counter = 0; counter < arraySize; counter++ )
    cout << " " << a[ counter ];
 
  if ( order == 1 ) {
    bubble( a, arraySize, ascending );
    cout << "\nData items in ascending order\n";
  }
  else {
    bubble( a, arraySize, descending );
    cout << "\nData items in descending order\n";
  }
 
  for ( counter = 0; counter < arraySize; counter++ )
    cout << " " << a[ counter ];
 
  cout << endl;
}
 
void bubble( int work[], const int size,
             int (*compare)( int, int ) )
{
  for ( int pass = 1; pass < size; pass++ )
    for ( int count = 0; count < size-1; count++)
      if ( (*compare)( work[count], work[count + 1]))
        swap( &work[ count ], &work[count + 1]);
}
 
void swap( int * const element1Ptr, 
           int * const element2Ptr )
{
  int hold = *element1Ptr;
  *element1Ptr = *element2Ptr;
  *element2Ptr = hold;
}
 
int ascending( int a, int b )
{
  return b < a;
}
 
int descending( int a, int b )
{
  return b > a;
}

 خروجی برنامه فوق به صورت زير می باشد :

Enter 1 to sort in ascending order,
Enter 2 to sort in descending order: 1
 
Data items in original order
  2  6  4  8  10  12  89  68  45  37
Data items in ascending order
  2  4  6  8  10  12  37  45  68  89
Enter 1 to sort in ascending order,
Enter 2 to sort in descending order: 2
 
Data items in original order
  2  6  4  8  10  12  89  68  45  37
Data items in descending order
  89  68  45  37  12  10  8  6  4  2

   همانطور که در برنامه ديديد آرگومان زير در تابع bubble مورد استفاده قرار گرفت :

int (*compare) (int , int)

   اين دستور به تابع bubble می گويد که آرگومانی که دريافت می کند، يک اشاره گر به تابعی می باشد که دو آرگومان از نوع عدد صحيح دريافت می کند و خروجی آن از نوع int می باشد.

   پرانتزهای به کار رفته در کنار compare* برای اينکه مشخص کنيم compare اشاره گری به يک تابع می باشد ، الزاميند. اگر پرانتزها را در کنار compare* به کار نبريم دستور زير را خواهيم داشت :

int *compare (int,int)

   که اين دستور ، تابعی را تعريف می کند که دو عدد صحيح را دريافت کرده و اشاره گری به مقداری از نوع int را به عنوان خروجی بر می گرداند .

   اين آرگومان در پيش تعريف تابع bubble به صورت زير می باشد :

int (*)(int,int)

   توجه داشته باشيد که تنها نوع داده ها مشخص شده است و نيازی به ذکر نام داده ها و آرگومانها نمی باشد .

   تابع ارسال شده به bubble توسط دستور زير فراخوانی می شود :

(*compare) (work[count],work[count+1])

   يکی ديگر از کاربردهای اشاره گرهای تابع در انتخاب يکی از موارد يک فهرست می باشد . برنامه از کاربر می خواهد که گزينه ای را از فهرستی انتخاب کند . هر گزينه به تابعی مرتبط است که با انتخاب آن گزينه ، تابع مرتبط به گزينه انتخاب شده ، اجرا می شود . اشاره گرهای به هر تابع ، در يک آرايه قرار می گيرند . در چنين حالتی همه اين توابع بايد ورودی و خروجی يکسانی از نظر نوع داده داشته باشند . انتخاب کاربر به عنوان انديسی از آرايه اشاره گرهای به توابع ، مورد استفاده قرار می گيرد و اشاره گر موجود در آرايه برای فراخوانی تابع مربوط استفاده می شود. در برنامه زير نحوه استفاده از آرايه ای از اشاره گرهای به توابع نشان داده شده است :

#include <iostream.h>
 
void function1( int );
void function2( int );
void function3( int );
 
int main()
{
  void(*f[ 3 ])(int)={function1, function2, function3};
 
  int choice;
 
  cout << "Enter a number between 0 and 2, 3 to end:";
  cin >> choice;
 
  while ( choice >= 0 && choice < 3 ) {
 
   (*f[ choice ])( choice ); 
 
    cout <<"Enter a number between 0 and 2, 3 to end:";
    cin >> choice;
  }
 
  cout << "Program execution completed." << endl;
 
  return 0;
}
 
void function1( int a )
{
  cout << "You entered " << a 
       << " so function1 was called\n\n";
}
 
void function2( int b )
{
  cout << "You entered " << b 
       << " so function2 was called\n\n";
}
 
void function3( int c )
{
  cout << "You entered " << c 
       << " so function3 was called\n\n";
}

خروجی برنامه فوق به صورت زير می باشد :

Enter a number between 0 and 2, 3 to end: 2
You entered 2 so function3 was called
 
Enter a number between 0 and 2, 3 to end: 0
You entered 0 so function1 was called
 
Enter a number between 0 and 2, 3 to end: 1
You entered 1 so function2 was called
 
Enter a number between 0 and 2, 3 to end: 3
Program execution completed.

   در برنامه فوق سه تابع با نامهای function1 و function2 و function3 که هر يک عدد صحيحی را به عنوان ورودی دريافت می کنند و خروجی ندارند ، تعريف شده است. دستور زير اشاره گرهای به اين سه تابع را در آرايه ای با نام f قرار می دهد .

void (*f[3]) (int) = {function1,function2,function3};

   همانطور که می بينيد نوع آرايه کاملاً مثل نوع توابع، تعريف شده است ، چون اين آرايه حاوی اشاره گرهايی به توابع می باشد . هنگامی که کاربر عددی را بين 0 تا 2 وارد می کند ، عدد وارد شده به عنوان انديس آرايه f استفاده می شود . لذا دستور زير :

(*f[choice]) (choice);

 باعث اجرای يکی از توابع آرایه f میشود و Choice به عنوان آرگومان به تابع ارسال میشود.

 

 

   معرفی کامپيوتروبرنامه نويسی

   ساختارهای کنترلی

   توابع

   آرايه ها

   اشاره گر ها و رشته ها

   کلاسها

   گرانبار کردن عملگر ها

 
 
 
   
 
 
 

حق کپی رایت محفوظ می باشد