برگزیده های پرشین تولز

نحوه ارسال مقادير به تابع در سي پلاس پلاس

saalek

مدیر بازنشسته
تاریخ عضویت
24 می 2005
نوشته‌ها
654
لایک‌ها
53
محل سکونت
در پاي كوهپايه ها
الان فصل اشاره گرهاي ديتل را نگاه كردم. ديدم همراه با ارسال آرايه ، سايز آرايه را هم ارسال كرده به تابع.
طبيعي هم هست. چون بايد تابع بدونه كه تا كجا بايد بره جلو.
يعني هر ارايه دو مشخصه داره :
آدرس شروع و طول آرايه.
.
کد:
#include <iostream.h>

f( int * const  , const int );

  void main()
{
const int arraysize=5 ;
int a[arraysize]={12,24,55,21,44};
f(a,arraysize);

}

f( int * const array , const int size)
{
cout<<"array[0],array[1],array[2]= "<<array[0]<<","<<array[1]<<","<<array[2]<<endl;

}

.
 

saalek

مدیر بازنشسته
تاریخ عضویت
24 می 2005
نوشته‌ها
654
لایک‌ها
53
محل سکونت
در پاي كوهپايه ها

d4.jpg


در شكل بالا ، ارسال با مقدارby-value را مشاهده مي كنيم.
اين عكس را براي اين گذاشتم كه نشان مي دهد قبل ارسال يك كپي ساخته مي شود و به تابع ارسال مي شود.
منبع :
Beginning Visual C++ 6

داخل تابع تاكيد كرده كه به متغيرهاي value و index دسترسي ندارد. چون كپي ارسال شده.

== = = == = = = == = =
از همين كتاب طرز ارسال يك آرايه را مي بينيم.

کد:
 // Ex4_04.cpp
// Passing an array to a function
#include <iostream.h>

//Function prototype
double average(double array[], int count); 
int main(void)
{ 
  double values[] = { 1.0, 2.0, 3.0, 4.0,           
                  5.0, 6.0, 7.0, 8.0, 9.0, 10.0 };
cout << endl<< "Average = "<< average(values, (sizeof values)/(sizeof values[0]));
cout << endl; 
return 0;
}
// Function to compute an average
double average(double array[], int count)
{
   double sum = 0.0;                 // Accumulate total in here
   for(int i = 0; i<count; i++)
      sum += array[i];               // Sum array elements
	return sum/count;                 // Return average
}

از sizeof براي محاسبه اندازه آرايه استفاده شده است . كه اندازه آرايه را بر اندازه يك خانه آرايه تقسيم كرده.من حاصل اين تقسيم را چاپ كردم 10 بود كه برابر تعداد اعضاي آرايه است.

= = = == = = = == = = =
باز از همين كتاب طرز ارسال يك آرايه چند بعدي را داريم.

کد:
// Ex4_06.cpp
// Passing a two-dimensional array to a function
#include <iostream.h>

double yield(double array[][4], int n);
int main(void)
{
	[color=red]double beans[3][4][/color] =  {   { 1.0,  2.0,  3.0,  4.0 },
									  { 5.0,  6.0,  7.0,  8.0 },
									  { 9.0, 10.0, 11.0, 12.0 }   };
 cout << endl<< "Yield = "<< yield(beans, sizeof beans/sizeof beans[0]);
 cout << endl;
 return 0;
}
// Function to compute total yield
double yield([color=red]double beans[][4][/color], int count)
 {
	double sum = 0.0;
	for(int i=0; i<count; i++)
// Loop through number of rows
	for(int j=0; j<4; j++)
// Loop through elements in a row
	sum += beans[i][j];
	return sum;
 }

همين طور كه مي بينيد تابع دو ورودي دارد كه يكي اندازه آرايه است.و از آن داخل تابع به عنوان row يعني رديف استفاده شده.
.
 

Arash_j13

Registered User
تاریخ عضویت
18 فوریه 2005
نوشته‌ها
778
لایک‌ها
2
محل سکونت
مشهد
به کمک عملگر ... می شه توابعی نوشت که تعداد نا محدودی پارمتر بگیرن فقط کافی توی تعریف ابتدا پارامتر ها اجباری رو مانند تمام توابع دیگه تعیین کنید و در آخر قبل از بستن پرانتر یه پارمرت دیگه هم اضافه کنید پارمتر ... این طوری تابع می تونید علاوه برپارمتر ها اجباری هر چند تای دیگه که بخواد پارامتر اختیاری بگیره بدون محدودیت تعداد مثلا
کد:
int f(int,float,…);

اما خب چه جوری به اون پارمتر هایی که نام ندارن دسترسی داشت برای اینکار یکم باید با نحوه ارسال پارمتر ها در سی و ساختار Stack آشنا باشید پارمتر ها موقع ارسال برروی پشته قرار می گیرن سی بر خلاف بسیاری از زبان این پارمتر ها رو از راست به چپ روی پشته می زاره یه برعکس اونجوری که شما می نویسید مثلا در تابع test(1,2,3,4,5) اول 5 بعد 4 همین طوری 3و2و1و روی پشته قرار می گیرن بعد تابع فراخوانی می شه

پشته هم به صور برعکس پر می شه یعنی در شروع برنامه اشاره گر پشته (sp) در دقیقا در انتهای پشته قرار داره و با هر بار push کردن به عقب بر می گرده و از مقدارش کم می شه تا وقتی که به ابتدای پشته(ss) برسه و پشته پر بشه که در صورت تقاضا مجدد برای push کردن خطای stack overflow
رخ می ده

یه نکته خیلی جالبه اینکه این دوتا برعکس بودن هم دیگه رو خنثی می کنن و پامتر هرچی زودتر بیاد در ادرس کوچکتری از پشته قرار می گیره بعنی توی هون مثال بالا اگه از اول به پشته نگاه کنیم پامتر ها به همون صورتی که توی پرانتز نوشته شدن توی پشته قرار می گیره

وقتی که ماتابعی رو که با عملگز ... تعریف کردیم رو صدا کنیم هم همین روال به همین صورته ما اگه بدونیم که چند تا پارمتر ارسال شده و چه نوعی بوده می تونیم به تمام اون ها دسترسی داشته باشیم
فقط کافیه ادرس اولین پامتر رو که یک پارمتر اجباری باید باشه رو داشته باشیم و به تعداد پارمتر ها از این آدرس جلو بریم مثلا من یه تابع می نویسم که میانگین یه تعدادی عدد رو حساب می کنه پارمتر اول باید تعداد عدد ها باشه و پامتر های بعدی خود عدد ها
کد:
#include <iostream>
#include <cstdlib>
using namespace std;
int avg(int,...);

int main(int argc, char* argv[])
{
	cout<<avg(5,1,2,3,4,5)<<endl;
	system("pause");
	return 0;
}

int avg(int n,...)
{
	int *p=&n+1,i,s=0;
	for(i=0 ; i< n; ++i)
		s+=p[i];	
	return static_cast<double>(s)/n;
}
تو تابع avg یه شاره گر تعریف می کنیم که با پارامتر بعد از پامتر اول پارا متر دوم اشاره کنه بعد توی یه حلقه به تمام پامرت ها دسترسی پیدا می کنیم قبلا گفتم که پامتر به همون ترتیب روی پشته هستن پس وقتی از یک نوع هستن می شه مثل یه ارایه بهشون نگاه کرد این طوری ما می تونیم خیلی ساده به ارگومان ها دسترسی داشته باشم
 
بالا