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

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

الگوریتم و فلوچارت چیست؟

قدم به قدم با اولین زبان مشترک انسان و کامپیوتر

معمولی
مبانی و مقدمات•صفحات ۱-۲•۱۸ دقیقه•۲٬۷۵۶ کلمهزمان مطالعه: ۰ دقیقه
فهرست این درس
// اهداف۵
  • تعریف دقیق الگوریتم و درک چرایی نیاز به آن پیش از نوشتن کد
  • شناخت کامل نماد‌های استاندارد فلوچارت: بیضی، مستطیل، لوزی، متوازی‌الاضلاع و فلش
  • ترسیم فلوچارت برای سه مسئله کلاسیک: جابه‌جایی دو مقدار، یافتن بزرگترین و حل معادله درجه یک
  • تفاوت برنامه‌نویسی بدون تفکر الگوریتمی و برنامه‌نویسی با تفکر الگوریتمی
  • توانایی خواندن، تفسیر و ردیابی (Trace) فلوچارت‌های موجود

الگوریتم چیست؟

یک الگوریتم (Algorithm) مجموعه‌ای محدود، مشخص و ترتیبی از گام‌هاست که برای حل یک مسئله یا انجام یک کار طراحی شده است. به زبان ساده‌تر: الگوریتم «دستور پخت» حل مسئله است.

برای نمونه، الگوریتم تهیه یک چای ساده این‌گونه است:

۱. آب را در کتری بریز. ۲. کتری را روی اجاق بگذار. ۳. صبر کن تا آب به جوش آید. ۴. یک قاشق چای‌خوری چای داخل فنجان بریز. ۵. آب جوش را روی چای بریز. ۶. صبر کن تا چای دم بکشد. ۷. اگر دوست داری، شکر اضافه کن.

این الگوریتم سه ویژگی کلیدی دارد که هر الگوریتمی باید داشته باشد:

  • محدود بودن: تعداد گام‌ها مشخص و متناهی است.
  • قطعی بودن: هر گام به‌طور روشن تعریف شده و ابهام ندارد.
  • ترتیبی بودن: گام‌ها باید به ترتیب درست اجرا شوند.

در برنامه‌نویسی، الگوریتم قبل از کد نوشته می‌شود؛ چون کد فقط پیاده‌سازی الگوریتم به زبان کامپیوتر است. اگر الگوریتم درست نباشد، حتی بهترین کد هم نمی‌تواند مسئله را درست حل کند.

چرا به الگوریتم نیاز داریم؟

شاید بپرسید: «چرا مستقیم کد ننویسم؟» این یکی از بزرگترین اشتباهات تازه‌کارهاست. نوشتن کد بدون الگوریتم مثل ساختن خانه بدون نقشه است؛ ممکن است دیوار‌ها بایستند، اما اتاق‌ها به هم نمی‌خورند.

دلایل اصلی استفاده از الگوریتم:

۱. شفاف شدن ذهن: وقتی الگوریتم را می‌نویسید، در واقع مسئله را برای خودتان حل می‌کنید. دیگر با کد درگیر نیستید، با منطق درگیرید. ۲. کاهش خطا: یک الگوریتم روی کاغذ راحت‌تر بررسی و اصلاح می‌شود تا صد خط کد ⁦C++⁩. ۳. استقلال از زبان: الگوریتم به ⁦C++⁩، پایتون یا جاوا وابسته نیست. وقتی الگوریتم را داشته باشید، آن را به هر زبانی می‌توانید پیاده کنید. ۴. ارتباط با دیگران: وقتی با هم‌تیمی‌تان در مورد راه‌حل صحبت می‌کنید، در واقع دارید الگوریتم را بحث می‌کنید، نه کد را. ۵. پیدا کردن خطاهای منطقی زودتر: اگر در الگوریتم باگ باشد، در مرحله طراحی پیدا می‌شود نه در مرحله تست، که هزینه بسیار کمتری دارد.

قاعده طلایی: هرچه زودتر الگوریتم را روی کاغذ بیاورید، دیرتر در کد گیر می‌کنید.

نماد‌های استاندارد فلوچارت

برای نمایش بصری الگوریتم از فلوچارت (Flowchart) استفاده می‌کنیم. فلوچارت از نماد‌های استانداردی تشکیل شده که هر کدام معنای خاصی دارند. این نماد‌ها بر اساس استاندارد بین‌المللی فلوچارت (ISO 5807:1985 که اکنون منسوخ شده ولی همچنان مرجع قرارداد صنعتی روزآمد است) تعریف شده‌اند و در سراسر جهان یکسان هستند.

