// ~/exam
شب امتحانی
وقت کمه و امتحان داره؟ نکات کلیدی رو سریع مرور کن، با آزمون سریع خودت رو محک بزن و آخرش با آزمون جامع پایانی، کل جزوه رو جمع کن!
هر برنامه باید هدر، 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
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
برای استخراج ارقام یا بررسی زوج/فرد: n % 10 = یکان، n % 2 == 0 = زوج.
int n = 528; cout << n % 10; // 8 (یکان) cout << (n / 10) % 10; // 2 (دهگان) cout << n % 2; // 0 → زوج
خروجی ← 8 2 0
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
= انتساب است (x = 5 مقدار میدهد). == مقایسه است (x == 5 بررسی میکند). در if همیشه == بنویسید!
int x = 5; if (x == 5) cout << "برابر"; // درست if (x = 5) cout << "همیشه چاپ میشود!"; // اشتباه!
خروجی ← برابر همیشه چاپ میشود!
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
اگر break ننویسید، اجرا به case بعدی میریزد (fall-through). همیشه break بگذارید مگر اینکه عمداً fall-through بخواهید.
int x = 2;
switch (x) {
case 1: cout << "یک"; break;
case 2: cout << "دو"; /* بدون break! */
case 3: cout << "سه"; break;
}
// خروجی: دوسه (fall-through)خروجی ← دوسه
for (init; condition; step). دقت: i < n یعنی n نمیرسد، i <= n یعنی n هم شامل است (تله off-by-one).
// چاپ 1 تا 5
for (int i = 1; i <= 5; i++) {
cout << i << ' ';
}
// خروجی: 1 2 3 4 5خروجی ← 1 2 3 4 5
فاکتوریل سریع بزرگ میشود! 13! از int سرریز میکند. از long long استفاده کنید.
long long fact = 1;
int n = 10;
for (int i = 1; i <= n; i++) {
fact *= i;
}
cout << fact; // 3628800خروجی ← 3628800
تا √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
با 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
برای پالیندروم: عدد را معکوس کنید و با اصل مقایسه کنید. اگر برابر بود، متقارن است.
int n = 12321, original = n, rev = 0;
while (n > 0) {
rev = rev * 10 + n % 10;
n /= 10;
}
if (rev == original) cout << "پالیندروم";
else cout << "نه";خروجی ← پالیندروم
اولین عنصر را بهعنوان 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
هر جفت مجاور را مقایسه و جابجا کنید. در هر پاس، بزرگترین به ته میرود.
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
برای جابجایی واقعی، پارامترها را با & (ارجاع) بگیرید، نه با مقدار.
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
بازگشت = شرط پایه + فراخوانی خود. شرط پایه فراموش نشود! 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
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
struct گروهی از متغیرها. دسترسی با نقطه (.). با اشارهگر با فلش (->).
struct Student {
string name;
float avg;
};
Student s;
s.name = "علی";
s.avg = 18.5;
cout << s.name << ": " << s.avg;خروجی ← علی: 18.5
بیضی = شروع/پایان، متوازیالاضلاع = ورودی/خروجی، مستطیل = پردازش، لوزی = تصمیم. زبان مشترک الگوریتم.
شروع ──▶ [دریافت a, b] ──▶ <a ≠ 0؟>
│ بله │ خیر
[x = -b/a] [«بدون جواب»]
└────▶ [چاپ x] ──▶ پایانخروجی ← فلوچارت = نقشهٔ راه کد
سه انتساب با متغیر کمکی t: مقدار a را موقتاً نگه دار وگرنه برای همیشه میرود. پایهٔ مرتبسازیها.
int a = 7, b = 5, t; t = a; // t = 7 a = b; // a = 5 b = t; // b = 7
خروجی ← a=5 b=7
اختلاف 'a' و 'A' در ASCII برابر 32 است. ch += 32 بزرگ→کوچک، ch -= 32 کوچک→بزرگ.
char ch = 'Q';
ch = ch + 32; // 'q'
// یا هوشمندتر — فقط اگر حرف بزرگ بود:
if (ch >= 'A' && ch <= 'Z')
ch += 32;خروجی ← q
در && اگر سمت چپ false باشد سمت راست اجرا نمیشود؛ در || برعکس. ترتیب شرطها را طوری بچینید که از خطا جلوگیری کند.
int a = 0;
// امن: شرط اول جلوی تقسیم بر صفر را میگیرد
if (a != 0 && 10 / a > 2) { /* ... */ }
// خطرناک: تقسیم بر صفر!
if (10 / a > 2 && a != 0) { /* کرش */ }خروجی ← شرط اول امن است
مثلث: مجموع هر دو ضلع > ضلع سوم (هر سه شرط!). معادلهٔ درجه ۲: اول دلتا = 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 /* بدون ریشهٔ حقیقی */;
خروجی ← سه حالت دلتا
تعداد تکرار مشخص → for. شرطِ ادامه نامشخص (تا ورودی خاص، تا انتهای رشته) → while. قانون جزوه.
for (int i = 1; i <= n; i++) { } // شمارشی
while (n > 0) { n /= 10; } // شرطی
while (cin >> x && x != 0) { } // تا ورودی صفرخروجی ← قاعدهٔ جزوه
اگر متغیر شرط در بدنه تغییر نکند (مثل فراموش کردن n /= 10)، حلقه هرگز تمام نمیشود.
while (n > 0) {
cout << n % 10;
// n /= 10; ← فراموش شده = بینهایت!
}خروجی ← تکرار بیپایان
جایگزینی (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
از کوچکترین عامل (۲) شروع کن؛ تا وقتی بخشپذیر است تقسیم کن و تعداد را بشمار، بعد سراغ عامل بعدی برو.
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
int a[100] = {0}; کل آرایه را صفر میکند. هر خانهای که در لیست مقدار نگیرد صفر است — اندیسها از ۰ تا n−1.
int a[100] = {0}; // همه صفر
int b[5] = {15, 12, 70, 0}; // b[4] = 0
// a[5] در آرایهٔ ۵تایی = خطای مرزی!خروجی ← قاعدهٔ {0}
cin >> s تا اولین فاصله میخواند. برای جملهٔ کامل با فاصلهها getline(cin, s) لازم است.
string s; cin >> s; // "hello world" → فقط hello getline(cin, s); // کل خط با فاصلهها cout << s.length(); // طول بدون
خروجی ← hello | hello world
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 منفی
روش ۱: رشتهٔ جدید از انتها پر شود. روش ۲ (بهینه): جابهجایی درجا با swap تا نصف طول — بدون حافظهٔ اضافه.
// درجا با دو اندیس
for (int i = 0; i < s.length() / 2; i++)
swap(s[i], s[s.length() - 1 - i]);خروجی ← salam → malas
Bubble: جفتهای مجاور جابجا میشوند (بزرگترین حباب میکند به بالا). Selection: کوچکترینِ باقیمانده پیدا و سرِ بخش میشود — جابهجایی کمتر.
// 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²)
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]
لبهها ۱ و هر خانهٔ داخلی = مجموع دو خانهٔ بالایی: 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
& آدرس متغیر را میدهد، * به آنچه در آدرس است دسترسی میکند. p = &x آنگاه *p یعنی خودِ x.
int x = 10; int* p = &x; // p آدرس x را دارد cout << p; // آدرس (هگز) cout << *p; // 10 *p = 20; // x حالا 20 شد!
خروجی ← 0x... 10
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[]
// سطح نکته: note = آسان، warning = متوسط، error = سخت
این نکتهها خلاصهٔ مهمترین بخشهای دورهاند. برای مطالعهٔ کامل هر مبحث، درس مربوطه را از فهرست درسها باز کنید.
شروع از درس اول