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

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

عملگر‌های مقایسه‌ای و دستور if

از == تا if/else: اولین گام در مسیر تصمیم‌گیری در برنامه

معمولی
مبانی و مقدمات•صفحات ۱۵-۱۶•۲۰ دقیقه•۲٬۸۶۹ کلمهزمان مطالعه: ۰ دقیقه
فهرست این درس
// اهداف۵
  • شناخت شش عملگر مقایسه‌ای (==، !=، <، >، <=، >=) و خروجی bool آن‌ها
  • درک قانون طلایی «عدد غیر صفر داخل پرانتز = true» در ⁦C++⁩
  • یادگیری ساختار کامل if و if/else و تفاوت تک‌دستور با بلوک { }
  • تشخیص و رفع باگ شماره یک مبتدی‌ها: = (انتساب) در برابر == (تساوی)
  • حل معادله درجه یک ax + b = 0 با بررسی تقسیم بر صفر

چرا به مقایسه نیاز داریم؟

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

  • اگر سن کاربر ۱۸ سال یا بیشتر بود، ورود به سایت را اجازه بده.
  • اگر رمز وارد شده با رمز ذخیره شده برابر بود، وارد حساب کاربری شو.
  • اگر نمره دانش‌آموز ۱۰ یا بیشتر بود، «قبول» چاپ کن وگرنه «مردود».
  • اگر مقدار a صفر نبود، تقسیم را انجام بده وگرنه پیام خطا نشان بده.

در همه‌ی این موارد یک مقایسه انجام می‌شود و سپس بر اساس نتیجهٔ مقایسه مسیر اجرای برنامه تغییر می‌کند. در این درس می‌آموزیم چطور در ⁦C++⁩ مقایسه کنیم و چطور از نتیجهٔ آن برای تصمیم‌گیری استفاده کنیم.

دو مفهوم کلیدی این درس عبارت‌اند از:

  1. عملگر‌های مقایسه‌ای — ابزار‌های زبان ⁦C++⁩ برای ساختن شرط‌ها.
  2. دستور if و if/else — ابزار اصلی تصمیم‌گیری در برنامه.

این درس پایه‌ی تمام درس‌های بعدی است. اگر if را خوب یاد نگیرید، در while، for، تابع و آرایه هم به مشکل می‌خورید.

جدول کامل عملگر‌های مقایسه‌ای

⁦C++⁩ شش عملگر مقایسه‌ای دارد. هر کدام دو مقدار را با هم مقایسه می‌کنند و نتیجه را به‌صورت bool (یعنی true یا false) برمی‌گردانند.

عملگرمعنیمثال (با a = 5)نتیجه
==مساوی است باa == 5true
!=مساوی نیست باa != 5false
<کوچک‌تر ازa < 10true
>بزرگ‌تر ازa > 10false
<=کوچک‌تر یا مساویa <= 5true
>=بزرگ‌تر یا مساویa >= 6false

نکته‌ها:

  • عملگر‌های == و != و <= و >= از دو کاراکتر پشت سر هم تشکیل شده‌اند. اگر بین آن‌ها فاصله بیفتد (مثلاً = =) خطای نحوی رخ می‌دهد.
  • در مقایسه‌ی اعشاری از == استفاده نکنید؛ به جای آن با یک eps کوچک مقایسه کنید (در درس محاسبات پیشرفته توضیح داده شده).
  • ترتیب در <= مهم است: یعنی همیشه < اول و = بعدش می‌آید، نه =<.
  • خروجی هر مقایسه یک مقدار bool است، یعنی فقط true یا false.

مثال ۱: نمایش مقدار true/false مقایسه‌ها

در ⁦C++⁩ هنگام چاپ مقدار bool با cout، به طور پیش‌فرض 1 (برای true) یا 0 (برای false) چاپ می‌شود. اگر می‌خواهید کلمهٔ true یا false چاپ شود، باید cout << boolalpha را اضافه کنید.

برنامه‌ای که چند مقایسه را چاپ می‌کندcpp
خروجی برنامه
a == 5   -> 1
a != 5   -> 0
a < 10   -> 1
a > 10   -> 0
a <= 5   -> 1
a >= 6   -> 0
-------------------
a == 5   -> true
a > 100  -> false

مفهوم true و false در ⁦C++⁩ (Truthy/Falsy)

یکی از مهم‌ترین مفاهیم ⁦C++⁩ که خیلی از مبتدی‌ها آن را درک نمی‌کنند این است:

هر عبارت عددی غیر صفر، در شرط به منزلهٔ true ارزیابی می‌شود، و صفر به منزلهٔ false.

یعنی دستور if (5) همیشه اجرا می‌شود (چون ۵ غیر صفر است). دستور if (0) هرگز اجرا نمی‌شود. حتی if (-3) هم true است، چون -3 غیر صفر است.

این قانون به ما اجازه می‌دهد کد را کوتاه‌تر بنویسیم. مثلاً به جای:

main.cppcpp

می‌توانیم بنویسیم:

main.cppcpp

هر دو معنی واحد دارند: «اگر n صفر نبود». اما نسخهٔ دوم فقط وقتی خواناست که n یک پرچم (flag) یا شمارنده باشد؛ اگر n یک عدد ریاضی است، نسخهٔ اول صریح‌تر و قابل‌فهم‌تر است.

نکتهٔ پیشرفته‌تر: در ⁦C++⁩ مقدار true هنگام تبدیل به int برابر 1 می‌شود، نه 1 و 0 به طور دلخواه. ولی در جهت عکس، هر عدد غیر صفر به bool تبدیل می‌شود به true. این تفاوت ظریف، گاهی باعث باگ می‌شود.

قانون طلایی: عدد غیر صفر داخل پرانتز = true

این قانون مهم‌ترین دلیل باگ شماره یک مبتدی‌هاست که در بخش بعدی توضیح می‌دهیم. آن را خوب به خاطر بسپارید:

هر چیزی که داخل پرانتز if (...) قرار می‌گیرد و در نهایت مقدارش «غیر صفر» می‌شود، به منزلهٔ true تفسیر می‌شود.

به این مثال‌ها دقت کنید:

main.cppcpp

خط آخر یک باگ خطرناک است: عبارت a = 5 ابتدا مقدار ۵ را در a می‌ریزد و سپس مقدار کل عبارت می‌شود 5. چون ۵ غیر صفر است، if به منزلهٔ true ارزیابی می‌شود! در بخش بعدی این باگ را به طور کامل تحلیل می‌کنیم.

ساختار دستور if

شکل کلی دستور if در ⁦C++⁩ به این صورت است:

main.cppcpp
  • کلمهٔ کلیدی if (با حروف کوچک).
  • پرانتز باز و بسته () که حاوی شرط است.
  • یک دستور (بدون ; بعد از پرانتز).

اگر شرط true باشد، دستور اجرا می‌شود. اگر false باشد، دستور نادیده گرفته می‌شود و برنامه به خط بعدی می‌رود.

مثال:

main.cppcpp

اگر بخواهیم چند دستور را در صورت برقراری شرط اجرا کنیم، باید آن‌ها را در یک بلوک قرار دهیم، یعنی بین { و }:

main.cppcpp

قانون طلایی: همیشه if را با بلوک { } بنویسید، حتی اگر فقط یک دستور دارید. این کار باعث می‌شود بعداً اگر دستوری اضافه کردید، فراموش نکنید که { } بگذارید. این یکی از توصیه‌های سبک کدنویسی Google و clang-tidy است.

if/else: تصمیم دو راهی و تفاوت تک‌دستور با بلوک

وقتی می‌خواهیم در صورت برقراری شرط یک کار بکنیم و در صورت عدم برقراری، کار دیگری، از ساختار if/else استفاده می‌کنیم:

main.cppcpp

مثال کلاسیک — تشخیص زوج/فرد:

main.cppcpp

تفاوت تک‌دستور و بلوک:

در نسخهٔ تک‌دستور:

main.cppcpp

خط دوم cout << " done"; همیشه اجرا می‌شود، چه شرط true باشد چه false! چون فقط اولین دستور بعد از if به آن تعلق دارد. این یکی از اشتباهات متداول مبتدی‌هاست که فکر می‌کنند هر دو خط به if تعلق دارند. برای جلوگیری از این اشتباه، همیشه از { } استفاده کنید.

در نسخهٔ بلوک:

main.cppcpp

مثال ۲: حل معادله درجه یک ax + b = 0 با if

معادلهٔ درجه یک ax + b = 0 تنها جواب x = -b / a دارد، به شرطی که a صفر نباشد. اگر a = 0 باشد، تقسیم بر صفر رخ می‌دهد و برنامه یا خطای زمان اجرا می‌دهد یا مقدار نامعتبر تولید می‌کند.

