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

پرش به محتوای اصلی
>_
درس ۲مقدماتی

متغیر‌ها و انواع داده

جعبه‌های حافظه، انواع داده و چرایی مقداردهی اولیه

معمولی
مبانی و مقدمات•صفحات ۳-۵ و ۷-۸•۲۰ دقیقه•۲٬۷۹۸ کلمهزمان مطالعه: ۰ دقیقه
فهرست این درس
// اهداف۵
  • درک مفهوم متغیر به‌عنوان جعبه‌ای در حافظه و رابطه آن با RAM
  • تمایز دقیق میان اعلان (Declaration) و مقداردهی (Assignment)
  • شناخت کامل انواع داده اصلی ⁦C++⁩: int، float، double و char
  • یادگیری قوانین نام‌گذاری متغیر‌ها و چرایی اهمیت نام‌های معنادار
  • پیاده‌سازی محاسبه مساحت و محیط مستطیل و حل دستگاه دو معادله دو مجهول

متغیر چیست؟ مفهوم جعبه حافظه

یک متغیر (Variable) مثل یک جعبه است که در آن یک مقدار را ذخیره می‌کنیم. هر جعبه دو چیز دارد:

  • یک نام (برچسب روی جعبه) — مثلاً age یا sum.
  • یک مقدار (محتوای داخل جعبه) — مثلاً 18 یا 42.

در کامپیوتر، این «جعبه» در واقع یک خانه از حافظه RAM است. وقتی می‌نویسیم:

main.cppcpp

کامپایلر در RAM یک فضای ۴ بایتی پیدا می‌کند، آن را به نام age ثبت می‌کند، و عدد 18 را در آن قرار می‌دهد. از آن به بعد، هر بار که بنویسیم age، کامپیوتر به آن خانه از RAM نگاه می‌کند و مقدارش را برمی‌گرداند.

چرا به آن «متغیر» می‌گویند؟ چون مقدارش می‌تواند تغییر کند (عکس «ثابت» که مقدارش همیشه یکسان است). یعنی می‌توانیم بعداً بنویسیم age = 19; و مقدار داخل جعبه عوض شود.

نکته کلیدی: نام متغیر در زمان کامپایل به یک آدرس عددی در RAM تبدیل می‌شود. برنامه‌نویس با نام کار می‌کند، اما کامپیوتر در واقعیت فقط با آدرس‌ها کار می‌کند.

RAM موقت است؛ داده‌ها از بین می‌روند

یکی از مهم‌ترین مفاهیمی که در صفحه اول جزوه با تأکید آمده: داده‌های ذخیره‌شده در RAM موقتی هستند و با خاموش شدن کامپیوتر از بین می‌روند.

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

برای ذخیره دائمی داده‌ها باید آن‌ها را در هارد دیسک (Hard Disk) یا SSD ذخیره کنید (مثلاً در یک فایل). در درس‌های بعدی با فایل‌ها آشنا خواهیم شد، اما فعلاً به خاطر داشته باشید:

  • ● RAM = سریع اما موقت
  • ◎ هارد دیسک = کند اما ماندگار

این یعنی اگر برنامه شما اطلاعاتی دارد که باید برای اجرای بعدی نگه داشته شود، حتماً آن را در فایل ذخیره کنید.

اعلان در برابر مقداردهی

دو عمل مختلف در ⁦C++⁩ وجود دارد که اغلب اشتباه گرفته می‌شوند:

اعلان (Declaration): به کامپایلر می‌گوید «یک متغیر با این نام و این نوع بساز».

main.cppcpp

پس از این خط، کامپایلر فضای ۴ بایتی در RAM برای age کنار می‌گذارد، اما مقدارش نامشخص است.

مقداردهی (Initialization) یا انتساب (Assignment): مقداری در آن متغیر قرار می‌دهد.

main.cppcpp

می‌توان هر دو را در یک خط انجام داد:

main.cppcpp

