برای روشن کردن ترمینال، کلیک کن یا هر کلیدی را بزن

پرش به محتوای اصلی
>_

// ~/exam

شب امتحانی

وقت کمه و امتحان داره؟ نکات کلیدی رو سریع مرور کن، با آزمون سریع خودت رو محک بزن و آخرش با آزمون جامع پایانی، کل جزوه رو جمع کن!

۳۶ نکته
shab-emtahan.cppg++ -Wall — zsh
~ % g++ shab-emtahan.cpp -Wall -Wextra
note:ساختار استاندارد برنامه-Wbasicمبانی

هر برنامه باید هدر، using namespace، int main و return 0 داشته باشد. متغیر‌ها را مقداردهی اولیه کنید.

// قالب استاندارد
#include <iostream>
using namespace std;

int main() {
    int n = 0;       // مقداردهی اولیه الزامی
    cin >> n;
    cout << n * 2;
    return 0;
}

خروجی ← ورودی: 5 خروجی: 10

warning:تقسیم صحیح vs اعشاری-Wbasicمبانی

int / int = int (بخش اعشاری حذف می‌شود). حداقل یک عملوند باید اعشاری باشد: float(n) یا (double)a.

// تله تقسیم صحیح
int a = 7, b = 2;
cout << a / b;           // 3 (صحیح)
cout << (double)a / b;   // 3.5 (اعشاری)
cout << a / (float)b;   // 3.5

خروجی ← 3 3.5 3.5

note:عملگر % (باقی‌مانده)-Wbasicمبانی

برای استخراج ارقام یا بررسی زوج/فرد: n % 10 = یکان، n % 2 == 0 = زوج.

// استخراج ارقام
int n = 528;
cout << n % 10;     // 8 (یکان)
cout << (n / 10) % 10;  // 2 (ده‌گان)
cout << n % 2;      // 0 → زوج

خروجی ← 8 2 0

warning:a++ vs ++a (پست‌فیکس/پری‌فیکس)-Wbasicمبانی

a++ اول مقدار را می‌دهد بعد افزایش. ++a اول افزایش بعد مقدار. b = a++ vs b = ++a.

// پست‌فیکس در برابر پری‌فیکس
int a = 5, b;
b = a++;   // b=5, a=6
cout << b << ' ' << a << '\n';
a = 5; b = ++a;  // b=6, a=6
cout << b << ' ' << a;

خروجی ← 5 6 6 6

warning:= vs == (باگ شماره یک)-Wcondشرط

= انتساب است (x = 5 مقدار می‌دهد). == مقایسه است (x == 5 بررسی می‌کند). در if همیشه == بنویسید!

// تله مساوی
int x = 5;
if (x == 5) cout << "برابر";   // درست
if (x = 5)  cout << "همیشه چاپ می‌شود!";  // اشتباه!

خروجی ← برابر همیشه چاپ می‌شود!

warning:char و ASCII-Wcharکاراکتر

char در واقع عدد است. 'A'=65، 'a'=97، '0'=48. اختلاف بزرگ/کوچک = 32. تبدیل: (int)ch یا ch - '0'.

// کاراکتر و کد اسکی
char ch = 'A';
cout << (int)ch;          // 65
char lower = ch + 32;    // 'a'
cout << lower;            // a
char digit = '7';
cout << digit - '0';      // 7 (عدد)

خروجی ← 65 a 7

warning:switch و فراموش کردن break-Wcondشرط

اگر break ننویسید، اجرا به case بعدی می‌ریزد (fall-through). همیشه break بگذارید مگر اینکه عمداً fall-through بخواهید.

// خطای fall-through
int x = 2;
switch (x) {
    case 1: cout << "یک"; break;
    case 2: cout << "دو"; /* بدون break! */
    case 3: cout << "سه"; break;
}
// خروجی: دوسه (fall-through)

خروجی ← دوسه

note:حلقه for — قالب-Wloopحلقه‌ها

for (init; condition; step). دقت: i < n یعنی n نمی‌رسد، i <= n یعنی n هم شامل است (تله off-by-one).

// for استاندارد
// چاپ 1 تا 5
for (int i = 1; i <= 5; i++) {
    cout << i << ' ';
}
// خروجی: 1 2 3 4 5

خروجی ← 1 2 3 4 5

note:فاکتوریل با long long-Wnumاعداد

فاکتوریل سریع بزرگ می‌شود! 13! از int سرریز می‌کند. از long long استفاده کنید.

// فاکتوریل با long long
long long fact = 1;
int n = 10;
for (int i = 1; i <= n; i++) {
    fact *= i;
}
cout << fact;   // 3628800

خروجی ← 3628800

warning:تشخیص عدد اول-Wnumاعداد