نمادشکلمعنامثال
● بیضی (Oval)شروع/پایاننقطه آغاز یا پایان برنامهStart، End
▮ مستطیل (Rectangle)پردازشیک عمل محاسباتی یا انتسابx ← -b/a، sum ← sum + i
◆ لوزی (Diamond)تصمیمیک پرسش بله/خیرa ≠ 0؟، i <= n؟
▰ متوازی‌الاضلاع (Parallelogram)ورودی/خروجیدریافت داده از کاربر یا چاپ نتیجهدریافت a, b، چاپ x
↓ فلش (Arrow)جریانجهت اجرای گام‌هااز یک گام به گام بعد
○ دایرهاتصالپیوند بین قسمت‌های مختلف فلوچارتبرای فلوچارت‌های طولانی

در فلوچارت استاندارد، ورودی و خروجی هر دو در متوازی‌الاضلاع قرار می‌گیرند. برخی کتاب‌ها برای خروجی از نماد برگه (Document) استفاده می‌کنند، اما در این دوره برای سادگی، برای هر دو از متوازی‌الاضلاع استفاده می‌کنیم.

چرا نماد‌ها مهم‌اند؟ چون فلوچارت یک زبان بین‌المللی است؛ وقتی شما فلوچارتی با نماد‌های درست می‌کشید، هر برنامه‌نویسی در جهان می‌تواند آن را بخواند، حتی اگر زبانش با شما فرق کند.

کد بدون تفکر الگوریتمی در برابر کد با تفکر الگوریتمی

فرض کنید می‌خواهیم برنامه‌ای بنویسیم که سه عدد بگیرد و بزرگترین را چاپ کند. برنامه‌نویس تازه‌کار مستقیم کد می‌زند و وسط کار گیر می‌کند؛ برنامه‌نویس حرفه‌ای اول الگوریتم را می‌نویسد.

در سمت چپ (نادرست)، بدون طراحی قبلی شروع به نوشتن می‌کنیم و وسط کار می‌فهمیم که فراموش کرده‌ایم مقدار اولیه بدهیم یا منطق اشتباه است. در سمت راست (درست)، اول الگوریتم روی کاغذ می‌آید و سپس کد به‌سادگی از آن پیاده‌سازی می‌شود.

قاعده: الگوریتم ساده‌ترین قدم است که اگر درست انجام شود، کد خودش می‌آید.

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

چگونه فلوچارت را بخوانیم؟

خواندن فلوچارت مثل خواندن یک نقشه است. این مراحل را دنبال کنید:

۱. از بیضی «شروع» پیدا کن. همیشه یک فلوچارت با یک بیضی Start آغاز می‌شود. ۲. فلش‌ها را دنبال کن. فلش‌ها به شما می‌گویند کدام گام بعد از کدام می‌آید. هیچ‌گاه خلاف جهت فلش نرو. ۳. وقتی به لوزی رسیدی، دو مسیر داری. هر لوزی یک پرسش است که پاسخ «بله» یا «خیر» دارد. روی هر فلش خروجی از لوزی باید برچسب بله/خیر نوشته شده باشد. ۴. در مستطیل، محاسبه انجام می‌شود. هر مستطیل یک انتساب یا عملیات است؛ متغیر سمت چپ مقدار جدید می‌گیرد. ۵. متوازی‌الاضلاع برای تعامل با کاربر است. یا چیزی از کاربر می‌گیریم یا چیزی به او نمایش می‌دهیم. ۶. در بیضی «پایان» متوقف شو. هر مسیر معتبر باید به یک بیضی End برسد.

یک فلوچارت خوب نباید هیچ فلش بدون مقصدی داشته باشد و هیچ مستطیل/لوزی نباید معلق بماند. هر عنصر باید در زنجیره اجرا باشد.

تمرین ذهنی: هر بار که فلوچارت می‌بینید، آن را قدم‌به‌قدم با مقادیر واقعی در ذهن اجرا کنید. این کار را ردیابی (Tracing) می‌نامند و یکی از مهم‌ترین مهارت‌های برنامه‌نویسی است.

مسئله اول: جابه‌جایی دو مقدار (Swap)

این یکی از کلاسیک‌ترین مسئله‌های اولیه است. فرض کنید دو متغیر a و b داریم و می‌خواهیم مقادیرشان را عوض کنیم؛ یعنی اگر a = 7 و b = 5 بود، بعد از اجرا a = 5 و b = 7 شود.