پس ساختار صحیح این است:

  1. ابتدا a و b را از ورودی بخوان.
  2. اگر a != 0 بود، x = -b / a را چاپ کن.
  3. در غیر این صورت، پیام «تقسیم بر صفر» چاپ کن.

توجه: چون ممکن است جواب اعشاری باشد، از double استفاده می‌کنیم، نه int.

بررسی تقسیم بر صفر پیش از محاسبهcpp
خروجی برنامه
ورودی ۱:
3 6
خروجی ۱:
x = -2

ورودی ۲:
0 5
خروجی ۲:
Error: division by zero (a = 0)
در حال باز کردن ویرایشگر…

فلوچارت: خواندن عدد → بررسی مثبت بودن → چاپ نتیجه

این الگوریتم ساده پایه‌ی بسیاری از برنامه‌های واقعی است: یک عدد را می‌خوانیم، با صفر مقایسه می‌کنیم و بر اساس علامت آن، پیام مناسبی چاپ می‌کنیم. شکل‌های استاندارد فلوچارت به این صورت‌اند: بیضی (شروع/پایان)، متوازی‌الأضلاع (ورودی/خروجی)، مستطیل (پردازش) و لوزی (تصمیم).

flow.svg

باگ شماره یک مبتدی‌ها: if (x = 5) در برابر if (x == 5)

این شاید رایج‌ترین باگی باشد که هر برنامه‌نویس ⁦C++⁩ یک بار آن را تجربه کرده. علامت = یک عملگر انتساب است (مقدار را در متغیر می‌ریزد)، اما علامت == یک عملگر تساوی است (مقایسه می‌کند). تفاوت ظاهراً کوچک است، اما رفتار برنامه کاملاً متفاوت می‌شود.

تحلیل نسخهٔ اشتباه (if (x = 5)):

  1. ابتدا مقدار 5 در x قرار می‌گیرد (انتساب).
  2. سپس عبارت کل x = 5 مقدار 5 را برمی‌گرداند (مقدار انتساب‌یافته).
  3. چون 5 غیر صفر است، طبق قانون «عدد غیر صفر = true»، شرط همیشه true ارزیابی می‌شود.
  4. نتیجه: بدنهٔ if همیشه اجرا می‌شود، حتی اگر x قبلاً هر چیزی بوده باشد.

این باگ به طور خاص خطرناک است چون:

  • برنامه بدون خطا کامپایل می‌شود (خطای نحوی نیست).
  • برنامه اجرا می‌شود اما رفتار اشتباه دارد (خطای منطقی).
  • پیدا کردن آن دشوار است چون ظاهر کد درست به نظر می‌رسد.

بسیاری از کامپایلر‌های مدرن یک هشدار (warning) برای این الگو صادر می‌کنند: «warning: suggest parentheses around assignment used as truth value» یا چیزی شبیه آن. همیشه هشدار‌های کامپایلر را جدی بگیرید!

راه‌حل جایگزین: برای جلوگیری از این باگ، بعضی برنامه‌نویسان از سبک Yoda Condition استفاده می‌کنند: مقدار ثابت را در سمت چپ بگذارید:

main.cppcpp

چون 5 = x معتبر نیست (نمی‌توان به ۵ مقدار داد)، این اشتباه بلافاصله به خطای کامپایل تبدیل می‌شود. اما سبک Yoda برای خواندن کمی عجیب است و در کد مدرن توصیه نمی‌شود؛ بهتر است فقط مراقب باشید.

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

هشدار خطرناک: = در برابر ==

این باگ شمار یک مبتدی‌ها در ⁦C++⁩ است. اگر یک چیز از این درس به خاطر بسپارید، این باشد:

عملگرنامکاربرد
=انتساب (Assignment)مقدار دادن به متغیر — x = 5 یعنی ۵ را در x بگذار
==تساوی (Equality)مقایسه — x == 5 یعنی آیا x برابر ۵ است؟

نشانه‌های این باگ در کد شما:

  • برنامهٔ شما همیشه یک مسیر را انتخاب می‌کند (مثلاً همیشه if اجرا می‌شود، هرگز else).
  • مقدار متغیر شما ناگهان عوض می‌شود بدون اینکه دستور صریحی برای آن نوشته باشید.
  • برنامه بدون خطا کامپایل می‌شود اما خروجی اشتباه می‌دهد.