تا √n بررسی کنید، نه تا n. اگر هیچ مقسوم‌علیه‌ای جز 1 و خودش نداشت، اول است.

// الگوریتم بهینه عدد اول
bool isPrime(int n) {
    if (n < 2) return false;
    for (int i = 2; i * i <= n; i++) {
        if (n % i == 0) return false;
    }
    return true;
}

خروجی ← isPrime(17) → true

note:مجموع ارقام عدد-Wnumاعداد

با while و n % 10 و n /= 10 ارقام را یکی یکی استخراج کنید.

// مجموع ارقام
int n = 1234, sum = 0;
while (n > 0) {
    sum += n % 10;   // رقم یکان
    n /= 10;          // حذف یکان
}
cout << sum;   // 1+2+3+4 = 10

خروجی ← 10

warning:معکوس عدد و پالیندروم-Wnumاعداد

برای پالیندروم: عدد را معکوس کنید و با اصل مقایسه کنید. اگر برابر بود، متقارن است.

// تشخیص پالیندروم
int n = 12321, original = n, rev = 0;
while (n > 0) {
    rev = rev * 10 + n % 10;
    n /= 10;
}
if (rev == original) cout << "پالیندروم";
else cout << "نه";

خروجی ← پالیندروم

note:یافتن max و اندیس در آرایه-Warrayآرایه

اولین عنصر را به‌عنوان max اولیه بگیرید، سپس بقیه را با آن مقایسه کنید.

// یافتن ماکزیمم
int a[5] = {3, 9, 2, 7, 5};
int max = a[0], idx = 0;
for (int i = 1; i < 5; i++) {
    if (a[i] > max) {
        max = a[i];
        idx = i;
    }
}
cout << max << " در اندیس " << idx;

خروجی ← 9 در اندیس 1

warning:Bubble Sort (حبابی)-Wsortمرتب‌سازی

هر جفت مجاور را مقایسه و جابجا کنید. در هر پاس، بزرگترین به ته می‌رود.

// مرتب‌سازی حبابی
int a[5] = {5, 2, 8, 1, 9};
for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 4 - i; j++) {
        if (a[j] > a[j + 1]) {
            int t = a[j];
            a[j] = a[j + 1];
            a[j + 1] = t;
        }
    }
}
// a = {1, 2, 5, 8, 9}

خروجی ← 1 2 5 8 9

warning:swap با ارجاع-Wfuncتابع

برای جابجایی واقعی، پارامترها را با & (ارجاع) بگیرید، نه با مقدار.

// swap با ارجاع
void swap(int& a, int& b) {
    int t = a;
    a = b;
    b = t;
}
int x = 3, y = 7;
swap(x, y);
cout << x << ' ' << y;   // 7 3

خروجی ← 7 3

warning:بازگشت — فاکتوریل-Wfuncتابع

بازگشت = شرط پایه + فراخوانی خود. شرط پایه فراموش نشود! fact(n) = n * fact(n-1)، fact(1) = 1.

// فاکتوریل بازگشتی
long long fact(int n) {
    if (n <= 1) return 1;     // شرط پایه
    return n * fact(n - 1);   // بازگشت
}
cout << fact(5);   // 120

خروجی ← 120

error:اشاره‌گر و new/delete-Wptrاشاره‌گر

new حافظه می‌گیرد، delete آزاد می‌کند. آرایه: delete[]. فراموش کردن = نشت حافظه!

// حافظه پویا
int* p = new int(42);
cout << *p;       // 42
delete p;         // آزادسازی

int* arr = new int[5];
for (int i = 0; i < 5; i++) arr[i] = i;
delete[] arr;     // آزادسازی آرایه

خروجی ← 42

warning:struct و دسترسی به فیلد‌ها-Wptrاشاره‌گر

struct گروهی از متغیر‌ها. دسترسی با نقطه (.). با اشاره‌گر با فلش (->).

// تعریف و استفاده struct
struct Student {
    string name;
    float avg;
};
Student s;
s.name = "علی";
s.avg = 18.5;
cout << s.name << ": " << s.avg;

خروجی ← علی: 18.5

note:نمادهای فلوچارت-Walgoالگوریتم

بیضی = شروع/پایان، متوازی‌الاضلاع = ورودی/خروجی، مستطیل = پردازش، لوزی = تصمیم. زبان مشترک الگوریتم.

// نمادهای استاندارد
شروع ──▶ [دریافت a, b] ──▶ <a ≠ 0؟>
                        │ بله          │ خیر
                  [x = -b/a]      [«بدون جواب»]
                        └────▶ [چاپ x] ──▶ پایان

خروجی ← فلوچارت = نقشهٔ راه کد

note:الگوریتم جابه‌جایی (Swap)-Walgoالگوریتم

