آرایه های چند بعدی

آرایه‌های چند بعدی آرایه‌هایی هستند که برای دسترسی به هر یک از عناصر آنها باید از چندین اندیس استفاده کنیم. یک آرایه چند بعدی را می‌توان مانند یک جدول با تعدای ستون و ردیف تصور کنید. با افزایش اندیسها اندازه ابعاد آرایه نیز افزایش می‌یابد و آرایه‌های چند بعدی با بیش از دو اندیس به وجود می‌آیند. نحوه ایجاد یک آرایه با دو بعد به صورت زیر است :

datatype arrayName[lengthX][lengthY];

و یک آرایه سه بعدی به صورت زیر ایجاد می‌شود :

datatype arrayName[lengthX][lengthY][lengthZ];

می‌توان یک آرایه با تعداد زیادی بعد ایجاد کرد به شرطی که هر بعد دارای طول مشخصی باشد. به دلیل اینکه آرایه‌های سه بعدی یا آرایه‌های با بیشتر از دو بعد بسیار کمتر مورد استفاده قرار می‌گیرند اجازه بدهید که در این درس بر روی آرایه‌های دو بعدی تمرکز کنیم. در تعریف این نوع آرایه ابتدا نوع آرایه یعنی اینکه آرایه چه نوعی از انواع داده را در خود ذخیره می‌کند را مشخص می‌کنیم. سپس نام آرایه و در نهایت دو جفت کروشه قرار می‌دهیم. در یک آرایه دو بعدی برای دسترسی به هر یک از عناصر به دو مقدار نیاز داریم یکی مقدار X و دیگری مقدار Y که مقدار x نشان دهنده ردیف و مقدار Y نشان دهنده ستون آرایه است البته اگر ما آرایه دو بعدی را به صورت جدول در نظر بگیریم. یک آرایه سه بعدی را می‌توان به صورت یک مکعب تصور کرد که دارای سه بعد است و x طول، Y عرض و z ارتفاع آن است. یک مثال از آرایه دو بعدی در زیر آمده است :

int numbers[3][5];

کد بالا به کامپایلر می‌گوید که فضای کافی به عناصر آرایه اختصاص بده (در این مثال 15 خانه). در شکل زیر مکان هر عنصر در یک آرایه دو بعدی نشان داده شده است.

مقدار 3 را به x اختصاص می‌دهیم چون 3 سطر و مقدار 5 را به Y چون 5 ستون داریم اختصاص می‌دهیم. چطور یک آرایه چند بعدی را مقدار دهی کنیم؟ چند راه برای مقدار دهی به آرایه‌ها وجود دارد.

datatype arrayName[x][y] = { { r0c0, r0c1, ... r0cX },
			     { r1c0, r1c1, ... r1cX },
			     .
			     .
			     .
			     { rYc0, rYc1, ... rYcX } 
			  };

البته می‌توان تعداد سطرها را هم ننوشت ولی تعداد ستون‌ها حتماً باید ذکر شوند :

datatype arrayName[][y] = { { r0c0, r0c1, ... r0cX },
			    { r1c0, r1c1, ... r1cX },
			    .
			    .
			    .
			     { rYc0, rYc1, ... rYcX } 
			  };

به عنوان مثال :

 int numbers[][5] = { { 1, 2, 3, 4, 5 },
                   { 6, 7, 8, 9, 10 },
                   { 11, 12, 13, 14, 15 } };

و یا می‌توان مقدار دهی به عناصر را به صورت دستی انجام داد مانند :

array[0][0] = value;
array[0][1] = value;
array[0][2] = value;
array[1][0] = value;
array[1][1] = value;
array[1][2] = value;
array[2][0] = value;
array[2][1] = value;
array[2][2] = value;

همانطور که مشاهده می‌کنید برای دسترسی به هر یک از عناصر در یک آرایه دو بعدی به سادگی می‌توان از اندیسهای X و Y و یک جفت کروشه مانند مثال استفاده کرد.

گردش در میان عناصر آرایه‌های چند بعدی

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

   1: #include <iostream>
   2: using namespace std;
   3: 
   4: int main()
   5: {
   6: 	int numbers[3][5] = { 
   7: 		              { 1 , 2 , 3 , 4 , 5  },
   8: 		              { 6 , 7 , 8 , 9 , 10 },
   9: 		              { 11, 12, 13, 14, 15 }
  10:                        };
  11: 
  12:     for (int row = 0; row < size(numbers); row++)
  13:     {
  14:         for (int col = 0; col < size(numbers); col++)
  15:         {
  16:            cout << numbers[row][col] << " ";
  17:         }
  18:         
  19:         //Go to the next line
  20:         cout << endl;
  21:     }
  22: }
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15

همانطور که در مثال بالا نشان داده شده است با استفاده از یک حلقه for نمی‌توان به مقادیر دسترسی یافت بلکه به یک حلقه for تو در تو نیاز داریم، زیرا آرایه دو بعدی به صورت یک جدول شامل سطر و ستون است، پس لازم است که از یک حلقه for برای گردش در میان سطرها و از حلقه for دیگر برای گردش در میان ستون‌های این جدول (آرایه) استفاده کنیم.
اولین حلقه for (خط 12) برای گردش در میان ردیف‌های آرایه به کار می‌رود. این حلقه تا زمانی ادامه می‌یابد که مقدار ردیف کمتر از طول اولین بعد باشد (زیرا اندیس ابعاد آرایه از صفر شروع می‌شود. در مثال بالا مقدار اولین بعد برابر 3 است). در این مثال از متد ()size استفاده کرده‌ایم. این متد طول آرایه را در یک بعد خاص نشان می‌دهد. به عنوان مثال برای به دست آوردن طول اولین یا همان تعداد سطرها کافیست که نام آرایه را به این متد ارسال می‌کنیم.