اشتباه رایج تازه‌کار‌ها:

main.cppcpp

این کار اشتباه است! چرا؟ چون در خط اول مقدار a از بین می‌رود و به مقدار b تبدیل می‌شود. وقتی در خط دوم b = a را اجرا می‌کنیم، در واقع داریم مقدار جدید a (که همان b قدیم است) را در b می‌ریزیم؛ پس هر دو متغیر مقدار b قدیم را خواهند داشت.

راه‌حل: از یک متغیر کمکی t (مخفف temporary) استفاده می‌کنیم تا مقدار a را موقتاً نگه دارد:

۱. t ← a (مقدار a را در t ذخیره کن) ۲. a ← b (حالا می‌توانیم a را با b بازنویسی کنیم) ۳. b ← t (مقدار t که همان a قدیم بود را در b بریز)

این الگوریتم مثل این است که می‌خواهیم محتویات دو لیوان آب را عوض کنیم؛ به یک لیوان سوم نیاز داریم تا آب یکی را موقتاً بریزیم.

فلوچارت: جابه‌جایی دو مقدار

flow.svg

پیاده‌سازی: جابه‌جایی دو مقدار

این کد معادل دقیق فلوچارت بالا است. به ترتیب سه انتساب دقت کنید: t = a، a = b، b = t. اگر این ترتیب به هم بریزد، جابه‌جایی درست انجام نمی‌شود.

برنامه کامل جابه‌جایی دو عدد با متغیر کمکی tcpp
خروجی برنامه
do adad vared konid: 7 5
baad az jabejaei: a = 5, b = 7
در حال باز کردن ویرایشگر…

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

می‌خواهیم بزرگترین عدد بین a، b و c را پیدا کنیم. دو روش کلی وجود دارد:

روش اول: مقایسه‌های تودرتو (Nested If)

اگر a > b:

  • اگر a > c: بزرگترین a است.
  • وگرنه: بزرگترین c است. وگرنه (یعنی b >= a):
  • اگر b > c: بزرگترین b است.
  • وگرنه: بزرگترین c است.

این روش درست کار می‌کند اما برای تعداد زیاد متغیر‌ها طولانی می‌شود.

روش دوم: متغیر کمکی max (روش حرفه‌ای)

۱. فرض کن max = a (اولین عدد را به‌عنوان بزرگترین در نظر بگیر). ۲. اگر b > max، آن‌گاه max = b کن. ۳. اگر c > max، آن‌گاه max = c کن. ۴. max را چاپ کن.

مزیت روش دوم: برای ۴، ۵ یا ۱۰۰ عدد هم قابل تعمیم است؛ فقط کافی است در یک حلقه، تک‌تک اعداد را با max مقایسه کنیم. این همان الگویی است که در درس‌های بعدی برای یافتن max بین n عدد از آن استفاده خواهیم کرد.

فلوچارت: یافتن بزرگترین بین سه عدد (روش متغیر max)

flow.svg

پیاده‌سازی: یافتن بزرگترین بین سه عدد

این کد معادل فلوچارت بالا است. max را با مقدار a مقداردهی اولیه می‌کنیم، نه با صفر. اگر max = 0 می‌گذاشتیم و همه اعداد منفی بودند، خروجی صفر می‌شد که غلط است. این یکی از تله‌های کلاسیک است که در نسخه اولیه جزوه هم دیده می‌شد.

الگوی «اولین عدد به‌عنوان مقدار اولیه max» — الگویی که در کل دوره استفاده می‌شودcpp
خروجی برنامه
se adad vared konid: 4 9 2
bigitarin = 9
در حال باز کردن ویرایشگر…

مسئله سوم: حل معادله درجه یک a·x + b = 0

معادله درجه یک به فرم کلی a*x + b = 0 (که در جزوه به‌صورت an + b = 0 نوشته شده) یکی از ساده‌ترین معادلات ریاضی است. حل تحلیلی آن ساده است:

اگر a ≠ 0: جواب یکتاست و برابر x = -b / a.

اگر a = 0:

  • اگر b = 0: معادله به 0 = 0 تبدیل می‌شود، یعنی هر عددی جواب است (بی‌نهایت جواب).
  • اگر b ≠ 0: معادله به b = 0 (مثلاً 5 = 0) تبدیل می‌شود، یعنی هیچ جوابی ندارد.

این مسئله فقط ریاضی نیست؛ یک الگوی مهم برنامه‌نویسی است: قبل از تقسیم، باید از صفر نبودن مخرج مطمئن شویم. اگر در ⁦C++⁩ بر صفر تقسیم کنیم، برنامه با خطای زمان اجرا (Runtime Error) متوقف می‌شود.