سه انتساب با متغیر کمکی t: مقدار a را موقتاً نگه دار وگرنه برای همیشه می‌رود. پایهٔ مرتب‌سازی‌ها.

// سه‌گامِ جابه‌جایی
int a = 7, b = 5, t;
t = a;    // t = 7
a = b;    // a = 5
b = t;    // b = 7

خروجی ← a=5 b=7

warning:تبدیل حروف بزرگ/کوچک با ۳۲-Wcharکاراکتر

اختلاف 'a' و 'A' در ASCII برابر 32 است. ch += 32 بزرگ→کوچک، ch -= 32 کوچک→بزرگ.

// ±۳۲ جادویی
char ch = 'Q';
ch = ch + 32;      // 'q'
// یا هوشمندتر — فقط اگر حرف بزرگ بود:
if (ch >= 'A' && ch <= 'Z')
    ch += 32;

خروجی ← q

error:ارزیابی اتصال کوتاه (Short-circuit)-Wcondشرط

در && اگر سمت چپ false باشد سمت راست اجرا نمی‌شود؛ در || برعکس. ترتیب شرط‌ها را طوری بچینید که از خطا جلوگیری کند.

// ترتیب شرط‌ها مهم است
int a = 0;
// امن: شرط اول جلوی تقسیم بر صفر را می‌گیرد
if (a != 0 && 10 / a > 2) { /* ... */ }
// خطرناک: تقسیم بر صفر!
if (10 / a > 2 && a != 0) { /* کرش */ }

خروجی ← شرط اول امن است

warning:تشکیل مثلث و معادلهٔ درجه ۲-Wcondشرط

مثلث: مجموع هر دو ضلع > ضلع سوم (هر سه شرط!). معادلهٔ درجه ۲: اول دلتا = b²−4ac، بعد سه حالت مثبت/صفر/منفی.

// دو کلاسیک امتحانی
// مثلث؟
if (a+b>c && a+c>b && b+c>a) cout << "مثلث";
// معادله درجه ۲:
double d = b*b - 4*a*c;
if (d > 0)      /* دو ریشه */;
else if (d == 0) /* یک ریشه */;
else            /* بدون ریشهٔ حقیقی */;

خروجی ← سه حالت دلتا

note:for یا while؟-Wloopحلقه‌ها

تعداد تکرار مشخص → for. شرطِ ادامه نامشخص (تا ورودی خاص، تا انتهای رشته) → while. قانون جزوه.

// انتخاب درست حلقه
for (int i = 1; i <= n; i++) { }   // شمارشی
while (n > 0) { n /= 10; }          // شرطی
while (cin >> x && x != 0) { }      // تا ورودی صفر

خروجی ← قاعدهٔ جزوه

warning:حلقهٔ بی‌نهایت — قاتل برنامه-Wloopحلقه‌ها

اگر متغیر شرط در بدنه تغییر نکند (مثل فراموش کردن n /= 10)، حلقه هرگز تمام نمی‌شود.

// تلهٔ while
while (n > 0) {
    cout << n % 10;
    // n /= 10;   ← فراموش شده = بی‌نهایت!
}

خروجی ← تکرار بی‌پایان

warning:ب.م.م با الگوریتم اقلیدسی-Wnumاعداد

جایگزینی (a, b) ← (b, a%b) تا صفر شدن b؛ بزرگ‌ترین مقسوم‌علیه = مقدار a. سریع‌تر از شمارش مقسوم‌علیه‌ها.

// اقلیدس
int a = 48, b = 18;
while (b != 0) {
    int r = a % b;
    a = b;
    b = r;
}
cout << a;   // 6

خروجی ← 6

error:تجزیه به عوامل اول-Wnumاعداد

از کوچک‌ترین عامل (۲) شروع کن؛ تا وقتی بخش‌پذیر است تقسیم کن و تعداد را بشمار، بعد سراغ عامل بعدی برو.

// تجزیهٔ ۳۶۰
int n = 360;
for (int i = 2; i * i <= n; i++) {
    while (n % i == 0) {
        cout << i << " ";
        n /= i;
    }
}
if (n > 1) cout << n;   // اگر باقی‌مانده اول است

خروجی ← 2 2 2 3 3 5

note:مقداردهی آرایه — قاعدهٔ صفر‌ها-Warrayآرایه

int a[100] = {0}; کل آرایه را صفر می‌کند. هر خانه‌ای که در لیست مقدار نگیرد صفر است — اندیس‌ها از ۰ تا n−1.

// صفرکردن آرایه
int a[100] = {0};     // همه صفر
int b[5] = {15, 12, 70, 0};  // b[4] = 0
// a[5] در آرایهٔ ۵تایی = خطای مرزی!

خروجی ← قاعدهٔ {0}

