در این قسمت، ابتدا به نحوه ارسال آرایه های دو بعدی به توابع می پردازیم و سپس آرایه های با ابعاد بالاتر می پردازیم.

شاید تصور کنید که برای تعریف یک آرایه دوبعدی بعنوان پارامتری از یک تابع، تنها قرار دادن دو علامت [] کافی است و نیازی به ذکر ابعاد آن نیست. اما متاسفانه اینگونه نیست، بلکه برنامه نویس باید تعداد ستونهای آرایه دوبعدی را صریحا مشخص نماید، اما نیازی به تعیین تعداد ردیفهای آن نیست. بعنوان مثال فرض کنید تابعی مانند test داریم که بعنوان ورودی یک آرایه دو بعدی و تعدادی پارامتر دیگر دریافت می کند. تعریف تابع بصورت زیر اشتباه است:

کد:
void test(int A[][], …) {
تعریف درست، تعریفی مانند زیر است:
کد:
void test(int A[][10] , …) {

همانطور که می بینید تعداد ردیفها مشخص نشده است، اما تعداد ستونها برابر 10 تعیین شده است. در هنگام فراخوانی تابع test، می توان هر آرایه دوبعدی 10 ستونی را به آن ارسال کرد. آرایه ارسالی به تابع می تواند 5×10 و یا 20×10 باشد، اما نمی تواند مثلا 5×20 باشد.

اکنون به 2 برنامه نمونه دقت کنید.

مثال) تابعي بنويسيد كه ميزان فروش تعدادي شركت در 12 ماه سال را بعنوان ورودي دريافت، و ميانگين فروش شركتي را كه بيشترين ميانگين فروش را داشته است، بازگرداند.

حل) با توجه به صورت مسئله مسلم است كه اين تابع بايد يك آرايه دو بعدي را بعنوان ورودي دريافت نمايد. رديفهاي اين آرايه به تعداد شركتهاي مورد نظر و ستونهاي آن برابر 12 (يك ستون براي هر ماه از سال) مي باشد. بنابراين كافيست تابع را بگونه اي تعريف نماييم كه يك آرايه 12 ستوني را بعنوان ورودي دريافت نمايد. حل دقيق بصورت زير است:

کد:
float maxSales(const long int sales[][12], int companyNo) {
int i,j;
float average , max;

max = 0.0;
for (i=0 ;i< companyNo; i++) {
average = 0;
for (j= 0;j<12; j++)
average += sales[i][j] ;

if (average > max) 
max = average ;
}
return(max);
}

مثال ) برنامه ای بنویسید که حاصلضرب دو ماتریس را با استفاده از یک تابع محاسبه نماید.

حل) برای حل این مسئله ابتدا باید تابعی بنویسیم که دو ماتریس را بعنوان ورودی دریافت و حاصلضرب آنها را بازگرداند. مسلما بهترین روش برای ذخیره هر ماتریس، استفاده از یک آرایه دوبعدی است. اما مشکل اینجا است که طبق تعاریف گفته شده، تعداد ستونهای آرایه های ورودی باید مشخص گردد و این باعث می شود که تابع نوشته شده محدود به ضرب ماتریسهای با تعداد ستونهای مشخصی گردد.

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

معمولا تعداد ستونهای واقعی آرایه دوبعدی بعنوان یک پارامتر مجزا به تابع ارسال می شود. به برنامه زیر دقت کنید:

کد:
const int maxCol = 10;

void multiply(const int A[][maxCol], const int B[][maxCol], int m,int p, int n, 
int C[][maxCol] ) {

for (i=0; i< m; i++) 
for (j=0; j< n; j++) {
sum = 0;
for (k= 0;k < p; k++) 
sum += A[i][k] * B[k][j] ;

C[i][j] = sum; 
}
}

void printMatrix(int matrix[][maxCol], int row,int col) {
int i,j;

for (i=0; i< row; i++) {
for (j=0; j< col ;j++)
printf(“%d ”,matrix[i][j]);
printf(“n”);
}
}

