در این جلسه از سری آموزش های برنامه نویسی ++C در مورد دستورات حلقه و تکرار در ++C صحبت خواهیم کرد. تکرار، اجرای پی در پی یک دستور یا بلوکی از دستورالعملها در یک برنامه است. با استفاده از تکرار میتوانیم کنترل برنامه را مجبور کنیم تا به خطوط قبلی برگردد و آنها را دوباره اجرا نماید. C++ دارای سه دستور تکرار است: دستور while، دستور do_while و دستور for. دستورهای تکرار به علت طبیعت چرخهمانندشان، حلقه نیز نامیده میشوند.
دستور while در ++C
در ابتدای جلسه دستورات حلقه و تکرار در ++C ، نحو یا syntax دستور while بیان میشود:
while (condition) statement;
به جای condition، یک شرط قرار میگیرد و به جای statement دستوری که باید تکرار شود قرار میگیرد. اگر مقدار شرط، صفر (یعنی نادرست) باشد، statement نادیده گرفته میشود و برنامه به اولین دستور بعد از while پرش میکند. اگر مقدار شرط ناصفر (یعنی درست) باشد، statement اجرا شده و دوباره مقدار شرط بررسی میشود. این تکرار آن قدر ادامه مییابد تا این که مقدار شرط صفر شود.
مثال: محاسبۀ حاصل جمع اعداد صحیح متوالی با حلقۀ while : این برنامه مقدار ۱ + ۲ + ۳ + … + n را برای عدد ورودی n محاسبه میکند:
#include <iostream> using namespace std; int main() { int n, i=1; cout << "Enter a positive integer: "; cin >> n; long sum=0; while (i <= n) sum += i++; cout << "The sum of the first " << n << " integers is " << sum; return 0; }
این دستور با استفاده از حلقه while تا زمانی که شرط توقف برآورده نشده ادامه پیدا میکند. در مثال بالا با اجرای برنامه متوجه خواهید شد که با ورودی عدد ۱۰ جمع اعداد ۱ تا ۱۰ یعنی ۵۵ را برای ما محاسبه میکند.
خاتمه دادن به یک حلقه در ++C
قبلا دیدیم که چگونه دستور break برای کنترل دستورالعمل switch استفاده میشود (جلسه چهارم : دستورات شرطی). از دستور break برای پایان دادن به حلقهها نیز میتوان استفاده کرد. یکی از مزیتهای دستور break این است که فوراً حلقه را خاتمه میدهد بدون این که مابقی دستورهای درون حلقه اجرا شوند.
مثال:
#include <iostream> using namespace std; int main() { int n, i=1; cout << "Enter a positive integer: "; cin >> n; long sum=0; while (true) { if (i > n) break; sum += i++; } cout << "The sum of the first " << n << " integers is " << sum; return 0; }
مثال اعداد فیبوناچی در مقاله دستورات حلقه و تکرار در ++C
در ادامه دستورات حلقه و تکرار در ++C مثال اعداد فیبوناچی را داریم. اعداد فیبوناچی …, F0, F1, F2, F3 به شکل بازگشتی توسط معادلههای زیر تعریف میشوند:
F0 = 0 , F1 = 1 , Fn = Fn-1 + Fn-2
مثلا برای n=2 داریم:
F2 = F2-1 + F2-2 = F1 + F0 = 0 + 1 = 1
یا برای n=3 داریم:
F3 = F3-1 + F3-2 = F2 + F1 = 1 + 1 = 2
و برای n=4 داریم:
F4 = F4-1 + F4-2 = F3 + F2 = 2 + 1 = 3
برنامۀ زیر، همۀ اعداد فیبوناچی را تا یک محدوده مشخص که از ورودی دریافت میشود، محاسبه و چاپ میکند:
#include <iostream> using namespace std; int main() { long bound; cout << "Enter a positive integer: "; cin >> bound; cout << "Fibonacci numbers < " << bound << ":\n0, 1"; long f0=0, f1=1; while (true) { long f2 = f0 + f1; if (f2 > bound) break; cout << ", " << f2; f0 = f1; f1 = f2; } }
مثال استفاده از تابع (exit(0
تابع (exit(0 روش دیگری برای خاتمه دادن به یک حلقه است. هرچند که این تابع بلافاصله اجرای کل برنامه را پایان میدهد:
#include <iostream> using namespace std; int main() { long bound; cout << "Enter a positive integer: "; cin >> bound; cout << "Fibonacci numbers < " << bound << ":\n0, 1"; long f0=0, f1=1; while (true) { long f2 = f0 + f1; if (f2 > bound) exit(0); cout << ", " << f2; f0 = f1; f1 = f2; } }
برنامهنویسان ترجیح میدهند از break برای خاتمه دادن به حلقههای نامتناهی استفاده کنند زیرا قابلیت انعطاف بیشتری دارد.
متوقف کردن یک حلقۀ نامتناهی در ++C
با فشردن کلیدهای Ctrl+C سیستم عامل یک برنامه را به اجبار خاتمه میدهد. کلید Ctrl را پایین نگه داشته و کلید C روی صفحهکلید خود را فشار دهید تا برنامۀ فعلی خاتمه پیدا کند.
دستور do while در ++C
ساختار do..while روش دیگری برای ساختن دستورات حلقه و تکرار در ++C است نحو آن به صورت زیر است:
do statement while (condition);
به جای condition یک شرط قرار میگیرد و به جای statement دستور یا بلوکی قرار میگیرد که قرار است تکرار شود. این دستور ابتدا statement را اجرا میکند و سپس شرط condition را بررسی میکند. اگر شرط درست بود حلقه دوباره تکرار میشود وگرنه حلقه پایان مییابد.
دستور do..while مانند دستور while است. با این فرق که شرط کنترل حلقه به جای این که در ابتدای حلقه ارزیابی گردد، در انتهای حلقه ارزیابی میشود.
یعنی هر متغیر کنترلی به جای این که قبل از شروع حلقه تنظیم شود، میتواند درون آن تنظیم گردد. نتیجۀ دیگر این است که حلقۀ do..while همیشه بدون توجه به مقدار شرط کنترل، لااقل یک بار اجرا میشود اما حلقۀ while میتواند اصلا اجرا نشود.
مثال: محاسبۀ حاصل جمع اعداد صحیح متوالی با حلقۀ do..while
#include <iostream> using namespace std; int main() { int n, i=0; cout << "Enter a positive integer: "; cin >> n; long sum=0; do sum += i++; while (i <= n); cout << "The sum of the first " << n << " integers is " << sum; }
مثال: اعداد فاکتوریل
اعداد فاکتوریل ۰! و ۱! و ۲! و ۳! و … با استفاده از رابطههای بازگشتی زیر تعریف میشوند:
۰! = 1 , n! = n(n-1)!
برای مثال، به ازای n = 1 در معادلۀ دوم داریم:
۱! = 1((۱-۱)!) = 1(۰!) = 1(۱) = 1
همچنین برای n = 2 داریم:
۲! = 2((۲-۱)!) = 2(۱!) = 2(۱) = 2
و به ازای n = 3 داریم:
۳! = 3((۳-۱)!) = 3(۲!) = 3(۲) = 6
برنامۀ زیر همۀ اعداد فاکتوریل را که از عدد داده شده کوچکترند، چاپ میکند:
#include <iostream> using namespace std; int main() { long bound; cout << "Enter a positive integer: "; cin >> bound; cout << "Factorial numbers < " << bound << ":\n1"; long f=1, i=1; do { cout << ", " << f; f *= ++i; } while (i < bound); }
دستور for در ++C
نحو یا syntax دستورالعمل for در دستورات حلقه و تکرار در ++C به صورت زیر است:
for (initialization; condition; update) statement;
سه قسمت داخل پرانتز، حلقه را کنترل میکنند.
- عبارت initialization برای اعلان یا مقداردهی اولیه به متغیر کنترل حلقه استفاده میشود.این عبارت اولین عبارتی است که ارزیابی میشود پیش از این که نوبت به تکرارها برسد.
- عبارت condition برای تعیین این که آیا حلقه باید تکرار شود یا خیر به کار میرود. یعنی این عبارت، شرط کنترل حلقه است. اگر این شرط درست باشد دستور statement اجرا میشود.
- عبارت update برای پیشبردن متغیر کنترل حلقه به کار میرود. این عبارت پس از اجرای statement ارزیابی میگردد.
بنابراین زنجیرۀ وقایعی که تکرار را ایجاد میکنند عبارتند از:
- ارزیابی عبارت initialization
- بررسی شرط condition . اگر نادرست باشد، حلقه خاتمه مییابد.
- اجرای statement
- ارزیابی عبارت update
- تکرار گامهای ۲ تا ۴
عبارتهای initialization و condition و update عبارتهای اختیاری هستند. یعنی میتوانیم آنها را در حلقه ذکر نکنیم.
مثال: استفاده از حلقه for برای محاسبه مجموع اعداد صحیح متوالی
#include <iostream> using namespace std; int main() { int n; cout << "Enter a positive integer: "; cin >> n; long sum=0; for (int i=1; i <= n; i++) sum += i; cout << "The sum of the first " << n << " integers is " << sum; }
در ++C استاندارد وقتی یک متغیر کنترل درون یک حلقۀ for اعلان میشود (مانند i در مثال بالا) حوزه آن متغیر به همان حلقه for محدود میگردد. یعنی آن متغیر نمیتواند بیرون از آن حلقه استفاده شود. نتیجه دیگر این است که میتوان از نام مشابهی در خارج از حلقه for برای یک متغیر دیگر استفاده نمود.
مثال: یک حلقه for نزولی – برنامه زیر ده عدد صحیح مثبت را به ترتیب نزولی چاپ میکند:
#include <iostream> using namespace std; int main() { for (int i=10; i > 0; i--) cout << " " << i; }
مثال: بیشتر از یک متغیر کنترل در حلقه for – حلقۀ for در برنامه زیر دو متغیر کنترل دارد:
#include <iostream> using namespace std; int main() { for (int m=95, n=11; m%n > 0; m -= 3, n++) cout << m << "%" << n << " = " << m%n << endl; }
مثال: حلقههای for تودرتو – برنامۀ زیر یک جدول ضرب چاپ میکند:
#include <iomanip> #include <iostream> using namespace std; int main() { for (int x=1; x <= 10; x++) { for (int y=1; y <= 10; y++) cout << setw(4) << x*y; cout << endl; } }
دستور break در ++C
دستور break یک دستور آشناست. قبلاً از آن برای خاتمه دادن به دستور switch و همچنین حلقههای while و do..while استفاده کردهایم. از این دستور برای خاتمه دادن به حلقۀ for نیز میتوانیم استفاده کنیم. دستور break در هر جایی درون حلقه میتواند جا بگیرد و در همان جا حلقه را خاتمه دهد.
وقتی دستور break درون حلقههای تودرتو استفاده شود، فقط روی حلقهای که مستقیماً درون آن قرار گرفته تاثیر میگذارد. حلقههای بیرونی بدون هیچ تغییری ادامه مییابند.
دستور continue در ++C
دستور break بقیۀ دستورهای درون بلوک حلقه را نادیده گرفته و به اولین دستور بیرون حلقه پرش میکند. دستور continue نیز شبیه همین است اما به جای این که حلقه را خاتمه دهد، اجرا را به تکرار بعدی حلقه منتقل میکند. این دستور، ادامه چرخه فعلی را لغو کرده و اجرای دور بعدی حلقه را آغاز میکند.
مثال: استفاده از دستورهای break و continue – این برنامه کوچک، دستورهای break و continue را شرح میدهد:
int main() { int n = 1; char c; for( ; ;n++ ) { cout << "\nLoop no: " << n << endl; cout << "Continue? <y|n> "; cin >> c; if (c = = 'y') continue; break; } cout << "\nTotal of loops: " << n; }
دستور goto در ++C
دستور goto نوع دیگری از دستورات حلقه و تکرار در ++C است. مقصد این پرش توسط یک برچسب معین میشود. برچسب شناسهای است که جلوی آن علامت کولن ( : ) میآید و جلوی یک دستور دیگر قرار میگیرد. یک مزیت دستور goto این است که با استفاده از آن میتوان از همۀ حلقههای تودرتو خارج شد و به مکان دلخواهی در برنامه پرش نمود.
مثال: استفاده از دستور goto برای خارج شدن از حلقههای تودرتو
#include <iostream> using namespace std; int main() { const int N=5; for (int i=0; i<N; i++) { for (int j=0; j<N; j++) { for (int k=0; k<N; k++) if (i+j+k>N) goto esc; else cout << i+j+k << " "; cout << "* "; } esc: cout << "." << endl; } }
تولید اعداد تصادفی در ++C
یکی از کاربردهای بسیار مهم کامپیوترها، «شبیهسازی» سیستمهای دنیای واقعی است. تحقیقات و توسعههای بسیار پیشرفته به این راهکار خیلی وابسته است. به وسیلۀ شبیهسازی میتوانیم رفتار سیستمهای مختلف را مطالعه کنیم بدون این که لازم باشد واقعا آنها را پیادهسازی نماییم. در شبیهسازی نیاز است «اعداد تصادفی» توسط کامپیوترها تولید شود تا نادانستههای دنیای واقعی مدلسازی شود.
کامپیوترها «ثابتکار» هستند یعنی با دادن دادههای مشابه به کامپیوترهای مشابه، همیشه خروجی یکسان تولید میشود. با وجود این می توان اعدادی تولید کرد که به ظاهر تصادفی هستند؛ اعدادی که به طور یکنواخت در یک محدودۀ خاص گستردهاند و برای هیچکدام الگوی مشخصی وجود ندارد. چنین اعدادی را «اعداد شبهتصادفی» مینامیم.
مثال: تولید اعداد شبه تصادفی – این برنامه از تابع rand() برای تولید اعداد شبهتصادفی استفاده میکند:
#include <iostream> #include<cstdlib>//defines the rand() and RAND_MAX using namespace std; int main() { // prints pseudo-random numbers: for (int i = 0; i < 8; i++) cout << rand() << endl; cout << "RAND_MAX = " << RAND_MAX << endl; }
در برنامه بالا که از دستورات حلقه و تکرار در ++C استفاده شده است، کامپایلر هشت عدد صحیح unsigned تولید میکند که به طور یکنواخت در فاصلۀ ۰ تا RAND_MAX گسترده شدهاند. AND_MAX در این کامپایلر برابر با ۲,۱۴۷,۴۸۳,۶۴۷ است. هر عدد شبهتصادفی از روی عدد قبلی خود ساخته میشود. اولین عدد شبهتصادفی از روی یک مقدار داخلی که «هسته» گفته میشود ایجاد میگردد.
هر دفعه که برنامه اجرا شود، هسته با یک مقدار پیشفرض بارگذاری میشود. برای حذف این اثر نامطلوب که از تصادفی بودن اعداد میکاهد، میتوانیم با استفاده از تابع ()srand خودمان مقدار هسته را انتخاب کنیم.
#include <iostream> #include<cstdlib>//defines the rand() and RAND_MAX using namespace std; int main() { // prints pseudo-random numbers: unsigned seed; cout << "Enter seed: "; cin >> seed; srand(seed); // initializes the seed for (int i = 0; i < 8; i++) cout << rand() << endl; }
مثال بالا کارگذاری هسته به طور محاورهای است. این برنامه مانند برنامۀ قبلی است بجز این که میتوان هستۀ تولیدکنندۀ اعداد تصادفی را به شکل محاورهای وارد نمود.
سخن آخر
در این مقاله درمورد انواع دستورات حلقه نظیر while، do while، for، goto و دستوراتی نظیر break و continue صحبت کردیم. در درس بعدی با مقاله انواع توابع در ++C در خدمت شما عزیزان خواهیم بود.