راه‌حل عملی:

  1. همیشه از فلگ کامپایلر -Wall -Wextra استفاده کنید تا هشدار‌ها را ببینید.
  2. در محیط Code::Blocks یا VS Code، هشدار‌های زرد را نادیده نگیرید.
  3. وقتی شرطی می‌نویسید، ذهنی از خود بپرسید: «آیا می‌خواهم مقدار بدهم یا مقایسه کنم؟» اگر پاسخ «مقایسه» است، حتماً == بنویسید.
  4. بعضی کامپایلر‌ها در حالت پیش‌فرض این الگو را به‌عنوان warning اعلام می‌کنند — آن را جدی بگیرید.

مثال ۳: تشخیص زوج/فرد و علامت عدد

این مثال دو شرط را با هم ترکیب می‌کند: علامت عدد (مثبت، منفی یا صفر) و زوج/فرد بودن آن. به نحوهٔ استفاده از if/else if/else دقت کنید. ساختار else if در درس بعدی به طور کامل توضیح داده می‌شود، اما در اینجا فقط می‌خواهیم نشان دهیم که چطور می‌توان چند شرط را پشت سر هم بررسی کرد.

استفاده از if/else تودرتوی سادهcpp
خروجی برنامه
ورودی ۱:  7
خروجی ۱: positive and odd

ورودی ۲: -4
خروجی ۲: negative and even

ورودی ۳:  0
خروجی ۳: zero and even
در حال باز کردن ویرایشگر…

اولویت عملگر‌های مقایسه‌ای پایین‌تر از حسابی است

در ⁦C++⁩ عملگر‌های حسابی (*، /، +، -) اولویت بالاتری از عملگر‌های مقایسه‌ای (<، >، == و غیره) دارند. یعنی در عبارت زیر:

main.cppcpp

اول a + b محاسبه می‌شود، سپس نتیجه با c مقایسه می‌شود. یعنی این عبارت معادل (a + b) > c است.

اما برای خوانایی، همیشه از پرانتز استفاده کنید:

main.cppcpp

این کار دو فایده دارد:

  1. خوانایی بیشتر: نیت شما برای خواننده روشن‌تر است.
  2. کم‌خطاتر: اگر بعداً شرط پیچیده‌تر شد، اولویت‌ها به هم نمی‌ریزد.

نکتهٔ مهم دیگر: عملگر == اولویت پایین‌تری از < و > دارد. یعنی در عبارت زیر:

main.cppcpp

معادل (a < b) == (c < d) است. این یک عبارت معتبر است که می‌گوید «آیا نتیجهٔ مقایسهٔ a < b با نتیجهٔ c < d برابر است؟». اما چنین کدی نامفهوم است؛ حتماً با پرانتز بنویسید.

اشتباهات رایج مبتدی‌ها

در این بخش چند اشتباه متداول را مرور می‌کنیم تا مراقب آن‌ها باشید:

۱. فراموش کردن ; بعد از شرط:

main.cppcpp

اگر بعد از if (...) سمی‌کالن بگذارید، یعنی یک دستور خالی به if تعلق دارد و دستور بعدی همیشه اجرا می‌شود:

main.cppcpp

۲. اشتباه در عملگر مقایسه:

  • => به جای >= ✗ (⁦C++⁩ فقط >= را می‌شناسد)
  • =< به جای <= ✗
  • =! به جای != ✗
  • = = با فاصله به جای == ✗

۳. مقایسهٔ اعشاری با ==:

main.cppcpp

چون اعداد اعشاری در باینری دقیق نمایش داده نمی‌شوند (۰.۱ در باینری یک عدد بی‌نهایت متناوب است)، بهتر است با یک eps کوچک مقایسه کنید:

main.cppcpp

۴. فراموش کردن { } وقتی چند دستور دارید:

main.cppcpp

راه‌حل: همیشه از بلوک استفاده کنید، حتی برای یک دستور.

۵. مقایسهٔ char با int بدون درک ASCII:

main.cppcpp

این اشتباهات را در کد خود مرور کنید و سعی کنید از همان ابتدا عادت‌های درست را در خود ایجاد کنید.

جمع‌بندی و قوانین طلایی

در این درس با مفهوم تصمیم‌گیری در ⁦C++⁩ آشنا شدیم. نکات کلیدی عبارت‌اند از:

۱. شش عملگر مقایسه‌ای: ==، !=، <، >، <=، >=. هر کدام یک مقدار bool برمی‌گردانند.

۲. قانون «عدد غیر صفر = true»: هر عبارت عددی که در پرانتز if (...) قرار می‌گیرد، اگر غیر صفر باشد true و اگر صفر باشد false ارزیابی می‌شود.