void main() {
int matrix1[2][maxCol] = { {7 ,3 , 2} , {-2, 6, 1} };
int matrix2[3][maxCol] = { {2 , 7 , -4, -1} , { 3 ,-3, 5, -8} , {6, -7, 2, 3} };
int result[2][maxCol] ;

multiply(matrix1, matrix2, 2, 3, 4, result);

printf(“matrix1 is :n”);
printMatrix(matrix1,2,3) ;
printf(“nmatrix2 is :n”);
printMatrix(matrix2,3,4) ;
printf(“nmultiply of matrix1 and matrix2 is :n”);
printMatrix(result,2,4) ;
}
matrix1 is : 
 7 3 2
-2 6 1
matrix2 is :
2  7 -4 -1
3 -3  5 -8
6 -7  2  3
multiply of matrix1 and matrix 2 is :
35  26 -9  -25
20 -39 40 -43

اگر به تابع multiply دقت كنيد، ابتدا دو ماتريس را بصورت ثابت دريافت مي كند (چرا كه مقادير ماتريسهاي اوليه نبايد عوض شود). سپس اندازه واقعي ماتريسها را در قالب سه پارامتر m، p و n دريافت مي نمايد، بدينصورت كه ماتريس اول m × p و ماتريس دوم p × n فرض شده است. مسلما ستونهاي ماتريس اول يعني p و ستونهاي ماتريس دوم يعني n، بايد كوچكتر از حداكثر تعداد ستونها يعني maxCol باشند. آخرين پارامتر نيز ماتريس حاصلضرب است كه خروجي تابع است (و بهمين دليل بصورت ثابت تعريف نشده است).

مسلم است كه اندازه ماتريس خروجي m × n خواهدبود و نيازي به بازگردندان ابعاد آن نيست. نحوه انجام عمليات ضرب نيز قبلا و در مبحث الگوريتمها تشريح شده است. و اما در تابع اصلي، ابتدا دو ماتريس matrix1 و matrix2 تعريف شده و مقدار اوليه گرفته اند. توجه كنيد كه گرچه ابعاد اصلي matrix1 برابر 2×3 است، اما از آنجا كه تابع multiply فقط ماتريسهايي را مي پذيرد كه تعداد ستونهاي آنها برابر maxCol يعني 10 باشد، مجبور شده ايم آن را بصورت 2×10 تعريف كنيم ولي از 7 ستون آخر استفاده نكنيم. بهمين دليل matrix2 نيز كه در حقيقت 3×4 بوده است، بصورت 3×10 تعريف شده است و ماتريس حاصلضرب يعني result نيز كه بايد 2×4 باشد، بصورت 2×10 تعريف شده است.

با اين تعاريف، مي توان بدون هيچ مشكلي تابع multiply را فراخواني كرد. در پايان نيز با استفاده از تابع printMatrix، ماتريسهاي اوليه و حاصلضرب آنها چاپ شده است. دقت كنيد كه تابع printMatrix نيز يك ماتريس با maxCol ستون را به همراه تعداد واقعي سطر و ستونهاي آن دريافت و آن را چاپ مي نمايد.

و اما ارسال آرايه هاي با ابعاد بالاتر به توابع نيز مشابه آرايه هاي دوبعدي است. به اين صورت كه در هنگام تعريف يك پارامتر از تابع بعنوان يك آرايه چندبعدي، مشخص كردن بعد اول لزومي ندارد، اما اندازه كليه ابعاد بعدي بايد حتما مشخص گردد. بعنوان مثال تابع زير:

کد:
void test(int A[][5][10], … ) {

يعنوان ورودي يك آرايه سه بعدي دريافت مي نمايد كه حتما بايد بعد دوم آن 5 و بعد سوم آن 10 باشند، اما اندازه بعد اول هر مقداري مي تواند باشد.