معرفی سایت
صفحه اول

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




آمار سايت
كل بازديدهاي سايت: 87897
تاريخ ايجاد وبلاگ: شنبه 2 آبان 1388
بروز رساني:چهارشنبه 12 خرداد 1389
تعداد نظرات داده شده : 73 نظر
كل مطالب ارسال شده: 791 عدد
تاريخ ايجاد وبلاگ: شنبه 2 آبان 1388
بروز رساني:چهارشنبه 12 خرداد 1389
تعداد نظرات داده شده : 73 نظر
كل مطالب ارسال شده: 791 عدد
امکانات جانبی
در این قسمت، ابتدا به نحوه ارسال آرایه های دو بعدی به توابع می پردازیم و سپس آرایه های با ابعاد بالاتر می پردازیم.
شاید تصور کنید که برای تعریف یک آرایه دوبعدی بعنوان پارامتری از یک تابع، تنها قرار دادن دو علامت [] کافی است و نیازی به ذکر ابعاد آن نیست. اما متاسفانه اینگونه نیست، بلکه برنامه نویس باید تعداد ستونهای آرایه دوبعدی را صریحا مشخص نماید، اما نیازی به تعیین تعداد ردیفهای آن نیست. بعنوان مثال فرض کنید تابعی مانند 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;
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] ;
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);
}
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] ) {
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] ;
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;
int i,j;
for (i=0; i< row; i++) {
for (j=0; j< col ;j++)
printf(“%d ”,matrix[i][j]);
printf(“\n”);
}
}
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] ;
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
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 باشند، اما اندازه بعد اول هر مقداري مي تواند باشد.
منبع : prdev.com
ارسال در تاريخ پنج شنبه 3 دی 1388 توسط
رضا عبدالملكي