۳. ساختار if/else:

main.cppcpp

۴. باگ شماره یک: = انتساب است، == تساوی است. if (x = 5) همیشه true است.

۵. همیشه از { } استفاده کنید: حتی اگر فقط یک دستور دارید. این کار از باگ‌های ظریف جلوگیری می‌کند.

۶. اولویت عملگر‌ها: حسابی (*، /، +، -) بالاتر از مقایسه‌ای (<، >، ==) است. برای خوانایی، از پرانتز استفاده کنید.

۷. تقسیم بر صفر: همیشه قبل از تقسیم، صفر نبودن مخرج را با if بررسی کنید.

در درس بعدی، با عملگر‌های منطقی (&&، ||، !) و if تودرتو آشنا می‌شویم و با ترکیب چند شرط، برنامه‌های پیچیده‌تری می‌نویسیم — مثل تشخیص نوع مثلث و حل معادلهٔ درجه دو.

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

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

تمرین‌ها

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

برنامه‌ای بنویسید که یک عدد صحیح n را بگیرد و تعیین کند آیا n مضرب ۵ است یا نه. خروجی: "Yes" یا "No".

نمایش راهنما
از عملگر باقی‌مانده % استفاده کنید: اگر n % 5 == 0 بود، مضرب ۵ است.
02
تمرین•حل کامل دارد

برنامه‌ای بنویسید که سن کاربر را بگیرد. اگر سن ۱۸ یا بیشتر بود، پیام "Adult" چاپ کند؛ اگر بین ۱۳ و ۱۷ بود، "Teen"؛ و در غیر این صورت "Child". (از if/else if/else استفاده کنید.)

نمایش راهنما
به ترتیب شرط‌ها را بنویسید: اول >= 18، بعد >= 13، در نهایت else برای بقیه.
03
تمرین•حل کامل دارد

برنامه‌ای بنویسید که دو عدد a و b را بگیرد و بزرگ‌تر را چاپ کند. اگر برابر بودند، پیام "Equal" چاپ کند. (از if/else if/else استفاده کنید.)

نمایش راهنما
سه حالت دارید: a > b، a < b، a == b. هر کدام را با if جداگانه بررسی کنید.
04
تمرین•حل کامل دارد

برنامه‌ای بنویسید که سه ضلع a، b، c را بگیرد و تعیین کند آیا این سه عدد می‌توانند اضلاع یک مثلث قائم‌الزاویه باشند یا نه (قانون فیثاغورث). اگر بود، "Right Triangle" چاپ کند، وگرنه "Not Right". فرض کنید اضلاع به ترتیب داده شده‌اند و c می‌تواند ضلع قائم باشد یا a یا b — باید هر سه حالت را بررسی کنید.

نمایش راهنما
قانون فیثاغورث: مربع طولانی‌ترین ضلع = مجموع مربعات دو ضلع دیگر. پس سه شرط دارید: a*a == b*b + c*c یا b*b == a*a + c*c یا c*c == a*a + b*b. برای «یا» از عملگر || (در درس بعدی) استفاده کنید یا سه if پشت سر هم بنویسید.
// نکات-کلیدی۵
  • 01شش عملگر مقایسه‌ای ⁦C++⁩: == (تساوی)، != (نامساوی)، <، >، <=، >=. هر کدام یک مقدار bool برمی‌گردانند.
  • 02قانون طلایی: هر عدد غیر صفر داخل پرانتز if به منزلهٔ true ارزیابی می‌شود؛ صفر به منزلهٔ false.
  • 03باگ شماره یک: = (انتساب) یک علامت است، == (تساوی) دو علامت. if (x = 5) همیشه true است چون 5 در x می‌رود و مقدار عبارت غیر صفر می‌شود.
  • 04همیشه از بلوک { } برای if/else استفاده کنید، حتی اگر فقط یک دستور دارید، از باگ‌های ظریف جلوگیری می‌کند.
  • 05اولویت عملگر‌ها: حسابی (*)، (/)، (+)، (-) بالاتر از مقایسه‌ای (<)، (>)، (==) است؛ برای خوانایی از پرانتز استفاده کنید.
گام بعدی پیشنهادی

عملگر‌های منطقی و if تودرتو

ترکیب شرط‌ها با &&، || و ! و ساختار‌بندی تصمیمات پیچیده

۲۵ دقیقهمتوسط۱۵ بخش

شروع درس

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

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