تفاوت مهم: اعلان فقط یک‌بار لازم است؛ اما انتساب می‌تواند چندین بار انجام شود.

main.cppcpp

نکته: در ⁦C++⁩ مدرن، توصیه می‌شود همیشه هنگام اعلان، مقداردهی اولیه هم انجام دهید تا از مقدار‌های زباله‌ای (Garbage Value) که به‌طور پیش‌فرض در متغیر قرار دارند، جلوگیری شود.

انواع داده اصلی در ⁦C++⁩

در ⁦C++⁩ هر متغیر باید یک نوع داده (Data Type) داشته باشد. نوع داده دو چیز را مشخص می‌کند:

۱. چقدر فضا در RAM اشغال می‌کند. ۲. چه نوع مقادیری می‌توان در آن ذخیره کرد (عدد صحیح، اعشاری، کاراکتر، ...).

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

نوعمعنااندازه (بایت)بازه تقریبیمثال
intعدد صحیح۴‎−۲,۱۴۷,۴۸۳,۶۴۸ تا ۲,۱۴۷,۴۸۳,۶۴۷42، -7
floatعدد اعشاری (دقت معمولی)۴حدود ۷ رقم معنادار (significant digits)3.14، -0.5
doubleعدد اعشاری (دقت مضاعف)۸حدود ۱۵ رقم معنادار3.141592653589
charیک کاراکتر۱کاراکتر‌های ASCII'A'، '9'، '\n'

علاوه بر این، انواع دیگری هم وجود دارد که بعداً معرفی می‌شوند:

  • bool برای مقادیر منطقی (true/false) — ۱ بایت.
  • long و long long برای اعداد صحیح بزرگ‌تر.
  • string برای رشته‌های متنی (مجموعه‌ای از کاراکتر‌ها).
  • unsigned int برای اعداد صحیح بدون علامت (فقط مثبت یا صفر).

قاعده انتخاب نوع: برای اعداد صحیح معمولی از int، برای اعشار معمولی از double (نه float، چون دقت بیشتری دارد)، و برای کاراکتر‌ها از char استفاده کنید.

قوانین نام‌گذاری متغیر‌ها

در ⁦C++⁩ نام متغیر باید این قوانین را رعایت کند:

۱. فقط شامل حروف انگلیسی (a-z, A-Z)، ارقام (0-9) و زیرخط (_) باشد. ۲. با رقم شروع نشود. 2nd مجاز نیست؛ x2 یا student_2 مجاز است. ۳. نباید کلمه کلیدی باشد. کلماتی مثل int، for، if، return نمی‌توانند نام متغیر باشند. ۴. حساس به بزرگی/کوچکی حروف (Case-Sensitive) است. age و Age و AGE سه متغیر مختلف هستند. ۵. طول نام می‌تواند هرچقدر باشد، اما توصیه می‌شود کوتاه و معنادار باشد.

مثال نام‌های درست:

  • age، sum، count، total_price
  • studentName، MAX_SIZE، n2

مثال نام‌های غلط:

  • 2count (شروع با رقم)
  • int (کلمه کلیدی)
  • total price (فاصله مجاز نیست)
  • total-price (خط تیره مجاز نیست، در ⁦C++⁩ عملگر تفریق است)

در نسخه اصلی جزوه، یک باگ کلاسیک وجود داشت: متغیر با حرف کوچک w تعریف می‌شد اما با حرف بزرگ W استفاده می‌شد (cin >> W;). این یکی از رایج‌ترین منابع خطا برای تازه‌کارهاست.

بهترین شیوه‌ها برای انتخاب نام متغیر

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

  • نام‌های تک‌حرفی فقط برای شمارنده‌های حلقه یا متغیر‌های ریاضی استفاده کنید: i, j, k, x, y.
  • برای بقیه موارد، نام توصیفی بنویسید: studentCount به جای s، totalPrice به جای tp.
  • از سبک camelCase استفاده کنید (حرف اول کلمه دوم بزرگ): studentCount، firstName، maxValue.
  • برای ثابت‌ها از UPPER_SNAKE_CASE استفاده کنید: MAX_STUDENTS = 100، PI = 3.14.
  • نام را کوتاه اما گویا نگه دارید: n خوب، numberOfStudents خوب، اما n برای «تعداد دانش‌آموزان» بد است.
  • از نام‌های مبهم پرهیز کنید: data، value، temp معمولاً جای نام بهتر دارند.
  • مخفف‌های نامفهوم نسازید: stnm به جای studentName بد است.