پس الگوریتم کامل این است:

۱. a و b را از ورودی بگیر. ۲. اگر a ≠ 0:

  • x = -b / a را محاسبه کن.
  • x را چاپ کن.
  1. وگرنه (یعنی a = 0):
    • اگر b = 0: پیام «بی‌نهایت جواب» چاپ کن.
    • وگرنه: پیام «بدون جواب» چاپ کن.

نکته: در نسخه ساده‌شده جزوه، فقط حالت «بی‌نهایت جواب» برای a = 0 در نظر گرفته شده بود. ما در اینجا نسخه کامل‌تری را پیاده می‌کنیم.

فلوچارت: حل معادله درجه یک (با کنترل خطای تقسیم بر صفر)

flow.svg

پیاده‌سازی: حل معادله درجه یک

در این کد از نوع double برای ضرایب و ریشه استفاده می‌کنیم تا تقسیم اعشاری درست انجام شود. اگر از int استفاده می‌کردیم، تقسیم -b / a تقسیم صحیح می‌شد و قسمت اعشاری حذف می‌گشت. این نکته را در درس متغیر‌ها و انواع داده با جزئیات خواهیم دید.

کنترل کامل سه حالت: a ≠ 0، a = 0 و b = 0، a = 0 و b ≠ 0cpp
خروجی برنامه
zarib a va b ra vared konid: 2 -6
rishe = 3

---
zarib a va b ra vared konid: 0 5
moadele javab nadarad

---
zarib a va b ra vared konid: 0 0
bi-nahayat javab (har x javab ast)
در حال باز کردن ویرایشگر…

ردیابی فلوچارت با مقادیر واقعی

برای اطمینان از درست کار کردن، فلوچارت حل معادله را با دو ورودی مختلف ردیابی (Trace) می‌کنیم.

حالت ۱: ورودی a = 2, b = -6

گامشکلعملیاتمقدار
۱● شروعآغاز-
۲▰ ورودیدریافت a و ba=2, b=-6
۳◆ تصمیمa ≠ 0؟بله
۴▮ پردازشx = -b/a = -(-6)/2x = 3
۵▱ خروجیچاپ x«3»
۶◎ پایانپایان-

حالت ۲: ورودی a = 0, b = 0

گامشکلعملیاتمقدار
۱● شروعآغاز-
۲▰ ورودیدریافت a و ba=0, b=0
۳◆ تصمیم اولa ≠ 0؟خیر
۴◆ تصمیم دومb = 0؟بله
۵▱ خروجیچاپ پیام«بی‌نهایت جواب»
۶◎ پایانپایان-

ردیابی یکی از مهم‌ترین مهارت‌های شماست. هر بار کدی نوشتید، با چند ورودی نمونه آن را در ذهن یا روی کاغذ اجرا کنید.

بهترین شیوه‌ها برای ترسیم فلوچارت

برای کشیدن فلوچارت تمیز و خوانا، این قواعد را رعایت کنید:

  • از بالا به پایین، از چپ به راست بنویسید. این جهت طبیعی خواندن است.
  • هر گام فقط یک کار انجام دهد. اگر یک مستطیل چند کار می‌کند، آن را بشکنید.
  • لوزی فقط پرسش بله/خیر باشد. نه محاسبه، نه چاپ.
  • روی فلش‌های خروجی از لوزی، برچسب «بله» و «خیر» بزنید. بدون این برچسب‌ها، فلوچارت مبهم می‌شود.
  • همه مسیر‌ها به یک بیضی پایان برسند. هیچ فلشی نباید معلق بماند.
  • برای حلقه، فلش بازگشت را واضح بکشید (معمولاً از پایین به بالا، با علامت ↻ یا کلمه «بازگشت»).
  • نام متغیر‌ها را یک‌دست بنویسید (همیشه i یا همیشه i، نه I و i).
  • اگر فلوچارت خیلی طولانی شد، آن را با دایره اتصال به چند بخش بشکنید.

نکته عملی: برای کشیدن فلوچارت از ابزارهایی مثل draw.io، Lucidchart یا حتی pencil و کاغذ استفاده کنید. برای این دوره، فلوچارت‌ها به‌صورت متن و با نماد‌های استاندارد ●▰▮◆▱◎ نمایش داده می‌شوند تا یادگیری‌شان آسان باشد.

اشتباهات رایج در فلوچارت

این خطاها اغلب در فلوچارت تازه‌کار‌ها دیده می‌شود:

۱. عدم تعیین بله/خیر روی لوزی. اگر لوزی a > b؟ است، باید مشخص کنید کدام فلش «بله» است و کدام «خیر».

۲. چند کار در یک مستطیل. مثل a, b ← b, a (هم‌زمان جابه‌جایی). این در الگوریتم به‌درستی تعریف نشده؛ به‌جای آن از سه مستطیل جداگانه استفاده کنید.

۳. استفاده از مستطیل به جای متوازی‌الاضلاع برای ورودی/خروجی. این تفاوت ظاهری به نظر بی‌اهمیت می‌آید، اما در اسناد رسمی مهم است.

۴. فراموش کردن مقداردهی اولیه. در فلوچارت فاکتوریل، اگر P ← 1 را فراموش کنید، در کد مقدار P نامشخص خواهد بود.

۵. فراموش کردن گام افزایش شمارنده در حلقه. اگر در حلقه i ← i + 1 را ننویسید، حلقه بی‌نهایت ایجاد می‌شود.

۶. عدم رسید به پایان. هر مسیری که از شروع شروع می‌شود باید به یک پایان برسد. اگر مسیری «در هوا» تمام می‌شود، الگوریتم شما ناقص است.

۷. به‌هم ریختن اولویت عملگر‌ها در محاسبات. مثلاً P ← P*(L+W) در نسخه اصلی جزوه اشتباه بود؛ فرمول صحیح P ← 2*(L+W) است. همیشه از پرانتز استفاده کنید تا اولویت روشن باشد.

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

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

تمرین‌ها

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

فلوچارت و کد ⁦C++⁩ برای یافتن کوچکترین عدد بین سه عدد `a`, `b`, `c` بنویسید.

نمایش راهنما
الگوریتم مثل max است؛ فقط متغیر را `min` بنامید و شرط را به `<` تغییر دهید. مقدار اولیه `min = a` را فراموش نکنید.
02
تمرین•حل کامل دارد

فلوچارت و کد ⁦C++⁩ برای جابه‌جایی دو عدد **بدون** استفاده از متغیر کمکی بنویسید (فقط با عملگر‌های + و -).

نمایش راهنما
از این سه گام استفاده کنید: a = a + b; b = a - b; a = a - b. ابتدا روی کاغذ با a=3, b=5 امتحان کنید.
03
تمرین•حل کامل دارد

فلوچارت و کد ⁦C++⁩ برای حل معادله درجه یک به فرم `a*x + b = 0` بنویسید، با تمام حالات (a≠0، a=0 و b=0، a=0 و b≠0).

نمایش راهنما
از ساختار if-else تو در تو استفاده کنید. برای نوع داده از double استفاده کنید تا تقسیم اعشاری درست باشد.
04
تمرین•حل کامل دارد

فلوچارت و کد ⁦C++⁩ برای یافتن **دومین عدد بزرگ** بین سه عدد بنویسید (مثلاً برای ۴, ۹, ۲ پاسخ ۴ است).

نمایش راهنما
اول max را پیدا کنید، سپس در میان اعدادی که کوچک‌تر از max هستند، بزرگترین را بگردید. یا روش ساده‌تر: سه مقایسه انجام دهید و نتایج را مرتب کنید.
// نکات-کلیدی۶
  • 01الگوریتم مجموعه‌ای محدود، مشخص و ترتیبی از گام‌ها برای حل مسئله است؛ قبل از کدنویسی باید طراحی شود.
  • 02فلوچارت زبان بصری بین‌المللی برای نمایش الگوریتم است؛ نماد‌های آن (بیضی، مستطیل، لوزی، متوازی‌الاضلاع، فلش) استاندارد هستند.
  • 03در لوزی تصمیم، باید هر دو فلش خروجی با «بله» و «خیر» برچسب‌گذاری شوند تا مسیر اجرا روشن باشد.
  • 04برای جابه‌جایی دو مقدار، یک متغیر کمکی لازم است؛ انتساب مستقیم `a=b; b=a;` مقدار اولیه را از بین می‌برد.
  • 05برای یافتن max/min بین چند عدد، اولین عدد را به‌عنوان مقدار اولیه قرار دهید، نه صفر را (تا اعداد منفی هم پوشش داده شوند).
  • 06قبل از هر تقسیمی، باید از صفر نبودن مخرج مطمئن شوید؛ تقسیم بر صفر باعث خطای زمان اجرا می‌شود.
گام بعدی پیشنهادی

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

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

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

شروع درس

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

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