شناخت شش عملگر مقایسهای (==، !=، <، >، <=، >=) و خروجی bool آنها
درک قانون طلایی «عدد غیر صفر داخل پرانتز = true» در C++
یادگیری ساختار کامل if و if/else و تفاوت تکدستور با بلوک { }
تشخیص و رفع باگ شماره یک مبتدیها: = (انتساب) در برابر == (تساوی)
حل معادله درجه یک ax + b = 0 با بررسی تقسیم بر صفر
چرا به مقایسه نیاز داریم؟
تا اینجا برنامههایمان خطی بودند: یک سری دستور از بالا به پایین اجرا میشد و تمام. اما دنیای واقعی چنین سادهای نیست. ما باید بتوانیم تصمیم بگیریم:
اگر سن کاربر ۱۸ سال یا بیشتر بود، ورود به سایت را اجازه بده.
اگر رمز وارد شده با رمز ذخیره شده برابر بود، وارد حساب کاربری شو.
اگر نمره دانشآموز ۱۰ یا بیشتر بود، «قبول» چاپ کن وگرنه «مردود».
اگر مقدار a صفر نبود، تقسیم را انجام بده وگرنه پیام خطا نشان بده.
در همهی این موارد یک مقایسه انجام میشود و سپس بر اساس نتیجهٔ مقایسه مسیر اجرای برنامه تغییر میکند. در این درس میآموزیم چطور در C++ مقایسه کنیم و چطور از نتیجهٔ آن برای تصمیمگیری استفاده کنیم.
دو مفهوم کلیدی این درس عبارتاند از:
عملگرهای مقایسهای — ابزارهای زبان C++ برای ساختن شرطها.
دستور if و if/else — ابزار اصلی تصمیمگیری در برنامه.
این درس پایهی تمام درسهای بعدی است. اگر if را خوب یاد نگیرید، در while، for، تابع و آرایه هم به مشکل میخورید.
جدول کامل عملگرهای مقایسهای
C++ شش عملگر مقایسهای دارد. هر کدام دو مقدار را با هم مقایسه میکنند و نتیجه را بهصورت bool (یعنی true یا false) برمیگردانند.
عملگر
معنی
مثال (با a = 5)
نتیجه
==
مساوی است با
a == 5
true
!=
مساوی نیست با
a != 5
false
<
کوچکتر از
a < 10
true
>
بزرگتر از
a > 10
false
<=
کوچکتر یا مساوی
a <= 5
true
>=
بزرگتر یا مساوی
a >= 6
false
نکتهها:
عملگرهای == و != و <= و >= از دو کاراکتر پشت سر هم تشکیل شدهاند. اگر بین آنها فاصله بیفتد (مثلاً = =) خطای نحوی رخ میدهد.
در مقایسهی اعشاری از == استفاده نکنید؛ به جای آن با یک 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 باشد، تقسیم بر صفر رخ میدهد و برنامه یا خطای زمان اجرا میدهد یا مقدار نامعتبر تولید میکند.
پس ساختار صحیح این است:
ابتدا a و b را از ورودی بخوان.
اگر a != 0 بود، x = -b / a را چاپ کن.
در غیر این صورت، پیام «تقسیم بر صفر» چاپ کن.
توجه: چون ممکن است جواب اعشاری باشد، از 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)):
ابتدا مقدار 5 در x قرار میگیرد (انتساب).
سپس عبارت کل x = 5 مقدار 5 را برمیگرداند (مقدار انتسابیافته).
چون 5 غیر صفر است، طبق قانون «عدد غیر صفر = true»، شرط همیشه true ارزیابی میشود.
نتیجه: بدنهٔ 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).
مقدار متغیر شما ناگهان عوض میشود بدون اینکه دستور صریحی برای آن نوشته باشید.
برنامه بدون خطا کامپایل میشود اما خروجی اشتباه میدهد.
راهحل عملی:
همیشه از فلگ کامپایلر -Wall -Wextra استفاده کنید تا هشدارها را ببینید.
در محیط Code::Blocks یا VS Code، هشدارهای زرد را نادیده نگیرید.
وقتی شرطی مینویسید، ذهنی از خود بپرسید: «آیا میخواهم مقدار بدهم یا مقایسه کنم؟» اگر پاسخ «مقایسه» است، حتماً == بنویسید.
بعضی کامپایلرها در حالت پیشفرض این الگو را بهعنوان 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
این کار دو فایده دارد:
خوانایی بیشتر: نیت شما برای خواننده روشنتر است.
کمخطاتر: اگر بعداً شرط پیچیدهتر شد، اولویتها به هم نمیریزد.
نکتهٔ مهم دیگر: عملگر == اولویت پایینتری از < و > دارد. یعنی در عبارت زیر:
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 تودرتو آشنا میشویم و با ترکیب چند شرط، برنامههای پیچیدهتری مینویسیم — مثل تشخیص نوع مثلث و حل معادلهٔ درجه دو.
برنامهای بنویسید که یک عدد صحیح 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 تودرتو
ترکیب شرطها با &&، || و ! و ساختاربندی تصمیمات پیچیده
if(5) cout <<"A";// چاپ میشود، چون 5 غیر صفر استif(0) cout <<"B";// چاپ نمیشود، چون 0 یعنی falseif(-7) cout <<"C";// چاپ میشود، چون -7 غیر صفر استif(a =5) cout <<"D";// چاپ میشود!! (اما چرا؟)
if(شرط) دستور;
if(n >0) cout <<"positive";
if(n >0){ cout <<"positive"; sum += n; count++;}
if(شرط){// این بخش در صورت true بودن شرط}else{// این بخش در صورت false بودن شرط}
if(n %2==0){ cout <<"even";}else{ cout <<"odd";}
if(x >0) cout <<"positive"; cout <<" done";// توجه! این همیشه اجرا میشود
if(x >0){ cout <<"positive"; cout <<" done";// این فقط در صورت true بودن اجرا میشود}
1#include<iostream>2usingnamespace std;34intmain(){5double a =0, b =0;6 cout <<"Enter a and b: ";7 cin >> a >> b;89if(a !=0){10double x =-b / a;11 cout <<"x = "<< x << endl;12}else{13 cout <<"Error: division by zero (a = 0)"<< endl;14}1516return0;17}18
flow.svg100%
Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.
شروع/پایانپردازشتصمیمورودی/خروجی
if(5== x)// اگر = بنویسید، کامپایلر خطا میدهد
1// ✗ باگ: = (انتساب) به جای == (تساوی)2#include<iostream>3usingnamespace std;45intmain(){6int x =0;7 cin >> x;8if(x =5){// 5 در x ریخته میشود، سپس 5 غیر صفر = true9 cout <<"x is five";// همیشه چاپ میشود!10}else{11 cout <<"x is not five";// هرگز اجرا نمیشود12}13 cout <<"x = "<< x;// x حالا 5 است، حتی اگر ورودی 0 بود14return0;15}16
1// ✓ صحیح: == (تساوی) برای مقایسه2#include<iostream>3usingnamespace std;45intmain(){6int x =0;7 cin >> x;8if(x ==5){// x با 5 مقایسه میشود9 cout <<"x is five";10}else{11 cout <<"x is not five";12}13 cout <<"x = "<< x;// x دستنخورده باقی میماند14return0;15}16
1#include<iostream>2usingnamespace std;34intmain(){5int n =0;6 cout <<"Enter an integer: ";7 cin >> n;89// بررسی علامت عدد10if(n >0){11 cout <<"positive";12}elseif(n <0){13 cout <<"negative";14}else{15 cout <<"zero";16}1718 cout <<" and ";1920// بررسی زوج/فرد21if(n %2==0){22 cout <<"even"<< endl;23}else{24 cout <<"odd"<< endl;25}2627return0;28}29
a + b > c
if((a + b)> c){...}
a < b == c < d
if(n >0)// اینجا ; نگذارید! cout <<"positive";
if(n >0);// این if یک دستور خالی دارد! cout <<"positive";// همیشه اجرا میشود
if(x ==0.1){...}// ممکن است false شود حتی اگر x = 0.1 باشد!