نکته جالب: در مطالعات نرم‌افزاری نشان داده شده که برنامه‌نویسان بیش از ۵۰٪ زمان خود را صرف خواندن کد می‌کنند، نه نوشتن آن. نام‌های خوب، سرمایه‌گذاری برای صرفه‌جویی در زمان آینده است.

چرا مقداردهی اولیه مهم است؟

وقتی متغیری را اعلان می‌کنید اما مقداردهی نمی‌کنید، کامپایلر فضایی در RAM برایش کنار می‌گذارد، اما آن فضا خالی نیست؛ هرچه قبلاً در آن خانه از حافظه بوده (مثلاً از برنامه‌ای که قبلاً اجرا می‌شده) همچنان آنجاست. به این مقدار Garbage Value (مقدار زباله) می‌گویند.

main.cppcpp

این رفتار Undefined Behavior (رفتار نامشخص) نام دارد. یعنی استاندارد ⁦C++⁩ تضمین نمی‌کند چه اتفاقی می‌افتد:

  • ممکن است هر بار برنامه را اجرا کنید، خروجی متفاوتی ببینید.
  • ممکن است روی کامپیوتر شما درست کار کند اما روی کامپیوتر استاد درس خراب شود.
  • ممکن است با کامپایلر‌های مختلف رفتار متفاوت داشته باشد.

راه‌حل: همیشه همزمان با اعلان، مقداردهی اولیه انجام دهید:

main.cppcpp

این عادت ساده، صدها ساعت دیباگ را از شما صرفه‌جویی می‌کند. در نسخه اولیه جزوه، متغیرهایی مثل sum و max بدون مقداردهی اولیه استفاده شده بودند که می‌توانست منجر به رفتار نامشخص شود.

تله‌های رایج با متغیر‌ها

چند خطای بسیار رایج برای تازه‌کار‌ها:

۱. استفاده از متغیر قبل از اعلان. در ⁦C++⁩ هر متغیر باید قبل از استفاده اعلان شود. اگر بنویسید cin >> x; بدون اینکه قبلاً int x; نوشته باشید، خطای کامپایل می‌گیرید.

۲. فراموش کردن نوع داده. در نسخه اولیه جزوه، تابع main() بدون نوع بازگشتی نوشته شده بود. این اشتباه است؛ باید int main() باشد.

۳. اشتباه در بزرگی/کوچکی حروف. مثلاً int w; تعریف می‌کنید اما بعد cin >> W; می‌نویسید. این دو متغیر متفاوت هستند و کامپایلر خطا می‌دهد (یا بدتر، در بعضی حالت‌ها یک متغیر جدید W اعلان می‌کند).

۴. عدم تعریف متغیر‌های میانی. در مثال مستطیل جزوه، متغیر‌های S و P استفاده شده بودند اما تعریف نشده بودند. همیشه هر متغیری را که استفاده می‌کنید، اول اعلان کنید.

۵. استفاده از کلمات کلیدی به‌عنوان نام. int int; یا float for; مجاز نیستند.

۶. اشتباه در نوع داده تقسیم. اگر int a = 5, b = 2; cout << a / b; بنویسید، خروجی 2 است نه 2.5، چون تقسیم دو int تقسیم صحیح است. باید حداقل یکی را به double تبدیل کنید: cout << (double)a / b;

مسئله: مساحت و محیط مستطیل

یکی از نمونه‌های کلاسیک برای تمرین متغیرها، محاسبه مساحت و محیط مستطیل است.

