PDA

مشاهده نسخه کامل : ارسال آرایه های یک بعدی به توابع در برنامه نویسی C



Security
16-11-07, 18:10
آرایه ها را نیز همچون سایر نوع داده ها می توان به یک تابع ارسال کرد. برای اینکار ابتدا باید تابع را بگونه ای تعریف کنیم که یک پارامتر از نوع آرایه را دریافت کند. فرض کنید تابعی بنام sumArray داریم که یک آرایه یک بعدی از اعداد صحیح را بعنوان ورودی دریافت می نماید و مجموع عناصر آن را باز می گرداند. تعریف این تابع بصورت زیر است:


int sumArray(int A[], int size) {
int i , sum = 0;
for (i=0; i< size; i++)
sum += A[i];
return(sum) ;
}

در تابع فوق، پارامتر A بعنوان یک آرایه از اعداد صحیح معرفی شده است. همانطور که می بینید، اندازه آرایه مشخص نشده است و این یک نکته مثبت است؛ چرا که تابع sumArray می تواند هر آرایه صحیحی را با هر اندازه ای دریافت نماید. درواقع حتی اگر اندازه آرایه را نیز مشخص نمایید، کامپایلر از آن صرفنظر خواهد کرد. دومین پارامتر، اندازه واقعی آرایه A را مشخص می نماید. معمولا توابع بگونه ای نوشته می شوند که هنگام ارسال یک آرایه به یک تابع، اندازه آن نیز بعنوان یک پارامتر ارسال گردد. درغیراینصورت مجبوریم در تابع اندازه مشخصی را برای آرایه در نظر بگیریم که باعث ایجاد محدودیت در ارسال آرایه های با اندازه دلخواه می گردد.

در هنگام فراخوانی تابع sumArray، برای ارسال آرایه موردنظر کافی است که تنها نام آرایه را بدون کروشه استفاده نماییم. البته اندازه واقعی آرایه نیز باید بعنوان دومین آرگومان به تابع ارسال شود.


void main() {
int data1[3] = {5, 10, 15};
int data2[5] = {1, 6, 4, 12, 5} ;
int sum1, sum2;
sum1 = sumArray(data1, 3);
sum2 = sumArray(data2, 5);
printf(“sum1 = %d\n”,sum1);
printf(“sum2 = %d\n”,sum2);
}

sum1 = 30
sum2 = 28

همانطور که در مثال فوق دیده می شود، تابع sumArray دوبار فراخوانی شده است. در بار اول یک آرایه با اندازه 3، و در دفعه دوم یک آرایه با اندازه 5 به آن ارسال شده است و تابع در هر دو مورد بدون هیچ مشکلی مجموع عناصر آرایه را باز گردندانده است.

نکته بسیار مهم، نحوه ارسال آرایه ها به توابع است. زبانC آرایه ها را توسط ارجاع به تابع ارسال می نماید (برخلاف انواع دیگر داده ها که درحالت عادی توسط مقدار به توابع ارسال می شدند). بدین معنا که در هنگام ارسال یک آرایه به تابع، بجای یک کپی از آرایه، خود آرایه ارسال می شود. در حقیقت در فصلهای بعدی خواهید دید که برای ارسال یک آرایه، آدرس اولین عنصر آن ارسال می گردد. لذا تابع می تواند از طریق این آدرس، به کلیه داده های آرایه اصلی دسترسی پیدا کند. اما چرا C در مورد آرایه ها به روش متفاوتی عمل می نماید؟ دلیل این مسئله آن است که معمولا یک آرایه حافظه بسیار زیادی را اشغال می کند، لذا تهیه یک کپی کردن از آن، نه تنها باعث اشغال حافظه می شود بلکه زمان زیادی را نیز صرف خواهد کرد. با ارسال آرایه ها توسط ارجاع در زمان و حافظه صرفه جویی زیادی صورت می گیرد.

اما آیا می توان یک آرایه را توسط مقدار به یک تابع ارسال کرد؟ متاسفانه خیر. اما اگر نگران تغییر سهوی آرایه ارسالی به یک تابع هستید می توانید آن را بگونه ای به تابع ارسال نمایید که تغییر آن در تابع ممکن نباشد. زبان C یک نحوه دیگر ارسال داده ها به توابع بنام ارسال توسط ارجاع ثابت می باشد. چنانچه در هنگام تعریف یک پارامتر از یک تابع، از کلمه کلیدی const استفاده شود، کامپایلر اجازه تغییر مقادیر آن پارامتر را در حین اجرای تابع نخواهد داد. با این ارسال آرایه ها بصورت ارجاع ثابت، می توانیم مانع از انجام تغییرات ناخواسته در آرایه شویم. مثال زیر نحوه انجام این کار را نشان می دهد.

برنامه ) برنامه ای بنویسید که با استفاده از یک تابع، اشتراک دو مجموعه را محاسبه و چاپ نماید.


void intersection(const int A[], int na, const int B[], int nb, int C[], int &nc) {
k = 0;
for (i=0; i< na; i++) {
sw = 1;
for (j=0; j< nb && sw; j++)
if (A[i] == B[j]) {
C[k] = A[i] ;
k ++;
sw = 0;
}
}
nc = k;
}
void printSet(int set[], int size) {
int i;
printf(“{ “) ;
for (i=0; i< size; i++)
printf(”%d ”,set[i]) ;
printf(“}\n”);
}

void main() {
int set1[5] = {5, 8, 3, 12, 20};
int set2[3] = {12, 16, 8} ;
int result[3] , resultSize ;
intersection(set1, 5, set2, 3, result, resultSize);
printf(“set 1 = “);
printSet(set1) ;
printf(“set 2 = “);
printSet(set2) ;
printf(“intersection = “);
printSet(result) ;
}

set1 = { 5 8 3 12 20 }
set2 = { 12 16 8 }
intersection = { 8 12 }

همانگونه که در مثال بالا دیده می شود، تابع intersection، دو مجموعه را بعنوان ورودی دریافت و اشتراک آنها را بعنوان خروجی باز می گرداند. آرایه های A و B بعنوان پارامترهای ورودی هستند که نماینده دو مجموعه اولیه هستند. از آنجا که لزومی ندارد مقادیر این دو آرایه در تابع تغییر نماید، بعنوان پارامتر ثابت (const) به تابع ارسال شده اند. اندازه این دو آرایه نیز به ترتیب در قالب پارامترهای na و nb ارسال شده است. اما آرایه C پارامتر خروجی است که اشتراک دو مجموعه را باز می گرداند، به همین دلیل بصورت ثابت تعریف نشده است. تابع intersection، اشتراک دو مجموعه را محاسبه و مجموعه حاصل را در پارامتر C و اندازه آن را در پارامتر nc قرار می دهد. از آنجا که هم پارامتر C (بدلیل اینکه یک آرایه است) و هم پارامتر nc (بدلیل استفاده از عملگر &) توسط ارجاع به تابع ارسال شده اند، تغییرات انجام شده در آنها (یعنی حاصل نهایی) به تابع فراخواننده منتقل خواهد شد.

در تابع اصلی ابتدا دو مجموعه بنامهای set1 و set2 تعریف شده و مقدار اولیه گرفته اند. سپس با استفاده از تابع intersection، اشتراک آنها محاسبه و حاصل در آرایه result و اندازه آن نیز در متغیر resultSize قرار گرفته است. سرانجام دو مجموعه اولیه و اشتراک آنها با فراخوانی تابع printSet چاپ شده اند.

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

منبع : prdev