در داخل اولین حلقه for حلقه for دیگری تعریف شده است (خط 14). در این حلقه یک شمارنده برای شمارش تعداد ستونهای (col) هر ردیف تعریف شده است و در شرط داخل آن بار دیگر از متد ()size استفاده شده است، ولی این بار مقدار [0]numbers را به آن ارسال می‌کنیم تا طول بعد دوم آرایه را به دست آوریم. پس به عنوان مثال وقتی که مقدار ردیف (row) صفر باشد، حلقه دوم از [0][0] تا [0][4] اجرا می‌شود. سپس مقدار هر عنصر از آرایه را با استفاده از حلقه نشان می‌دهیم، اگر مقدار ردیف (row) برابر 0 و مقدار ستون (col) برابر 0 باشد مقدار عنصری که در ستون 1 و ردیف 1 (numbers[0][0]) قرار دارد نشان داده خواهد شد که در مثال بالا عدد 1 است.

بعد از اینکه دومین حلقه تکرار به پایان رسید، فوراً دستورات بعد از آن اجرا خواهند شد، که در اینجا دستور cout << endl; که به برنامه اطلاع می‌دهد که به خط بعد برود. سپس حلقه با اضافه کردن یک واحد به مقدار row این فرایند را دوباره تکرار می‌کند. سپس دومین حلقه for اجرا شده و مقادیر دومین ردیف نمایش داده می‌شود. این فرایند تا زمانی اجرا می‌شود که مقدار row کمتر از طول اولین بعد باشد. حال بیایید آنچه را از قبل یاد گرفته‌ایم در یک برنامه به کار بریم. این برنامه نمره چهار درس مربوط به سه دانش آموز را از ما می‌گیرد و معدل سه دانش آموز را حساب می‌کند.

   1: #include <iostream>
   2: 
   3: using namespace std;
   4: 
   5: int main()
   6: {
   7:     double studentGrades[3][4];
   8:     double total;
   9:     
  10:     for (int student = 0; student < size(studentGrades); student++)
  11:     {
  12:         total = 0;
  13:         
  14:         cout << "Enter grades for Student " << (student + 1) << endl;
  15:         
  16:         for (int grade = 0; grade < size(studentGrades); grade++)
  17:         {
  18:             cout << "Enter Grade #" << (grade + 1) << " : " ;
  19:             cin >> studentGrades[student][grade];
  20:             total += studentGrades[student][grade];
  21:         }
  22:         
  23:         cout << "Average is " << (total / size(studentGrades)) << endl;
  24:         cout << endl;
  25:     }
  26: }
Enter grades for Student 1
Enter Grade #1: 92
Enter Grade #2: 87
Enter Grade #3: 89
Enter Grade #4: 95
Average is 90.75

Enter grades for Student 2
Enter Grade #1: 85
Enter Grade #2: 85
Enter Grade #3: 86
Enter Grade #4: 87
Average is 85.75

Enter grades for Student 3
Enter Grade #1: 90
Enter Grade #2: 90
Enter Grade #3: 90
Enter Grade #4: 90
Average is 90.00

در برنامه بالا یک آرایه چند بعدی از نوع double تعریف شده است (خط 7). همچنین یک متغیر به نام total تعریف می‌کنیم که جمع نمرات وارد شده برای دانش آموز در آن قرار می‌گیرد. حال وارد حلقه for تو در تو می‌شویم (خط 10). در اولین حلقه for یک متغیر به نام student تعریف کرده‌ایم که مقادیر اولین بعد آرایه (که همان تعداد دانش آموزان است) در آن قرار می‌گیرد. از متد متد ()size هم برای تشخیص تعداد دانش آموزان استفاده شده است. وارد بدنه حلقه for می‌شویم. در خط 12 مقدار متغیر total را برابر صفر قرار می‌دهیم. سپس برنامه یک پیغام را نشان می‌دهد و از شما می‌خواهد که نمرات دانش آموز را وارد کنید (student + 1). عدد 1 را به student اضافه کرده‌ایم تا به جای نمایش Student 0، با Student 1 شروع شود، تا طبیعی‌تر به نظر برسد.

سپس به دومین حلقه for در خط 16 می‌رسیم. وظیفه این حلقه گردش در میان دومین بعد که همان نمرات دانش آموز است می‌باشد. برنامه چهار نمره مربوط به دانش آموز را می‌گیرد. هر وقت که برنامه یک نمره را از کاربر دریافت می‌کند، نمره به متغیر total اضافه می‌شود. وقتی همه نمره‌ها وارد شدند، متغیر total هم جمع همه نمرات را نشان می‌دهد. در خطوط 24-23 معدل دانش آموز نشان داده می‌شود. معدل از تقسیم کردن total (جمع) بر تعداد نمرات به دست می‌آید. از size(studentGrades[0]) هم برای به دست آوردن تعداد نمرات استفاده می‌شود.