ورودی: طول (L) و عرض (W). خروجی: مساحت (S) و محیط (P).

فرمول‌ها:

  • مساحت: $S = L \times W$
  • محیط: $P = 2 \times (L + W)$

این مسئله به‌ظاهر ساده چند نکته آموزشی دارد:

۱. انتخاب نوع داده: چون طول و عرض ممکن است اعشاری باشند، از double استفاده می‌کنیم. ۲. نام‌گذاری معنادار: L, W, S, P نام‌های ریاضی کلاسیک هستند (Length، Width، Surface، Perimeter). ۳. اولویت عملگر‌ها: در فرمول محیط باید پرانتز باشد: 2 * (L + W) نه 2 * L + W (که می‌شود 2L + W اشتباه). ۴. اعلان همه متغیر‌ها: هم L و W (ورودی) و هم S و P (خروجی) باید اعلان شوند.

در نسخه اولیه جزوه، متغیر‌های S و P فراموش شده بودند، در نام‌گذاری w و W اشتباه شده بود، و تابع main() نوع بازگشتی نداشت. در نسخه اصلاح‌شده زیر همه این موارد رفع شده‌اند.

پیاده‌سازی: مساحت و محیط مستطیل

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

  • از double استفاده کرده‌ایم تا اعداد اعشاری هم پشتیبانی شوند.
  • متغیر‌های S و P را به‌صورت جداگانه اعلان و مقداردهی اولیه کرده‌ایم.
  • نام متغیر‌ها یکدست است (L, W, S, P، همگی حرف بزرگ).
  • cout با حرف کوچک نوشته شده است (Case-Sensitive).
  • تابع main() نوع بازگشتی int دارد و با return 0; تمام می‌شود.
برنامه کامل با استفاده از double و نام‌گذاری یکدستcpp
خروجی برنامه
tol va arz ra vared konid: 4.5 3
Masahat = 13.5
Mohit   = 15
در حال باز کردن ویرایشگر…

فلوچارت: محاسبه مساحت و محیط مستطیل

flow.svg

اصلاح: تابع main() بدون نوع بازگشتی

در نسخه اولیه جزوه (صفحه ۷ و ۸)، تابع main() بدون نوع بازگشتی نوشته شده بود. این در ⁦C++⁩ استاندارد غلط است و در کامپایلر‌های مدرن (مثل GCC یا Clang) خطای کامپایل می‌دهد یا حداقل هشدار تولید می‌کند.

استاندارد ⁦C++⁩ (هم نسخه ۹۸ و هم نسخه‌های مدرن ۱۷/۲۰) صراحتاً می‌گوید تابع main باید نوع بازگشتی int داشته باشد. مقدار بازگشتی به سیستم‌عامل می‌گوید برنامه با موفقیت تمام شد (0) یا با خطایی مواجه شد (غیر صفر).

همچنین return 0; در پایان برنامه قرارداد استانداردی است که می‌گوید «برنامه درست تمام شد».

نسخه اشتباه جزوه
کد دارای باگcpp
نسخه اصلاح‌شده و استاندارد
کد صحیحcpp

مسئله: حل دستگاه دو معادله دو مجهول

فرض کنید دستگاه معادلات خطی زیر را داریم:

$$\begin{cases} a_1 x + b_1 y = c_1 \ a_2 x + b_2 y = c_2 \end{cases}$$