warning:cin یا getline؟-Wstrرشته‌ها

cin >> s تا اولین فاصله می‌خواند. برای جملهٔ کامل با فاصله‌ها getline(cin, s) لازم است.

// ورودی رشته
string s;
cin >> s;              // "hello world" → فقط hello
getline(cin, s);       // کل خط با فاصله‌ها
cout << s.length();    // طول بدون 

خروجی ← hello | hello world

warning:خانوادهٔ string.h-Wstrرشته‌ها

strlen طول، strcpy کپی، strcat الحاق، strcmp مقایسه (صفر = برابر، منفی = اولی کوچک‌تر). در C++ مدرن: <cstring>.

// چهار تابع کلاسیک
char s1[100] = "salam", s2[100];
strcpy(s2, s1);          // s2 = "salam"
strcat(s2, " donya");    // "salam donya"
cout << strlen(s2);      // 11
cout << strcmp("abc", "abd");  // منفی

خروجی ← 11 منفی

warning:معکوس رشته — دو روش-Wstrرشته‌ها

روش ۱: رشتهٔ جدید از انتها پر شود. روش ۲ (بهینه): جابه‌جایی درجا با swap تا نصف طول — بدون حافظهٔ اضافه.

// معکوس درجا
// درجا با دو اندیس
for (int i = 0; i < s.length() / 2; i++)
    swap(s[i], s[s.length() - 1 - i]);

خروجی ← salam → malas

warning:Selection در برابر Bubble-Wsortمرتب‌سازی

Bubble: جفت‌های مجاور جابجا می‌شوند (بزرگ‌ترین حباب می‌کند به بالا). Selection: کوچک‌ترینِ باقی‌مانده پیدا و سرِ بخش می‌شود — جابه‌جایی کمتر.

// هستهٔ Selection Sort
// Selection — هستهٔ الگوریتم
for (int i = 0; i < n - 1; i++) {
    int m = i;
    for (int j = i + 1; j < n; j++)
        if (a[j] < a[m]) m = j;
    swap(a[i], a[m]);   // فقط یک جابجایی در هر دور
}

خروجی ← هر دو O(n²)

error:ضرب ماتریس‌ها — شرط ابعاد-Wmatماتریس

a[m][n] × b[k][l] فقط وقتی n == k ممکن است؛ حاصل m×l است. سه حلقهٔ تو در تو: i، j و k جمعی.

// قلب ضرب ماتریس
int c[10][10] = {0};
for (int i = 0; i < m; i++)
    for (int j = 0; j < l; j++)
        for (int k = 0; k < n; k++)
            c[i][j] += a[i][k] * b[k][j];

خروجی ← c[m][l]

error:مثلث خیام–پاسکال-Wmatماتریس

لبه‌ها ۱ و هر خانهٔ داخلی = مجموع دو خانهٔ بالایی: a[i][j] = a[i-1][j-1] + a[i-1][j]. سطر n = ضرایب (a+b)ⁿ.

// خیام–پاسکال
for (int i = 0; i < n; i++) {
    a[i][0] = a[i][i] = 1;
    for (int j = 1; j < i; j++)
        a[i][j] = a[i-1][j-1] + a[i-1][j];
}
// سطر ۴: 1 4 6 4 1

خروجی ← 1 4 6 4 1

warning:* و & — دو عملگر کلیدی-Wptrاشاره‌گر

& آدرس متغیر را می‌دهد، * به آنچه در آدرس است دسترسی می‌کند. p = &x آنگاه *p یعنی خودِ x.

// آدرس و مقدار
int x = 10;
int* p = &x;    // p آدرس x را دارد
cout << p;      // آدرس (هگز)
cout << *p;     // 10
*p = 20;        // x حالا 20 شد!

خروجی ← 0x... 10

error:delete یا delete[]؟-Wptrاشاره‌گر

new int → delete p. new int[n] → delete[] p. خلط این دو رفتار تعریف‌نشده دارد؛ فراموش کردنش = نشت حافظه.

// جفتِ درست
int* p  = new int(5);    delete p;    // تکی
int* a  = new int[100]; delete[] a;  // آرایه
// *(p + i) ≡ p[i] — دو روش دسترسی

خروجی ← new↔delete, new[]↔delete[]

6 error, 20 warning, 10 note generated

// سطح نکته: note = آسان، warning = متوسط، error = سخت

~ %

این نکته‌ها خلاصهٔ مهم‌ترین بخش‌های دوره‌اند. برای مطالعهٔ کامل هر مبحث، درس مربوطه را از فهرست درس‌ها باز کنید.

شروع از درس اول

جستجوی سریع در درس‌ها

نام درس، موضوع یا کلمه کلیدی را بنویسید و با Enter به آن بروید