آرایه‌ها در سی‌پلاس‌پلاس

قسمت 7 از دوره C++

معرفی

چرا به آرایه ها نیاز داریم؟

میانگین گرفتن

حذف نمرات غلط

دریافت نمرات از کاربر

جمع بندی

معرفی
چرا به آرایه ها نیاز داریم؟
میانگین گرفتن
حذف نمرات غلط
دریافت نمرات از کاربر
جمع بندی

در این مقاله با نوشتن یک برنامه که کارش محاسبه میانگین نمرات دانش‌آموزان یک کلاس است با کاربرد آرایه‌ها آشنا می‌شویم.

آرایه‌ها به بیان ساده مجموعه‌ای از متغیرها هستند و به ما کمک می‌کنند مجموعه‌‌ها و یا لیستی از مقادیر را بدون نیاز به تعریف تعداد زیادی متغیر در حافظه کامپیوتر ذخیره کنیم.

با مفاهیمی که تا به اینجا با آن‌ها آشنا شدیم می‌توانیم یک برنامه بنویسیم که میانگین ۲ عدد را محاسبه می‌کند.

#include <iostream>

using namespace std;

int main() {
    int a = 80;
    int b = 100;
    cout << (a + b) / 2 << endl;
}
90

درواقع اعداد را با هم جمع کرده و تقسیم بر تعداد (که در اینجا ۲ است) می‌کنیم. اما اگر بخواهیم این کار را برای ۳ عدد انجام دهیم چه؟ آن وقت باید ۳ متغیر تعریف کنیم و در خط آخر جمع آن سه متغیر تقسیم بر ۳ را چاپ کنیم. اگر بخواهیم این برنامه را برای یک کلاس کامل ۳۰ نفره طراحی کنیم ۳۰ متغیر نیاز خواهیم داشت و همچنین برنامه ما هم در کلاس هایی که تعداد دانش‌آموزان متفاوتی دارند کار نخواهد کرد.
اینجاست که مفهوم آرایه ها به کارمان می‌‌آید٬ آرایه‌ها مجموعه مقدارهایی ذخیره شده پشت هم در حافظه است که با شماره‌شان قابل دسترسی‌ هستند.
پس مثلا به جای تعریف کردن ۵ متغیر عددی int برای نمره ۵ دانش‌آموز می‌توانیم یک آرایه با طول ۵ از نوع int تعریف کنیم.

int scores[5];

می‌توان مقدارها اولیه این ۵ نمره را هم تنظیم کرد:

int scores[5] = { 80, 70, 90, 60, 100 };

و برای پرینت کردن یک خانه از آرایه‌ای که تعریف کردیم می‌توانیم از همین کارکتر براکت باز و بسته[] که برای نشان دادن سایز آرایه استفاده کردیم استفاده کنیم.

cout << scores[1] << endl;

اما خروجی این کد ۷۰ خواهد بود یعنی مورد دوم در آرایه و اگر بخواهیم مورد اول (۸۰) را چاپ کنیم باید index یا اندیس ۰ را بجای یک بگذاریم:

cout << scores[0] << endl;

و خروجی این خط ۸۰ خواهد بود.

آرایه‌ها مانند یک جدول در حافظه نگه داشته می‌شوند و خود متغیر scores به محل شروع این آرایه در حافظه کامپیوتر اشاره می‌کند (جایی که ۸۰ نگه داشته می‌شود و اعداد بعدی به ترتیب پشت آن اضافه می‌شوند)
پس وقتی شما از کامپیوتر می‌خواهید که خانه ۰ آرایه را برگرداند کامپیوتر از محل scores صفر خانه به جلو می‌رود (درواقع حرکت نمی‌کند) و مقدار ۸۰ را بر می‌گرداند.
وقتی مقدار scores[1] را می‌خواهید کامپیوتر یک خانه به جلو حرکت کرده و عدد ۷۰ را بر می‌گرداند.

80709060100
scores[0]scores[1]scores[2]scores[3]scores[4]

همچنین می‌توانید مقادیر داخل آرایه‌ها را با علامت مساوی تغییر دهید:

int scores[5] = { 80, 70, 90, 60, 100 };
scores[0] = 90;
cout << scores[0] << endl;
cout << scores[1] << endl;
90
70

درواقع داریم مقدار خانه اول (۸۰) را به ۹۰ تغییر می‌دهیم و بعد خانه اول (که حالا مقدار ۹۰ را داراست) و خانه دوم (۷۰) را پرینت می‌کنیم.

در نهایت کمی راجع به حلقه for و آرایه‌ها صحبت کنیم٬ اگر بخواهیم تمام موارد داخل یک آرایه را پرینت کنیم می‌توانیم یک حلقه فور از ۰ (اندیس اولین مورد) تا کوچکتر از اندازه آرایه‌مان (آخرین اندیس) ایجاد کنیم و آن خانه آرایه را چاپ کنیم:

#include <iostream>

using namespace std;

int main() {
    int scores[5] = { 80, 70, 90, 60, 100 };
    for (int i = 0; i < 5; i++) {
        cout << scores[i] << endl;
    }
}
80
70
90
60
100

وقتی این حلقه اجرا می‌شود اول i مقدار ۰ را دارد و scores[0] یعنی ۸۰ پرینت می‌شود و در تکرار بعد i  یکی افزایش پیدا می‌کند و مقدار یک را خواهد داشت پس scores[1] یعنی ۷۰ پرینت می‌شود؛ این حلقه تا کوچکتر از ۵ یعنی ۴ که اندیس اخر این آرایه خواهد بود ادامه میابد و scores[4] یعنی ۱۰۰ در آخرین اجرای این حلقه پرینت خواهد شد.
دقت کنید که این حلقه تا کوچکتر از ۵ یعنی تا ۴ ادامه پیدا می‌کند و ۴ اخرین اندیس در آرایه ما است (زیرا اگر ۴ خانه به جلو برویم به ۱۰۰ می‌رسیم و اگر پنجمین خانه‌ای برای جلو رفتن وجود ندارد)

برای محاسبه میانگین موارد داخل آرایه می‌توانیم همان حلقه for که در مرحله قبل نوشتیم را طوری تغییر دهیم که به جای پرینت کردن موارد داخل آرایه (scores[i]) آن‌ها را با هم جمع و نهایتا تقسیم بر تعداد کند.

#include <iostream>

using namespace std;

int main() {
    int scores[] = { 80, 70, 90, 60, 100 };
    int sum = 0;
    for (int i = 0; i < 5; i++) {
        sum += scores[i];
    }
    cout << sum << endl;
}
400

این برنامه متغیر sum را با مقدار ۰ تعریف و تمام موارد scores را با آن جمع می‌بندد و نهایتا sum را پرینت می‌کند که معادل ۴۰۰ است.
دقت کنید تعداد موارد موجود در آرایه حذف و از یک براکت خالی به جای آن استفاده شده؛ علت آن است که موارد موجود در آرایه در همان خط تعریف شده‌اند پس کامپایلر خودش می‌تواند بفهمد که چه مواردی باید در این آرایه جای دهد و اندازه مورد نیاز آن چقدر است (پس می‌توانید وقتی که تمام موارد را موقع تعریف آرایه مشخص می‌کنید اندازه آن را در براکت‌ها نگذارید)

حالا تنها کاری که برای ما باقی می‌‌ماند این است که این مجموع را تقسیم بر تعداد نمرات (۵) بکنیم تا میانگین درست را به دست بیاوریم:

#include <iostream>

using namespace std;

int main() {
    int scores[] = { 80, 70, 90, 60, 100 };
    int sum = 0;
    for (int i = 0; i < 5; i++) {
        sum += scores[i];
    }
    cout << sum / 5 << endl;
}
80

فرض کنید به ما می‌گویند که مشکلی در ثبت نمرات در این لیست وجود داشته و ما باید نمرات بزرگتر از ۱۰۰ را از میانگین حذف کنیم.
راه اول برای حل این مساله این است که کد داخل حلقه را داخل یک شرط بگذاریم تا وقتی عدد در شرایط مطلوب است آن را در میانگین لحاظ کند:

for (int i = 0; i < 5; i++) {
    if (scores[i] <= 100) {
        sum += scores[i];
    }
}

اگر عدد کوچکتر یا مساوی ۱۰۰ است آن را در میانگین اضافه کن.
اما خیلی وقت ها ترجیح ما این است که به جای این که کل کد داخل حلقه را داخل یک شرط بگذاریم ابتدا موارد پرت را حذف کنیم تا دیگر نیاز نباشد نگران آن‌ها در باقی کد و فرایند اجرای حلقه باشیم.
برای این کار می‌توانیم از continue استفاده کنیم که وقتی اجرا می‌شود ادامه کد داخل حلقه را رد کرده و مجددا به بالای حلقه باز می‌گردد. پس می‌توانیم کد را به این شکل بنویسیم:

for (int i = 0; i < 5; i++) {
    if (scores[i] > 100) {
        continue;
    }
    sum += scores[i];
}

اگر عدد بزرگتر از ۱۰۰ باشد شرط اجرا شده و بدون اجرای باقی کد داخل حلقه (که اضافه کردن مقدار scores[i] به به متغیر sum را عهده دار بود) به بالای حلقه رفته و از این مورد می‌پریم.
اگر یکی از اعداد در آرایه را بالاتر از ۱۰۰ در نظر بگیریم تا این کد را تست کنیم خروجی زیر را دریافت می‌کنیم:

#include <iostream>

using namespace std;

int main() {
    int scores[] = { 80, 70, 90, 60, 120 };
    int sum = 0;
    for (int i = 0; i < 5; i++) {
        if (scores[i] > 100) {
            continue;
        }
        sum += scores[i];
    }
    cout << sum / 5 << endl;
}
60

که مشخصا خروجی درستی نیست چرا که امکان ندارد میانگین ۸۰ – ۷۰ – ۹۰ و ۶۰ معادل ۶۰ شود. علت این خطا این است که با وجود این که یک مورد از مجموع موارد را حذف کردیم همچنان جمع را تقسیم بر ۵ می‌کنیم.
برای حل این مساله می‌توانیم یک متغیر تعریف کنیم که تعداد نمرات حذف شده را می‌شمارد و نهایتا آن را از تعداد کل کم کنیم.

#include <iostream>

using namespace std;

int main() {
    int scores[] = { 80, 70, 90, 60, 120 };
    int sum = 0;
    int corrupt = 0;
    for (int i = 0; i < 5; i++) {
        if (scores[i] > 100) {
            corrupt++;
            continue;
        }
        sum += scores[i];
    }
    cout << sum / (5 - corrupt) << endl;
    cout << "Corrupt numbers: " << corrupt << endl;
}
75
Corrupt numbers: 1

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

#include <iostream>

using namespace std;

int main() {
    int scores[] = { -80, 70, 90, 60, 120 };
    int sum = 0;
    int corrupt = 0;
    for (int i = 0; i < 5; i++) {
        if (scores[i] > 100 || scores[i] < 0) {
            corrupt++;
            continue;
        }
        sum += scores[i];
    }
    cout << sum / (5 - corrupt) << endl;
    cout << "Corrupt numbers: " << corrupt << endl;
}
73
Corrupt numbers: 2

برنامه در مرحله قبل کامل شد اما هنوز یک مشکل کوچک دارد و آن این است که نمرات درون خود برنامه ثبت شده‌اند بدیهی است که شما از استاد نمی‌خواهید که کد شما را تغییر دهد و اجرا کند تا میانگین نمرات را به دست آورد پس برنامه‌ای که می‌نویسیم باید بتواند نمرات را از ورودی بپذیرد.
برای این کار یک متغیر عددی به اسم students تعریف می‌کنیم که تعداد دانش‌آموزان در کلاس را در آن ذخیره کنیم و سپس آرایه نمرات را به اندازه students تعریف می‌کنیم تا بتواند نمرات تمام دانش‌آموزان را نگه دارد:

int students;
cin >> students;
int scores[students];

سپس یک حلقه می‌نویسیم که به تعداد دانش‌آموزان ورودی دریافت کند و آن را در آرایه scores قرار دهد:

for (int i = 0; i < students; i++) {
    cout << "Enter student #" << i << " score ";
    cin >> scores[i];
}

در این مقاله با نوشتن یک برنامه که تعدادی نمره از ورودی دریافت و میانگین آن‌ها را محاسبه می‌کند در مورد آرایه‌ها به منظور نگه داشتن تعدادی مقدار در حافظه و همچنین استفاده continue برای حذف داده‌های پرت صحبت کردیم. منتظر شما در مقاله بعدی که در آن یک برنامه برای آینه کردن متن می‌نویسیم هستم.

#include <iostream>

using namespace std;

int main() {
    int students;
    cin >> students;
    int scores[students];
    for (int i = 0; i < students; i++) {
        cout << "Enter student #" << i << " score ";
        cin >> scores[i];
    }
    int sum = 0;
    int corrupt = 0;
    for (int i = 0; i < students; i++) {
        if (scores[i] > 100 || scores[i] < 0) {
            corrupt++;
            continue;
        }
        sum += scores[i];
    }
    cout << sum / (students - corrupt) << endl;
    cout << "Corrupt numbers: " << corrupt << endl;
}
5
Enter student #0 score -80
Enter student #1 score 70
Enter student #2 score 60
Enter student #3 score 90
Enter student #4 score 120
73
Corrupt numbers: 2

وارد شوید تا پیشرفت خود را ثبت کنید

وارد شوید تا پروژه‌هایی که تکمیل می‌کنید را علامت گذاری کنید و فرایند یادگیری خود را ثبت کنید

دیدگاهتان را بنویسید

برای نوشتن نظر٬ اول باید وارد شوید

مرحله بعد

معرفی

اطلاعات شما با موفقیت ثبت شد. کارشناسان ما در اسرع وقت با شما تماس خواهند گرفت.

از شکیبایی شما متشکریم.