می‌خواهیم مقادیر x و y را پیدا کنیم. با استفاده از قاعده کرامر (Cramer's Rule):

$$x = \frac{c_1 b_2 - c_2 b_1}{a_1 b_2 - a_2 b_1}$$

$$y = \frac{a_1 c_2 - a_2 c_1}{a_1 b_2 - a_2 b_1}$$

به مخرج مشترک دقت کنید: $D = a_1 b_2 - a_2 b_1$. این مقدار ** determinant دستگاه** نامیده می‌شود.

حالت‌های ممکن:

۱. اگر $D \neq 0$: دستگاه یک جواب یکتا دارد (فرمول‌های بالا). ۲. اگر $D = 0$ و صورت هر دو کسر هم صفر باشد: دستگاه بی‌نهایت جواب دارد (دو معادله وابسته). ۳. اگر $D = 0$ ولی صورت کسر‌ها صفر نباشد: دستگاه جواب ندارد (دو معادله ناسازگار).

این مسئله نمونه‌ای عالی از ترکیب ریاضیات و برنامه‌نویسی است و نشان می‌دهد چطور یک فرمول ریاضی مستقیماً به کد تبدیل می‌شود. فقط باید به تقسیم بر صفر دقت کنیم.

پیاده‌سازی: حل دستگاه دو معادله دو مجهول

این برنامه شش ضریب دستگاه را می‌گیرد و مقادیر x و y را چاپ می‌کند. اگر D = 0 باشد، پیام مناسب چاپ می‌شود.

نکات کد:

  • همه متغیر‌ها از نوع double هستند تا تقسیم اعشاری درست انجام شود.
  • مخرج D را اول محاسبه می‌کنیم و سپس چک می‌کنیم صفر نیست.
  • از نام‌های a1, b1, c1, a2, b2, c2 استفاده کرده‌ایم که با نمادگذاری ریاضی هم‌خوان است.
برنامه کامل با کنترل خطای D = 0 و استفاده از double برای دقت اعشاریcpp
خروجی برنامه
Zarayeb-e moadele-ye avval (a1 b1 c1): 1 1 3
Zarayeb-e moadele-ye dovvom (a2 b2 c2): 1 -1 1
x = 2
y = 1

(بررسی: x=2, y=1 در هر دو معادله: 2+1=3 ✓ و 2-1=1 ✓)

مثال اجرای دستگاه معادلات

دستگاه زیر را حل می‌کنیم: $$\begin{cases} 2x + 3y = 8 \ x - y = 1 \end{cases}$$

ضریب‌ها: a1=2, b1=3, c1=8 و a2=1, b2=-1, c2=1.

محاسبه determinant: D = a1*b2 - a2*b1 = 2*(-1) - 1*3 = -2 - 3 = -5

چون D ≠ 0، یک جواب یکتا داریم.

محاسبه x: x = (c1*b2 - c2*b1) / D = (8*(-1) - 1*3) / -5 = (-8 - 3) / -5 = -11 / -5 = 2.2

محاسبه y: y = (a1*c2 - a2*c1) / D = (2*1 - 1*8) / -5 = (2 - 8) / -5 = -6 / -5 = 1.2

بررسی: در معادله اول: 2(2.2) + 3(1.2) = 4.4 + 3.6 = 8 ✓ در معادله دوم: 2.2 - 1.2 = 1 ✓

پس جواب درست است. این ردیابی (Trace) نشان می‌دهد چطور برنامه با ورودی کار می‌کند و چطور می‌توانیم اعتبارسنجی کنیم.

راهنمای انتخاب نوع داده

برای انتخاب نوع داده مناسب، این سؤال‌ها را از خود بپرسید:

۱. آیا مقدار اعشاری است؟

  • بله → از double استفاده کنید (نه float؛ double دقت بیشتری دارد و در کامپیوتر‌های مدرن هم‌سرعت است).
  • خیر → به سؤال بعد بروید.

۲. آیا عدد ممکن است خیلی بزرگ شود (بیشتر از ۲ میلیارد)؟

  • بله → از long long استفاده کنید (تا حدود ۹ کوینتیلیون).
  • خیر → int کافی است.

۳. آیا مقدار همیشه مثبت است؟

  • بله → می‌توانید از unsigned int استفاده کنید (دو برابر بازه مثبت).
  • خیر → از نوع علامت‌دار استفاده کنید.

۴. آیا فقط یک کاراکتر است؟

  • بله → از char استفاده کنید.
  • اگر رشته‌ای از چند کاراکتر است → از string (که در درس‌های بعدی معرفی می‌شود).

۵. آیا مقدار منطقی (درست/غلط) است؟

  • بله → از bool استفاده کنید.

نکته عملی: وقتی شک دارید، int برای اعداد صحیح و double برای اعشاری، انتخاب پیش‌فرض خوبی است. این دو نوع برای ۹۰٪ موارد کافی هستند.

مرور سریع مطالب

۱۶ بخش در این درس

تمرین‌ها

01
تمرین•حل کامل دارد

برنامه‌ای بنویسید که شعاع دایره را از ورودی بگیرد و مساحت (πr²) و محیط (2πr) را چاپ کند. از مقدار ثابت `PI = 3.14159` استفاده کنید.

نمایش راهنما
یک ثابت double به نام PI تعریف کنید. مساحت = PI * r * r، محیط = 2 * PI * r. نوع داده را double انتخاب کنید تا اعشار حفظ شود.
02
تمرین•حل کامل دارد

برنامه‌ای بنویسید که دمای هوا را به‌صورت سانتی‌گراد بگیرد و معادل فارنهایتی آن را چاپ کند. فرمول: F = (9/5)*C + 32.

نمایش راهنما
مراقب تقسیم صحیح باشید! 9/5 در ⁦C++⁩ برابر 1 می‌شود (تقسیم صحیح). بنویسید 9.0/5.0 یا (double)9/5 یا 1.8.
03
تمرین•حل کامل دارد

برنامه‌ای بنویسید که سه نمره دانش‌آموز را از ورودی بگیرد و میانگین آن‌ها را چاپ کند. حتماً از double استفاده کنید.

نمایش راهنما
اگر نمره‌ها را در int ذخیره کنید، میانگین هم int می‌شود و اعشار حذف می‌شود. یا از ابتدا double تعریف کنید، یا در خط آخر از (double) برای cast استفاده کنید.
04
تمرین•حل کامل دارد

برنامه‌ای بنویسید که یک کاراکتر از ورودی بگیرد و کد ASCII آن را چاپ کند.

نمایش راهنما
اگر متغیر char را به int تبدیل (cast) کنید، کد ASCII به‌دست می‌آید. مثلاً (int)ch یا int(ch).
05
تمرین•حل کامل دارد

برنامه‌ای بنویسید که طول سه ضلع یک مثلث را بگیرد و مساحت آن را با فرمول هرون محاسبه کند. فرمول: s = (a+b+c)/2، مساحت = √(s(s-a)(s-b)(s-c)). برای جذر از کتابخانه <cmath> استفاده کنید.

نمایش راهنما
ابتدا #include <cmath> را اضافه کنید. سپس sqrt(expression) برای جذر استفاده کنید. همه متغیر‌ها را double تعریف کنید.
// نکات-کلیدی۶
  • 01متغیر جعبه‌ای در حافظه RAM است که مقدار را در خود نگه می‌دارد؛ موقت است و با خاموش شدن کامپیوتر از بین می‌رود.
  • 02اعلان (Declaration) فقط فضای حافظه را کنار می‌گذارد؛ مقداردهی (Assignment) مقدار واقعی در آن می‌ریزد.
  • 03انواع اصلی داده عبارت‌اند از: int (صحیح)، float و double (اعشاری)، char (کاراکتر).
  • 04⁦C++⁩ حساس به بزرگی/کوچکی حروف است؛ `w` و `W` دو متغیر مختلف هستند.
  • 05همیشه هنگام اعلان، متغیر‌ها را مقداردهی اولیه کنید تا از Garbage Value و رفتار نامشخص جلوگیری شود.
  • 06تابع main در ⁦C++⁩ استاندارد باید نوع بازگشتی int داشته باشد و با return 0; تمام شود.
گام بعدی پیشنهادی

اولین برنامه ⁦C++⁩

ساختار برنامه، Hello World، cout و cin، کامنت‌ها و کامپایل

۱۶ دقیقهمقدماتی۱۷ بخش

شروع درس

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

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