ساختار تکرار for (ادامه)

Report
Ali Shakiba – http://shakiba.id.ir
‫مبانی برنامه‌سازی با‬
‫‪C++‬‬
‫علی شکیبا‬
[email protected]
‫فروردین ‪1392‬‬
‫جلسه سوم‬
‫مباحث این جلسه‬
،‫• حلقه‌ها‬
.‫• توابع‬
Ali Shakiba – http://shakiba.id.ir
‫یادآوری‬
Ali Shakiba – http://shakiba.id.ir
‫یادآوری‬
‫• قبل از نوشتن هر برنامه‌ای‪،‬‬
‫– صورت مساله را به درستی درک کنید‪،‬‬
‫– یک روش برای حل آن مساله ارائه کنید‪.‬‬
‫• در هنگام نوشتن برنامه‪،‬‬
‫– درک روشنی از ساختارهای برنامه نویس ی داشته باشید‪،‬‬
‫• مانند حلقه‌ها‪ ،‬شرط‌ها‪ ،‬توابع و مانند این‪،‬‬
‫– از الگوهای برنامه نویس ی صحیح استفاده کنید‪،‬‬
‫– زبان برنامه نویس ی متناسب با مساله خود را انتخاب کنید‪.‬‬
‫•‪‬‬
‫‪5‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫الگوریتم‌ها‬
‫• یک برنامه‪ ،‬برای محاسبه پاسخ یک مساله‪،‬‬
‫– دنباله‌ای از دستورات را اجرا می‌کند‪.‬‬
‫• الگوریتم رویه‌ای است برای تعیین‬
‫– وظایفی که باید برای حل مساله انجام شوند‪،‬‬
‫– ترتیب انجام آن وظایف‪،‬‬
‫• مثال‪ ،‬دستور پخت یک کیک خامه‌ای خوشمزه هجده طبقه!‬
‫• کنترل جریان برنامه‬
‫– تعیین ترتیبی که دستورات برنامه اجرا می‌شوند‪.‬‬
‫‪6‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫شبه‌کد‬
‫• شبه‌کد‬
‫– زبانی مصنوعی و غیر رسمی برای توصیف الگوریتم‌ها است‪،‬‬
‫– شبیه به زبان‌های روزمره است‪،‬‬
‫• نمی‌توانند توسط یک کامپیوتر اجرا شوند‪،‬‬
‫– مهم‌ترین کاربرد آن‪ ،‬امکان فکر کردن درباره ساختار برنامه است‪ ،‬چرا که‪:‬‬
‫• تبدیل آن به کد برنامه نویس ی ساده است‪،‬‬
‫– شبه‌کد می‌تواند تنها شامل دستورات اجرایی باشد‪.‬‬
‫‪7‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫متغیر‬
‫• متغیر‌‬
‫–‬
‫–‬
‫–‬
‫–‬
‫مکانی از حافظه که می‌توان داده(ها) را در آن ذخیره نمود‪،‬‬
‫تمام متغیرها در ‪ C++‬باید دارای نام و نوع داده باشند‪،‬‬
‫نوع داده قبل از نام متغیر می‌آید‪،‬‬
‫;‪int test‬‬
‫انواع داده معمو ‌ل‬
‫;‪double grade‬‬
‫• عدد صحیح (‪،)int‬‬
‫• کاراکتر (‪،)char‬‬
‫• ممیز شناور با دقت مضاعف (‪،)double‬‬
‫;‪char firstChar‬‬
‫– می‌توان چندین متغیر از یک نوع را با یک دستور مشخص نمود‪.‬‬
‫;‪int test1, test2, numberOfPCs‬‬
‫‪8‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
C++ ‫انواع داده‌ها در‬
9
Ali Shakiba – http://shakiba.id.ir
)‫ (ادامه‬C++ ‫انواع داده‌ها در‬
10
Ali Shakiba – http://shakiba.id.ir
‫انتساب (‪( )Assignment‬عملگر =)‬
‫• مقدار دهی اولیه در هنگام تعریف متغیرها‪،‬‬
‫– اگر این کار را انجام ندهید‪ ،‬مقدار اولیه متغیر نامشخص است و می‌تواند هر مقداری‬
‫باشد!‬
‫– عادت خوب برنامه نویس ی‪ ،‬مقداردهی اولیه همه متغیرها در هنگام تعریف است‪.‬‬
‫;‪int myValue = 0‬‬
‫• انتساب در حین اجرا‪،‬‬
‫– مقادیر سمت راست و سمت چپ‬
‫• مقادیر سمت چپ در یک انتساب باید شناسه یک متغیر باشند‪،‬‬
‫• مقادیر سمت راست در یک انتساب می‌توانند هر عبارتی باشند‪،‬‬
‫• مثال‪:‬‬
‫;‪distance = rate * time‬‬
‫"‪: "distance‬مقدار سمت چپ‬
‫"‪: "rate * time‬مقدار سمت راست‬
‫‪11‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫مبان‌برهایی برای عملگر انتساب‬
12
Ali Shakiba – http://shakiba.id.ir
‫ثوابت‬
‫• قالب کلی تعریف ثوابت‬
‫; مقدار = ‪ NAME_OF_VAR‬نوع داده ‪const‬‬
‫•مثال‪:‬‬
‫;‪const int NUMBER_OF_STUDENTS = 24‬‬
‫– در هر کجای برنامه‪ ،‬می‌توان از این ثابت با نوشتن نامش استفاده کرد‪،‬‬
‫– مقدار ثابت در طول برنامه‪ ،‬پس از تعریف؛ غیر قابل تغییر است!‬
‫‪13‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫دقت محاسبات ریاض ی‬
‫• دقت محاسبات ریاض ی‬
‫– یک اصل مهم در برنامه نویس ی است که باید همواره در نظر گرفته شود‪،‬‬
‫• ممکن است محاسبه عبارات آنگونه که شما انتظار دارید‪ ،‬پیش نروند!‬
‫– دقت محاسبات توسط عملگر محاسباتی با بیشترین اولویت مشخص‬
‫می‌شود!‬
‫– عدم دقت به این مورد‪ ،‬متاسفانه یکی از معمول‌ترین خطاها در بین‬
‫برنامه نویسان ‪ C++‬است!‬
‫‪14‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫مثال‌هایی از محاسبات ریاض ی در ‪C++‬‬
‫• مثال‬
‫‪– 17 / 5‬‬
‫• هر دو عملوند صحیح هستند!‬
‫• در نتیجه تقسیم صحیح انجام شده است!‬
‫‪– 17.0 / 5‬‬
‫• یکی از عملوندها‪ ،‬ممیز شناور دارد‪ ،‬بنابراین‬
‫• عملگر تقسیم با ممیز شناور اعمال شده است‪.‬‬
‫;‪– int intVar1 =1, intVar2=2‬‬
‫;‪intVar1 / intVar2‬‬
‫• اعمال تقسیم صحیح‪،‬‬
‫• جواب‪ 0 :‬است!‬
‫‪15‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫تبدیل نوع داده‬
‫• دو نوع!‬
‫– ضمنی‪ ،‬یا خودکار‬
‫• به صورت خودکار انجام می‌شود‪،‬‬
‫‪17 / 5.5‬‬
‫»منجر به تبدیل زیر می‌شود‪:‬‬
‫‪17  17.0‬‬
‫– صریح‬
‫)‪static_cast<double>(intVar‬‬
‫نیز قابل انجام است‪ ،‬اما توصیه می‌کنم به‬
‫یر ‌‬
‫تبدیل صریح با دستور‌ ز ‌‬
‫ق عادت کنید!‬
‫استفاده ‌از دستور‌ فو ‌‬
‫نام متغیر )نوع داده مقصد(‬
‫‪16‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫عملگرهای اختصاری‌‬
‫• عملگرهای افزایش ی و کاهش ی‬
‫– عملگر ‪،++‬‬
‫• ‪ z++‬معادل با ‪ z = z + 1‬است!‬
‫– عملگر ‪،--‬‬
‫• ‪ z--‬معادل با ‪ z = z – 1‬است!‬
‫مقدار را ارزیابی کرده ‌و‬
‫‌‬
‫یکدیگر متفاوت هستند! این د ‌و‬
‫‌‬
‫‪ Z++‬و ‪ ++Z‬با‬
‫توجیه کنید!‬
‫‪ ++Z * 8‬و ‪Z++ * 8‬‬
‫‪17‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫ورودی و خروجی کنسو ‌ل‬
‫• اشیا مربوط به ‪ I/O‬عبارتند از ‪cin, cout, cerr‬‬
‫• که در کتابخانه >‪ <iostream‬در فضای نام ‪ std‬تعریف شده اند‪،‬‬
‫• برای استفاده از آن‌ها‪ ،‬می‌توان از رویه ذیل استفاده نمود‪:‬‬
‫>‪#include <iostream‬‬
‫;‪using namespace std‬‬
‫– این دستورات به ‪ C++‬می‌گویند که تعاریف مربوط به ‪ cout ،cin‬و ‪ cerr‬را از کجا‬
‫به دست بیاورد!‬
‫‪18‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫قالب‌دار کردن اعداد‬
‫• دستورات زیر‪ ،‬نمایش معمول (با دو رقم اعشار) از اعداد ممیز شناور را‬
‫موجب می‌شوند‪،‬‬
‫;)‪cout.setf(ios::fixed‬‬
‫;)‪cout.setf(ios::showpoint‬‬
‫;)‪cout.precision(2‬‬
‫• این دستورات‪ ،‬همه ‪ cout‬های پس از خود را تحت تاثیر قرار می‌دهند‪.‬‬
‫– دقیقا دو رقم اعشار پس از ممیز داریم!‬
‫– مثال‪:‬‬
‫;‪cout << "The price is $" << price << endl‬‬
‫• نتیجه به صورت ذیل است‪:‬‬
‫‪The price is $78.50‬‬
‫• دقت نمایش را می‌توان در هنگام اجرا نیز تغییر داد‪.‬‬
‫‪19‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫خروجی خطا‬
‫• کافی است که خروجی را به ‪ cerr‬ارسال کنیم‪،‬‬
‫– ‪cerr‬دقیقا مانند ‪ cout‬کار می‌کند‪،‬‬
‫– مکانیزمی برای تفاوت قائل شدن بین خروجی استاندارد و خروجی خطا‬
‫فراهم می‌کند‪( ،‬سعی کنیم به استفاده صحیح از این اشیا عادت کنیم‬
‫‪)‬‬
‫‪20‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫ورودی با استفاده از ‪cin‬‬
‫• از ش ی ‪ cin‬برای ورودی و از ش ی ‪ cout‬برای خروجی استفاده می‌شود‪،‬‬
‫• تفاوت‌ها‬
‫– ">>" عملگر استخراج از جریان‬
‫• جهت آن از جریان به سمت متغیر(ها) است‪.‬‬
‫– از ش ی ‪ "cin‬به جای ش ی ”‪ "cout‬استفاده می‌شود‪،‬‬
‫– برای ‪ ،cin‬از هیچ لفظی نمی‌توان استفاده کرد‪.‬‬
‫• باید ورودی‌ای برای یک متغیر فراهم کند!‬
‫;‪cin >> num‬‬
‫– در کنسول‪ ،‬منتظر دریافت یک ورودی می‌ماند‪،‬‬
‫– مقدار وارد شده در کنسول را به متغیر منسوب می‌کند‪.‬‬
‫‪21‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫توضیحات‬
‫• یکی از مهمترین اهداف توضیحات‪ ،‬خواناتر کردن برنامه‌ها و ساده‌تر کردن فرآیند تغییر‬
‫آن‌ها است‪.‬‬
‫• دو شیوه کلی‪:‬‬
‫از محل قرار گیری دو اسلش تا پایان خط جاری به عنوان توضیح فرض می‌شود‪– // .‬‬
‫هر آنچه که بین این دو عالمت قرار بگیرد‪– /*،‬‬
‫‪*/‬حتی کاراکتر خط جدید نیز به عنوان توضیح فرض می شود‪.‬‬
‫– از هر دو روش به صورت معمول استفاده می‌شود‪.‬‬
‫‪22‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫کتابخانه‌ها‬
‫• برای استفاده از کتابخانه‌ها در ‪ ،C++‬از قالب دستوری زیر استفاده‬
‫می‌کنیم‪:‬‬
‫>‪• #include <Library_Name‬‬
‫– به پیش‌پردازنده می‌گوید که کتابخانه مورد نظر را برای استفاده‪ ،‬به‬
‫برنامه الحاق کند‪.‬‬
‫• به صورت خیلی ساده می‌توان گفت که قبل از کامپایل برنامه‪ ،‬کتابخانه مورد‬
‫نظر را به برنامه الحاق می‌کند‪،‬‬
‫• کتابخانه‌های زیادی برای ‪ C++‬وجود دارند‪.‬‬
‫‪23‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫عملگرهای رابطه‌ای‬
‫توضیح‬
‫مثال در ‪C++‬‬
‫عملگر معادل در زبان ‪C++‬‬
‫نماد مرسوم‬
‫عملگرهای رابطه‌ای‬
‫‪X‬بزرگتر از ‪ y‬است‪.‬‬
‫‪x>y‬‬
‫>‬
‫>‬
‫‪X‬از ‪ y‬کمتر است‪.‬‬
‫‪x<y‬‬
‫<‬
‫<‬
‫‪X‬بزرگتر یا مساوی با ‪ y‬است‪.‬‬
‫‪x >= y‬‬
‫=>‬
‫‪‬‬
‫‪X‬کوچکتر یا مساوی با ‪ y‬است‪.‬‬
‫‪x <= y‬‬
‫=<‬
‫‪‬‬
‫عملگرهای برابری‌‬
‫‪X‬با ‪ y‬برابر است‪.‬‬
‫‪x == y‬‬
‫==‬
‫=‬
‫‪X‬با ‪ y‬برابر نیست‪.‬‬
‫‪x != y‬‬
‫=!‬
‫‪‬‬
‫‪24‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫ارزیابی عبارات رابطه‌ای‬
‫• نوع داده ‪bool‬‬
‫– مقدار ‪ true‬یا ‪ false‬را باز می‌گرداند‪،‬‬
‫– ‪ True‬و ‪ ،false‬ثوابت از پیش‌تعریف شده برای نوع داده ‪bool‬‬
‫هستند‪.‬‬
‫‪25‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫اولویت عملگرها‬
‫بیشترین اولویت‬
‫کمترین اولویت‬
‫‪26‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫اولویت عملگرها (ادامه)‬
‫بیشترین اولویت‬
‫کمترین اولویت‬
‫‪27‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫اولویت عملگرها (ادامه)‬
‫بیشترین اولویت‬
‫کمترین اولویت‬
‫‪28‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫اولویت عملگرها (ادامه)‬
‫بیشترین اولویت‬
‫کمترین اولویت‬
‫‪29‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫ساختارهای کنترل جریان برنامه‬
‫• اجرای دنباله‌ای‬
‫– دستورات به ترتیبی که در برنامه آمده اند اجرا می‌شوند‪،‬‬
‫• انتقال کنترل‌‬
‫– دستور بعدی که اجرا می‌شود‪ ،‬الزاما دستور بعدی نیست!‬
‫• سه ساختار کنترل جریان وجود دارد‪:‬‬
‫– ساختار دنباله‌ای‬
‫• به صورت پیش فرض‪ ،‬دستورات برنامه به ترتیبی که در برنامه آمده اند اجرا می‌شوند‪،‬‬
‫– ساختارهای انتخاب‬
‫‪• if, if/else, switch‬‬
‫– ساختارهای تکرار‬
‫‪• while, do/while, for‬‬
‫‪30‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
if ‫ساختار انتخابی‬
،‫ ذیل‬C++ ‫• ترجمه شبه کد به کد‬
If student’s grade is greater than or equal to 60
Print “Passed”
if ( grade >= 60 )
cout << "Passed";
A decision can be made on
any expression.
zero - false
nonzero - true
Example:
3 - 4 is true
31
Ali Shakiba – http://shakiba.id.ir
‫عملگر شرطی سه‌تایی‬
(?:)‫• عملگر شرطی سه‌تایی‬
cout << ( grade >= 60 ? “Passed” : “Failed” );
Condition
32
Ali Shakiba – http://shakiba.id.ir
Value if true
Value if false
switch ‫ساختار انتخاب چندگانه‬
33
Ali Shakiba – http://shakiba.id.ir
‫ساختار تکرار‬
Ali Shakiba – http://shakiba.id.ir
while ‫ساختار تکرار‬
‫• ساختار تکرار‬
.‫ تکرار می‌شود‬،‫– اجرای فرآیند مادامی که شرط صحیح باشد‬
‫– شبه‌کد‬
while there are more items on my shopping list
Purchase next item and cross it off my list
‫ تا زمانی ادامه می‌یابد که شرط حلقه‬while ‫– اجرای بدنه حلقه‬
!‫نادرست شود‬
‫• مثال‬
int product = 2;
while ( product <= 1000 )
product = 2 * product;
35
Ali Shakiba – http://shakiba.id.ir
)‫ (ادامه‬while ‫ساختار تکرار‬
36
Ali Shakiba – http://shakiba.id.ir
‫کنترل تکرار با شمارنده‬
‫• کنترل تکرار با شمارنده‬
‫– اجرای بدنه حلقه تا زمانی ادامه پیدا می‌کند که شمارنده به مقدار‬
،‫مشخص ی برسد‬
‫• تکرار معین‬
،‫– تعداد تکرارها از پیش مشخص است‬
‫• مثال‬
A class of ten students took a quiz. The grades
(integers in the range 0 to 100) for this quiz are
available to you. Determine the class average on
the quiz.
37
Ali Shakiba – http://shakiba.id.ir
)‫کنترل تکرار با شمارنده (ادامه‬
:‫• شبه کد نمونه‬
Set total to zero
Set grade counter to one
While grade counter is less than or equal to ten
Input the next grade
Add the grade into the total
Add one to the grade counter
Set the class average to the total divided by ten
Print the class average
.‫ تبدیل کنید‬C++ ‫ این شبه‌کد را به یک برنامه معتبر‬:‫• تمرین کالس ی‬
38
Ali Shakiba – http://shakiba.id.ir
)‫کنترل تکرار با شمارنده (ادامه‬
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Fig. 2.7: fig02_07.cpp
// Class average program with counter-controlled repetition.
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
// function main begins
int main()
{
int total;
//
int gradeCounter; //
int grade;
//
int average;
//
program execution
sum of grades input by user
number of grade to be entered next
grade value
average of grades
// initialization phase
total = 0;
// initialize total
gradeCounter = 1;
// initialize loop counter
39
Ali Shakiba – http://shakiba.id.ir
)‫کنترل تکرار با شمارنده (ادامه‬
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// processing phase
while ( gradeCounter <= 10 ) {
cout << "Enter grade: ";
cin >> grade;
total = total + grade;
gradeCounter = gradeCounter + 1;
}
// termination phase
average = total / 10;
//
//
//
//
//
loop 10 times
prompt for input
read grade from user
add grade to total
increment counter
// integer division
// display result
cout << "Class average is " << average << endl;
return 0;
// indicate
} // end function main
40
Ali Shakiba – http://shakiba.id.ir
The counter gets incremented each
time the loop executes.
program ended successfully
Eventually, the counter causes the
loop to end.
)‫کنترل تکرار با شمارنده (ادامه‬
Enter
Enter
Enter
Enter
Enter
Enter
Enter
Enter
Enter
Enter
Class
grade: 98
grade: 76
grade: 71
grade: 87
grade: 83
grade: 90
grade: 57
grade: 79
grade: 82
grade: 94
average is 81
41
Ali Shakiba – http://shakiba.id.ir
‫کنترل تکرار با نگهبان‬
‫• حال فرض کنید مساله قبلی را به صورت زیر تغییر دهیم‪:‬‬
‫‪Develop a class-averaging program that will process‬‬
‫‪an arbitrary number of grades each time the program‬‬
‫‪is run‬‬
‫– تعداد دانش آموزان نامشخص است!‬
‫– برنامه چگونه متوجه شود که لیست پایان یافته است؟‬
‫• مقدار نگهبان در این مساله‪،‬‬
‫– مشخص کننده پایان ورود داده‌ها‪،‬‬
‫– هنگامی‌که مقدار نگهبان به ورودی داده شد‪ ،‬حلقه خاتمه پیدا می‌کند‪.‬‬
‫– باید مقدار نگهبان را به گونه‌ای انتخاب نمود که یک ورودی معتبر نباشد‪،‬‬
‫• مثال نمره منفی نداریم‪ ،‬پس مقدار نگهبان ‪ ،-1‬انتخابی مناسب است‪.‬‬
‫‪42‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
)‫کنترل تکرار با نگهبان (ادامه‬
)‫• یادآوری (حل گام به گام مساله‬
،‫– شبه کد سطح باال‬
Determine the class average for the quiz
‫– اصالح و پاالیش شبه کد‬
Initialize variables
Input, sum and count the quiz grades
Calculate and print the class average
43
Ali Shakiba – http://shakiba.id.ir
‫کنترل تکرار با نگهبان (ادامه)‬
‫• بسیاری از برنامه‌ها از سه فاز تشکیل شده‌اند‪:‬‬
‫– مقداردهی اولیه‬
‫• مقداردهی اولیه متغیرهای برنامه‪،‬‬
‫– پردازش‬
‫• دریافت داده از ورودی‪ ،‬تغییر دادن متغیرهای برنامه‪،‬‬
‫– خاتمه‬
‫• محاسبه و چاپ نتایج‬
‫‪44‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
)‫کنترل تکرار با نگهبان (ادامه‬
:‫• مقداردهی اولیه‬
Initialize variables
:‫به دستورات زیر تبدیل می‌شود‬
Initialize total to zero
Initialize counter to zero
:‫• پردازش‬
Input, sum and count the quiz grades
:‫به دستورات زیر تبدیل می‌شود‬
Input the first grade (possibly the sentinel)
While the user has not as yet entered the sentinel
Add this grade into the running total
Add one to the grade counter
Input the next grade (possibly the sentinel)
45
Ali Shakiba – http://shakiba.id.ir
)‫کنترل تکرار با نگهبان (ادامه‬
‫• خاتمه‬
Calculate and print the class average
:‫به دستورات زیر تبدیل می‌شود‬
If the counter is not equal to zero
Set the average to the total divided by the counter
Print the average
Else
Print “No grades were entered”
.‫ تبدیل کنید‬C++ ‫ این شبه‌کد را به یک برنامه معتبر‬:‫• تمرین کالس ی‬
46
Ali Shakiba – http://shakiba.id.ir
)‫کنترل تکرار با نگهبان (ادامه‬
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
47
25
Ali Shakiba – http://shakiba.id.ir
// Fig. 2.9: fig02_09.cpp
// Class average program with sentinel-controlled repetition.
#include <iostream>
using
using
using
using
std::cout;
std::cin;
std::endl;
std::fixed;
#include <iomanip>
// parameterized stream manipulators
using std::setprecision;
// sets numeric output precision
// function main begins program execution
int main()
Data type double used to represent
{
int total;
// sum of grades decimal numbers.
int gradeCounter; // number of grades entered
int grade;
// grade value
double average;
// number with decimal point for average
// initialization phase
total = 0;
// initialize total
gradeCounter = 0; // initialize loop counter
)‫کنترل تکرار با نگهبان (ادامه‬
48
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// processing phase
// get first grade from user
cout << "Enter grade, -1 to end: ";
cin >> grade;
// prompt for input
// read grade from user
// loop until sentinel value read from user
treats total
while ( grade != -1 )static_cast<double>()
{
double temporarily
(casting).
total = total + grade;
// add
grade to total
gradeCounter = gradeCounter + 1; // increment counter
as a
Required because dividing two integers truncates the
cout << "Enter grade, -1 to end: ";
remainder.
cin >> grade;
} // end while
// prompt for input
// read next grade
gradeCounter is an int, but it gets promoted to
double.
// termination phase
// if user entered at least one grade ...
if ( gradeCounter != 0 ) {
// calculate average of all grades entered
average = static_cast< double >( total ) / gradeCounter;
Ali Shakiba – http://shakiba.id.ir
)‫کنترل تکرار با نگهبان (ادامه‬
49
50
51
52
53
54
55
56
57
58
59
60
49
// display average with two digits of precision
cout << "Class average is " << setprecision( 2 )
<< fixed << average << endl;
} // end if part of if/else
else // if no grades were entered, output appropriate message
cout << "No grades were entered" << endl;
return 0;
// indicate program ended successfully
} // end function main
Enter
Enter
Enter
Enter
Enter
Enter
Enter
Enter
Enter
Class
grade, -1 to end:
grade, -1 to end:
grade, -1 to end:
grade, -1 to end:
grade, -1 to end:
grade, -1 to end:
grade, -1 to end:
grade, -1 to end:
grade, -1 to end:
average is 82.50
Ali Shakiba – http://shakiba.id.ir
75
94
97
88
70
64
83
89
-1
setprecision(2)prints
two digits past
fixed forces output
to print
decimal
in fixed point format
(not point (rounded to fit precision).
scientific notation). Also,
that use this must include <iomanip>
forces trailing zerosPrograms
and
decimal point to print.
Include <iostream>
‫ساختار تکرار ‪do/while‬‬
‫• با ساختار تکرار ‪ while‬مشابه است‪ ،‬اما دارای تفاوت‌های ذیل‬
‫است‪:‬‬
‫– شرط ادامه حلقه را در انتهای حلقه کنترل می‌کند‪،‬‬
‫– بدنه حلقه حداقل برای یک بار اجرا می‌شود‪،‬‬
‫• به فرم ذیل است‪:‬‬
‫{ ‪do‬‬
‫‪statement‬‬
‫;) ‪} while ( condition‬‬
‫‪50‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
)‫ (ادامه‬do/while ‫ساختار تکرار‬
51
Ali Shakiba – http://shakiba.id.ir
)‫ (ادامه‬do/while ‫ساختار تکرار‬
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
52
1
// Fig. 2.24: fig02_24.cpp
// Using the do/while repetition structure.
#include <iostream>
using std::cout;
using std::endl;
// function main begins program execution
int main()
{
int counter = 1;
// initialize counter
do {
cout << counter << " ";
} while ( ++counter <= 10 );
Notice the preincrement in
loop-continuation test.
// display counter
// end do/while
cout << endl;
return 0;
// indicate successful termination
} // end function main
2
3
4
5
Ali Shakiba – http://shakiba.id.ir
6
7
8
9
10
‫ساختارهای کنترلی النه‌ای‬
‫• بیان مساله‬
‫‪A college has a list of test results (1 = pass, 2 = fail) for‬‬
‫‪10 students. Write a program that analyzes the‬‬
‫‪results. If more than 8 students pass, print "Raise‬‬
‫‪Tuition".‬‬
‫• با در نظر گرفتن شرایط زیر‬
‫– برنامه دقیقا ‪ 10‬نمره را دریافت می‌کند‪،‬‬
‫• بنابراین از ساختار تکرار با شمارنده می‌توان استفاده کرد‪،‬‬
‫– می‌توان از دو شمارنده استفاده نمود‪،‬‬
‫• یک شمارنده تعداد افراد قبول شده را ذخیره کند‪،‬‬
‫• شمارنده دیگر‪ ،‬تعداد افراد رد شده را ذخیره کند‪،‬‬
‫– نتیجه آزمون یا ‪ 1‬است یا ‪،2‬‬
‫• هر ورودی غیر از ‪ 1‬را به عنوان مردود در نظر بگیرید‪.‬‬
‫‪53‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
)‫ساختارهای کنترلی النه‌ای (ادامه‬
‫• شبه‌کد سطح باال‬
Analyze exam results and decide if tuition should be raised
‫• پاالیش اولیه‬
Initialize variables
Input the ten quiz grades and count passes and failures
Print a summary of the exam results and decide if tuition
should be raised
‫• پاالیش سه‌گامی‬
Initialize variables
:‫به دستورات زیر تبدیل می‌شود‬
Initialize passes to zero
Initialize failures to zero
Initialize student counter to one
54
Ali Shakiba – http://shakiba.id.ir
)‫ساختارهای کنترلی النه‌ای (ادامه‬
)‫• پاالیش سه‌گامی (ادامه‬
Input the ten quiz grades and count passes and failures
:‫به دستورات زیر تبدیل می‌شود‬
While student counter is less than or equal to ten
Input the next exam result
If the student passed
Add one to passes
Else
Add one to failures
Add one to student counter
55
Ali Shakiba – http://shakiba.id.ir
)‫ساختارهای کنترلی النه‌ای (ادامه‬
)‫• پاالیش سه‌گامی (ادامه‬
Print a summary of the exam results and decide if tuition
should be raised
:‫به دستورات زیر تبدیل می‌شود‬
Print the number of passes
Print the number of failures
If more than eight students passed
Print “Raise tuition”
.‫ تبدیل کنید‬C++ ‫ این شبه کد را به یک برنامه معتبر‬:‫• تمرین کالس ی‬
56
Ali Shakiba – http://shakiba.id.ir
)‫ساختارهای کنترلی النه‌ای (ادامه‬
57
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Fig. 2.11: fig02_11.cpp
// Analysis of examination results.
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
// function main begins program execution
int main()
{
// initialize variables in declarations
int passes = 0;
// number of passes
int failures = 0;
// number of failures
int studentCounter = 1;
// student counter
int result;
// one exam result
// process 10 students using counter-controlled loop
while ( studentCounter <= 10 ) {
Ali Shakiba – http://shakiba.id.ir
// prompt user for input and obtain value from user
cout << "Enter result (1 = pass, 2 = fail): ";
cin >> result;
)‫ساختارهای کنترلی النه‌ای (ادامه‬
58
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// if result 1, increment passes; if/else nested in while
if ( result == 1 )
// if/else nested in while
passes = passes + 1;
else // if result not 1, increment failures
failures = failures + 1;
// increment studentCounter so loop eventually terminates
studentCounter = studentCounter + 1;
} // end while
// termination phase; display number of passes and failures
cout << "Passed " << passes << endl;
cout << "Failed " << failures << endl;
// if more than eight students passed, print "raise tuition"
if ( passes > 8 )
cout << "Raise tuition " << endl;
return 0;
// successful termination
} // end function main
Ali Shakiba – http://shakiba.id.ir
)‫ساختارهای کنترلی النه‌ای (ادامه‬
Enter result
Enter result
Enter result
Enter result
Enter result
Enter result
Enter result
Enter result
Enter result
Enter result
Passed 6
Failed 4
(1
(1
(1
(1
(1
(1
(1
(1
(1
(1
=
=
=
=
=
=
=
=
=
=
pass,
pass,
pass,
pass,
pass,
pass,
pass,
pass,
pass,
pass,
2
2
2
2
2
2
2
2
2
2
=
=
=
=
=
=
=
=
=
=
fail):
fail):
fail):
fail):
fail):
fail):
fail):
fail):
fail):
fail):
1
2
2
1
1
1
2
1
1
2
Enter result (1
Enter result (1
Enter result (1
Enter result (1
Enter result (1
Enter result (1
Enter result (1
Enter result (1
Enter result (1
Enter result (1
Passed 9
Failed 1
Raise tuition
=
=
=
=
=
=
=
=
=
=
pass,
pass,
pass,
pass,
pass,
pass,
pass,
pass,
pass,
pass,
2
2
2
2
2
2
2
2
2
2
=
=
=
=
=
=
=
=
=
=
fail):
fail):
fail):
fail):
fail):
fail):
fail):
fail):
fail):
fail):
1
1
1
1
2
1
1
1
1
1
59
Ali Shakiba – http://shakiba.id.ir
for ‫ساختار تکرار‬
for ‫• ساختار کلی حلقه تکرار‬
for ( initialization; LoopContinuationTest;
increment )
statement
‫• مثال‬
for( int counter = 1; counter <= 10; counter++ )
cout << counter << endl;
.‫ را چاپ می‌کند‬10 ‫ تا‬1 ‫– اعداد صحیح از‬
No semicolon
after last
statement
60
Ali Shakiba – http://shakiba.id.ir
)‫ (ادامه‬for ‫ساختار تکرار‬
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Fig. 2.17: fig02_17.cpp
// Counter-controlled repetition with the for structure.
#include <iostream>
using std::cout;
using std::endl;
// function main begins program execution
int main()
{
// Initialization, repetition condition and incrementing
// are all included in the for structure header.
for ( int counter = 1; counter <= 10; counter++ )
cout << counter << endl;
return 0;
// indicate successful termination
} // end function main
61
Ali Shakiba – http://shakiba.id.ir
)‫ (ادامه‬for ‫ساختار تکرار‬
1
2
3
4
5
6
7
8
9
10
62
Ali Shakiba – http://shakiba.id.ir
‫ساختار تکرار ‪( for‬ادامه)‬
‫• حلقه‌های تکرار ‪ for‬را می‌توان با استفاده از حلقه‌های تکرار‬
‫‪ while‬بازنویس ی کرد‪.‬‬
‫;‪initialization‬‬
‫{)‪while ( loopContinuationTest‬‬
‫‪statement‬‬
‫;‪increment‬‬
‫}‬
‫• مقداردهی اولیه و افزایش‬
‫– برای استفاده از چندین متغیر‪ ،‬از ‪ ,‬استفاده می‌شود‪.‬‬
‫;‪for (int i = 0, j = 0; j + i <= 10‬‬
‫)‪j++, i++‬‬
‫;‪cout << j + i << endl‬‬
‫‪63‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
)‫ (ادامه‬for ‫ساختار تکرار‬
64
Ali Shakiba – http://shakiba.id.ir
)‫ (ادامه‬for ‫ساختار تکرار‬
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Fig. 2.20: fig02_20.cpp
// Summation with for.
#include <iostream>
using std::cout;
using std::endl;
// function main begins program execution
int main()
{
int sum = 0;
// initialize sum
// sum even integers from 2 through 100
for ( int number = 2; number <= 100; number += 2 )
sum += number;
// add number to sum
cout << "Sum is " << sum << endl;
return 0;
} // end function main
Sum is 2550
65
Ali Shakiba – http://shakiba.id.ir
// output sum
// successful termination
)‫ (ادامه‬for ‫ساختار تکرار‬
‫• مساله محاسبه سود ترکیبی‬
• A person invests $1000.00 in a savings account yielding 5 percent interest.
Assuming that all interest is left on deposit in the account, calculate and
print the amount of money in the account at the end of each year for 10
years. Use the following formula for determining these amounts:
a = p(1+r)
n
• p is the original amount invested (i.e., the principal),
r is the annual interest rate,
n is the number of years and
a is the amount on deposit at the end of the nth year
66
Ali Shakiba – http://shakiba.id.ir
)‫ (ادامه‬for ‫ساختار تکرار‬
67
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Fig. 2.21: fig02_21.cpp
// Calculating compound interest.
#include <iostream>
using
using
using
using
std::cout;
std::endl;
std::ios;
std::fixed;
#include <iomanip>
using std::setw;
using std::setprecision;
#include <cmath>
<cmath> header needed for
the pow function (program
will not compile without it).
// enables program to use function pow
// function main begins program execution
int main()
{
double amount;
// amount on deposit
double principal = 1000.0; // starting principal
double rate = .05;
// interest rate
Ali Shakiba – http://shakiba.id.ir
)‫ (ادامه‬for ‫ساختار تکرار‬
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// output table column heads
cout << "Year" << setw( 21 ) << "Amount on deposit" << endl;
// set floating-point number format
cout << fixed << setprecision( 2 );
Sets the field width to at least
21 characters. If output less
than 21, it is right-justified.
// calculate amount on deposit for each of ten years
for ( int year = 1; year <= 10; year++ ) {
pow(x,y) = x raised to the
yth power.
// calculate new amount for specified year
amount = principal * pow( 1.0 + rate, year );
// output one table row
cout << setw( 4 ) << year
<< setw( 21 ) << amount << endl;
} // end for
return 0;
// indicate successful termination
} // end function main
68
Ali Shakiba – http://shakiba.id.ir
)‫ (ادامه‬for ‫ساختار تکرار‬
Year
1
2
3
4
5
6
7
8
9
10
Amount on deposit
1050.00
1102.50
1157.63
1215.51
1276.28
1340.10
1407.10
1477.46
1551.33
1628.89
Numbers are right-justified
due to setw statements (at
positions 4 and 21).
69
Ali Shakiba – http://shakiba.id.ir
‫عبارت ‪break‬‬
‫• ‪break‬‬
‫– در ساختارهای تکرار‪ ، do/while، for،while‬و ساختار‬
‫تصمیم ‪ switch‬منجر به خاتمه بالفاصله ساختار می‌شود‪.‬‬
‫– اجرای برنامه با اولین دستور بعد از ساختار ادامه می‌یابد‪.‬‬
‫• استفاده‌های معمول‌‬
‫– خروج زودهنگام از حلقه‌های تکرار‪،‬‬
‫– پریدن از بقیه حالت‌های ساختار ‪.switch‬‬
‫‪70‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
)‫ (ادامه‬break ‫عبارت‬
1
// Fig. 2.26: fig02_26.cpp
2
// Using the break statement in a for structure.
3
#include <iostream>
4
5
using std::cout;
6
using std::endl;
7
8
// function main begins program execution
9
int main()
10 {
11
12
int x; // x declared here so it can be used after the loop
13
14
// loop 10 times
Exits for structure when
15
for ( x = 1; x <= 10; x++ ) {
break executed.
16
17
// if x is 5, terminate loop
18
if ( x == 5 )
19
break;
// break loop only if x is 5
20
21
cout << x << " ";
// display value of x
22
23
} // end for
24
71
25
cout << "\nBroke out of loop when x became " << x << endl;
Ali Shakiba – http://shakiba.id.ir
)‫ (ادامه‬break ‫عبارت‬
26
27
28
29
return 0;
// indicate successful termination
} // end function main
1 2 3 4
Broke out of loop when x became 5
72
Ali Shakiba – http://shakiba.id.ir
‫عبارت ‪continue‬‬
‫• ‪continue‬‬
‫– کاربرد در ساختارهای تکرار ‪while, for, do/while‬‬
‫– از اجرای بقیه ساختار صرف نظر می‌کند و‬
‫– تکرار بعدی حلقه را انجام می‌دهد‪.‬‬
‫• در ساختارهای ‪ while‬و ‪do/while‬‬
‫– بالفاصله پس از عبارت ‪ ،continue‬شرط حلقه آزموده می‌شود‪.‬‬
‫• در ساختار ‪for‬‬
‫– بالفاصله پس از عبارت ‪ ،continue‬عبارت افزایش اجرا می‌شود‪،‬‬
‫– شرط حلقه مورد آزمایش قرار می‌گیرد‪.‬‬
‫‪73‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
)‫ (ادامه‬continue ‫عبارت‬
1
// Fig. 2.27: fig02_27.cpp
2
// Using the continue statement in a for structure.
3
#include <iostream>
4
5
using std::cout;
6
using std::endl;
7
8
// function main begins program execution
9
int main()
10 {
11
// loop 10 times
12
for ( int x = 1; x <= 10; x++ ) {
Skips to next iteration of the
13
loop.
14
// if x is 5, continue with next
iteration of loop
15
if ( x == 5 )
16
continue;
// skip remaining code in loop body
17
18
cout << x << " ";
// display value of x
19
20
} // end for structure
21
22
cout << "\nUsed continue to skip printing the value 5"
23
<< endl;
24
74
25
return 0;
// indicate successful termination
Ali Shakiba – http://shakiba.id.ir
)‫ (ادامه‬continue ‫عبارت‬
26
27
} // end function main
1 2 3 4 6 7 8 9 10
Used continue to skip printing the value 5
75
Ali Shakiba – http://shakiba.id.ir
)‫ساختارهای کنترلی (جمع بندی‬
76
Ali Shakiba – http://shakiba.id.ir
)‫ساختارهای کنترلی (جمع بندی‬
77
Ali Shakiba – http://shakiba.id.ir
‫توابع‬
Ali Shakiba – http://shakiba.id.ir
‫مقدمه‬
‫• تقسیم و غلبه‬
‫– ساختن یک برنامه با استفاده از برنامه‌های کوچک‌تر‬
‫– فرآیند توسعه هر کدام از برنامه‌های کوچکتر‪ ،‬به دلیل کوچکی‪ ،‬قابل‬
‫مدیریت تر است‪.‬‬
‫‪79‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫اجزای برنامه‌های ‪C++‬‬
‫• توابع و کالس‌ها‪،‬‬
‫• برنامه‌های ‪ C++‬از اجزای جدید و همچنین پیش‌تعریف شده استفاده‬
‫می‌کنند‪:‬‬
‫– جدید‪ :‬توابع و کالس‌های تعریف شده توسط برنامه‌نویس‪،‬‬
‫– پیش‌تعریف شده‪ :‬توابع و کالس‌های تعریف شده در کتابخانه‌های موجود‪،‬‬
‫• … ‪STL, Boost, CGAL, LEDA,‬‬
‫• برای استفاده از توابع‪ ،‬باید آن‌ها را فراخوانی کرد‪:‬‬
‫– برای فراخوانی‪ ،‬نیاز به نام و اطالعات ورودی تابع است‪،‬‬
‫• تعریف توابع‬
‫– فقط یک بار نوشته می‌شوند‪،‬‬
‫– از سایر توابع مخفی است‪.‬‬
‫‪80‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫اجزای برنامه‌های ‪( C++‬ادامه)‬
‫• رئیس و کارمند‬
‫– رئیس از کارمند خود می‌خواهد (فراخوانی) کاری را انجام دهد و پس از‬
‫انجام آن کار‪ ،‬نتیجه حاصل را گزارش (بازگرداندن نتیجه) کند‪.‬‬
‫‪81‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫توابع‬
‫• توابع‬
‫– پیمانه‌ای کردن برنامه‌ها‪،‬‬
‫– استفاده مجدد‬
‫• توابع یک بار تعریف و چندین بار فراخوانی می‌شوند‪،‬‬
‫• متغیرهای محلی‬
‫– تنها در بدنه توابع شناخته شده هستند‪،‬‬
‫– تمامی متغیرهای تعریف شده در بدنه توابع‪ ،‬محلی هستند‪،‬‬
‫• پارامترها‬
‫– متغیرهایی که به عنوان ورودی به تابع مورد فراخوانی داده شده اند‪،‬‬
‫– با خود اطالعاتی را از جهان بیرون حمل می‌کنند!‬
‫‪82‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫تعریف توابع‬
‫• نمونه اولیه توابع‬
‫– به کامپایلر درباره نوع پارامترهای ورودی و نتیجه تابع اطالع می‌دهد‪:‬‬
‫;) ‪– int square( int‬‬
‫• مقدار ورودی تابع از نوع ‪ int‬بوده و نتیجه آن نیز از نوع ‪ int‬است‪،‬‬
‫• فراخوانی تابع‬
‫;)‪– square(x‬‬
‫– عملگر پرانتز بعد از نام تابع‪ ،‬عملگر فراخوانی تابع است‪،‬‬
‫• پارامتر ‪ x‬را به تابع پاس می‌دهد‪،‬‬
‫• تابع یک کپی از پارامتر ‪ x‬را دریافت می‌کند (تغییر در آن منجر به تغییر ‪ x‬در برنامه‬
‫فراخواننده نمی‌شود)‪،‬‬
‫– پس از پایان تابع‪ ،‬نتیجه را بازگردانی می‌کند‪.‬‬
‫‪83‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫تعریف توابع (ادامه)‬
‫• قالب تعریف توابع‬
‫) ‪return-value-type function-name( parameter-list‬‬
‫{‬
‫‪declarations and statements‬‬
‫}‬
‫– لیست پارامترها‬
‫• پارامترها با کاما از یکدیگر جدا شده اند‪،‬‬
‫– هر پارامتر باید دارای یک نوع داده باشد‪،‬‬
‫• در صورتی که تابع هیچ پارامتری نداشته باشد‪ ،‬از نوع ‪ void‬استفاده می‌شود و یا‬
‫لیست پارامترها را تهی در نظر می‌گیریم‪.‬‬
‫– نوع داده نتیجه‬
‫• اگر تابع هیچ مقداری را به عنوان نتیجه بازنگرداند‪ ،‬از ‪ void‬استفاده می‌کنیم‪.‬‬
‫‪84‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫تعریف توابع (ادامه)‬
‫• مثال‬
‫) ‪int square( int y‬‬
‫{‬
‫;‪return y * y‬‬
‫}‬
‫• کلمه کلیدی ‪return‬‬
‫– داده را بازگردانده و کنترل اجرا را به فراخواننده بر می‌گرداند‪،‬‬
‫• در صورتی که هیچ داده‌ای بر نمی گردانید‪ ،‬به عنوان یک عادت خوب از عبارت‬
‫;‪ return‬استفاده کنید‪.‬‬
‫– اجرای تابع هنگامی که به } برسد‪ ،‬خاتمه پیدا می‌کند‪،‬‬
‫• در این حالت‪ ،‬کنترل اجرا به فراخواننده بازگردانده می‌شود‪،‬‬
‫• نمی‌توان یک تابع را درون تابعی دیگر تعریف کرد‪.‬‬
‫‪85‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
86
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Fig. 3.3: fig03_03.cpp
// Creating and using a programmer-defined function.
#include <iostream>
using std::cout;
using std::endl;
int square( int );
//
Function prototype: specifies
data types of arguments and
return values. square
expects and int, and returns
function prototype
an int.
int main()
{
Parentheses () cause
// loop 10 times and calculate and output
function to be called. When
// square of x each time
done, it returns the result.
for ( int x = 1; x <= 10; x++ )
cout << square( x ) << " "; // function call
cout << endl;
return 0;
} // end main
Ali Shakiba – http://shakiba.id.ir
// indicates successful termination
23
24
25
26
27
28
1
// square function definition returns square of an integer
int square( int y ) // y is a copy of argument to function
{
return y * y;
// returns square of y as an int
} // end function square
4
9
16
87
Ali Shakiba – http://shakiba.id.ir
25
36
49
64
81
100
Definition of square. y is a
copy of the argument passed.
Returns y * y, or y squared.
1
// Fig. 3.4: fig03_04.cpp
2
// Finding the maximum of three floating-point numbers.
3
#include <iostream>
4
5
using std::cout;
6
using std::cin;
7
using std::endl;
8
9
double maximum( double, double, double ); // function prototype
10
11 int main()
12 {
13
double number1;
Function maximum takes 3
14
double number2;
arguments (all double) and
15
double number3;
returns a double.
16
17
cout << "Enter three floating-point numbers: ";
18
cin >> number1 >> number2 >> number3;
19
20
// number1, number2 and number3 are arguments to
21
// the maximum function call
22
cout << "Maximum is: "
23
<< maximum( number1, number2, number3 ) << endl;
88
24
25
return 0; // indicates successful termination
Ali Shakiba – http://shakiba.id.ir
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
} // end main
Comma separated list for
multiple parameters.
// function maximum definition;
// x, y and z are parameters
double maximum( double x, double y, double z )
{
double max = x;
// assume x is largest
if ( y > max )
max = y;
// if y is larger,
// assign y to max
if ( z > max )
max = z;
// if z is larger,
// assign z to max
return max;
// max is largest value
} // end function maximum
Enter three floating-point numbers: 99.32 37.3 27.1928
Maximum is: 99.32
Enter three floating-point numbers: 1.1 3.333 2.22
Maximum is: 3.333
Enter three floating-point numbers: 27.9 14.31 88.99
Maximum is: 88.99
Ali Shakiba – http://shakiba.id.ir
89
‫نمونه اولیه توابع‬
‫• نمونه اولیه توابع شامل‬
‫–‬
‫–‬
‫–‬
‫–‬
‫نام تابع‪،‬‬
‫تعداد و نوع داده پارامترها‪،‬‬
‫نوع داده نتیجه تابع‪،‬‬
‫تنها در صورتی نیاز به تعریف نمونه اولیه تابع داریم که تابع را قبل از تعریف‬
‫آن فراخوانی کرده باشیم‪.‬‬
‫• نمونه اولیه باید دقیقا با تعریف تابع همخوانی داشته باشد‪:‬‬
‫– نمونه اولیه‬
‫;) ‪double maximum( double, double, double‬‬
‫– تعریف‬
‫) ‪double maximum( double x, double y, double z‬‬
‫{‬
‫…‬
‫}‬
‫‪90‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫نمونه اولیه توابع (ادامه)‬
‫• امضای تابع‬
‫– نام و پارامترهای نمونه اولیه تابع‬
‫;) ‪• double maximum( double, double, double‬‬
‫‪Function signature‬‬
‫– امضای هیچ دو تابعی نمی‌تواند یکسان باشد‪،‬‬
‫• تبدیل نوع داده خودکار پارامترها‬
‫– الزام به اینکه پارامترهای ورودی توابع از نوع داده تعیین شده باشند‪،‬‬
‫• تبدیل )‪ int (4‬به نوع )‪double (4.0‬‬
‫– قواعد تبدیل‬
‫)‪cout << sqrt(4‬‬
‫• عموما به صورت خودکار انجام می‌شود‪،‬‬
‫• تبدیل از ‪ double‬به ‪ int‬می‌تواند منجر به از دست رفتن داده‌ها شود‪،‬‬
‫– انواع مرکب به باالترین نوع داده تبدیل می‌شوند‪:‬‬
‫‪– 3.4 to 3‬‬
‫‪• int * double‬‬
‫‪91‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
)‫نمونه اولیه توابع (ادامه‬
Data types
long double
double
float
unsigned long int (synonymous with unsigned long)
long int
(synonymous with long)
unsigned int
(synonymous with unsigned)
int
unsigned short int
short int
(synonymous with unsigned short)
(synonymous with short)
unsigned char
char
bool
92
Ali Shakiba – http://shakiba.id.ir
(false becomes 0, true becomes 1)
‫فایل‌های سرآمد‬
‫• فایل‌های سرآمد شامل‬
‫– نمونه‌های اولیه توابع‪،‬‬
‫– تعریف انواع داده و ثوابت‪.‬‬
‫• پسوند فایل‌های سرآمد ‪ .h‬است‬
‫– فایل‌های سرآمد تولید شده توسط برنامه‌نویس‬
‫”‪#include “myheader.h‬‬
‫• فایل‌های سرآمد کتابخانه‌ای‬
‫>‪#include <cmath‬‬
‫‪93‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫تولید عدد تصادفی‬
<cstdlib> ‫ از کتابخانه‬rand ‫• تابع‬
– i = rand();
‫ (معموال‬RAND_MAX‫– تولید یک عدد صحیح نامنفی تصادفی بین صفر و‬
،)‫ است‬32767
‫• تبدیل به بازه مورد نظر‬
% ‫– عملگر باقی‌مانده‬
• 10 % 3 is 1
• x % y is between 0 and y – 1
‫– مثال‬
i = rand() % 6 + 1;
• “Rand() % 6” generates a number between 0 and 5 (scaling)
• “+ 1” makes the range 1 to 6 (shift)
94
Ali Shakiba – http://shakiba.id.ir
1
// Fig. 3.7: fig03_07.cpp
2
// Shifted, scaled integers produced by 1 + rand() % 6.
3
#include <iostream>
4
5
using std::cout;
6
using std::endl;
7
8
#include <iomanip>
9
10 using std::setw;
11
12 #include <cstdlib>
// contains function prototype for rand
13
14 int main()
15 {
16
// loop 20 times
Output of rand() scaled
17
for ( int counter = 1; counter <= 20; counter++ ) {
shifted to be a number
18
19
// pick random number from 1 to 6 and output it between 1 and 6.
20
cout << setw( 10 ) << ( 1 + rand() % 6 );
21
22
// if counter divisible by 5, begin new line of output
23
if ( counter % 5 == 0 )
24
cout << endl;
25
95
26
} // end for structure
Ali Shakiba – http://shakiba.id.ir
and
27
28
29
30
return 0;
// indicates successful termination
} // end main
6
5
6
6
96
Ali Shakiba – http://shakiba.id.ir
6
1
6
2
5
1
2
3
5
5
4
4
6
3
2
1
‫تولید عدد تصادفی (ادامه)‬
‫• تمرین کالس ی‪ :‬توزیع احتمال تابع )(‪ rand‬را بیابید!‬
‫‪97‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
1
// Fig. 3.9: fig03_09.cpp
2
// Randomizing die-rolling program.
3
#include <iostream>
4
5
using std::cout;
6
using std::cin;
7
using std::endl;
8
9
#include <iomanip>
10
11 using std::setw;
12
13 // contains prototypes for functions srand and rand
14 #include <cstdlib>
15
16 // main function begins program execution
17 int main()
18 {
19
unsigned seed;
Setting the seed with
20
srand().
21
cout << "Enter seed: ";
22
cin >> seed;
23
srand( seed ); // seed random number generator
98
24
Ali Shakiba – http://shakiba.id.ir
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// loop 10 times
for ( int counter = 1; counter <= 10; counter++ ) {
// pick random number from 1 to 6 and output it
cout << setw( 10 ) << ( 1 + rand() % 6 );
// if counter divisible by 5, begin new line of output
if ( counter % 5 == 0 )
cout << endl;
} // end for
return 0;
// indicates successful termination
rand() gives the same
sequence if it has the same
initial seed.
} // end main
Enter seed: 67
6
1
1
6
4
1
6
6
2
4
Enter seed: 432
4
3
6
1
3
5
1
4
6
2
1
6
4
1
6
6
2
4
Enter seed: 67
99
6
Ali Shakiba – http://shakiba.id.ir 1
‫تولید عدد تصادفی (ادامه)‬
‫• برای اینکه الزم نباشد مقدار اولیه تصادفی را از کاربر دریافت کنیم‪،‬‬
‫می‌توان از راهکار زیر استفاده کرد‪:‬‬
‫;) ) ‪– srand( time( 0‬‬
‫;) ‪– time( 0‬‬
‫>‪• <ctime‬‬
‫• زمان فعلی را به ثانیه بازمی‌گرداند‪.‬‬
‫‪100‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
enum ‫ساختار‬
Enumeration •
‫– مجموعه‌ای مرتب از برچسب‌ها‬
enum typeName {constant1, constant2…};
،‫ اندیس اولین عنصر صفر است‬،‫– به صورت پیش‌فرض‬
،‫– برچسب‌ها باید متمایز باشند‬
!‫ نمی‌توان عدد صحیح نسبت داد‬enum ‫– به متغیرهای‬
:‫• مثال‬
enum Status {CONTINUE, WON, LOST};
Status enumVar;
enumVar = WON; // cannot do enumVar = 1
101
Ali Shakiba – http://shakiba.id.ir
)‫ (ادامه‬enum ‫ساختار‬
:‫• می‌توان اندیس اولیه متفاوتی به اولین عنصر نسبت داد‬
enum Months { JAN = 1, FEB, MAR,
APR, MAY, JUN, JUL, AUG, SEP, OCT,
NOV, DEC};
102
Ali Shakiba – http://shakiba.id.ir
‫رده‌های حافظه‬
‫• خصوصیت‌های یک متغیر‬
‫– نام‪ ،‬نوع داده‪ ،‬اندازه‪ ،‬مقدار‬
‫– رده حافظه‬
‫• تا چه مدت مقدار آن در حافظه نگهداری شود؟‬
‫– قلمر ‌و‬
‫• در چه جایی از برنامه می‌توان به متغیرها ارجاع داد؟‬
‫– قابلیت پیوند‬
‫• آیا متغیر فقط در همین فایل قابل ارجاع است یا نه؟‬
‫‪103‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫رده‌های حافظه (ادامه)‬
‫• رده حافظه خودکار‬
‫– هنگامی که اجرای برنامه وارد بلوکی می‌شود که متغیر در آن تعریف شده‪ ،‬متغیر ایجاد‬
‫شده‪،‬‬
‫– و با به رسیدن به پایان آن بلوک‪ ،‬متغیر از بین می‌رود‪،‬‬
‫– فقط متغیرهای محلی در توابع می‌توانند خودکار باشند‪،‬‬
‫• به صورت پیش‌فرض خودکار هستند‪،‬‬
‫• از کلمه کلیدی ‪ auto‬برای بیان خودکار بودن صریح یک متغیر استفاده می‌شود‪،‬‬
‫– کلمه کلیدی ‪register‬‬
‫• به کامپایلر توصیه می‌کند که این متغیر را در ثبات‌های پردازنده جاگذاری کند!‬
‫• معموال برای متغیرهای پر استفاده مانند شمارنده‌های حلقه‌ها کاربرد دارد‪،‬‬
‫• معموال نیازی به آن نیست‪ ،‬زیرا کامپایلرهای امروزی بهینه سازی را خودکار انجام می‌دهند‪،‬‬
‫– نمی توان به صورت همزمان از دو کلمه کلیدی ‪ register‬یا ‪ auto‬استفاده‬
‫کرد‬
‫;‪• register int counter = 1‬‬
‫‪104‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫رده‌های حافظه (ادامه)‬
‫• رده‌های حافظه استاتیک‬
‫– در تمام طول اجرای برنامه از زمان تعریف وجود دارند‪،‬‬
‫دسترس‬
‫– البته قواعد قلمرو در مورد آن‌ها صادق است‪ ،‬بنابراین ممکن است در ‌‬
‫نباشند!‬
‫• کلمه‌کلیدی ‪static‬‬
‫– متغیرهای محلی در توابع‪،‬‬
‫– در توالی فراخوانی توابع‪ ،‬مقدار خود را حفظ می‌کنند!‬
‫– تنها در تابعی که تعریف شده اند‪ ،‬شناخته شده هستند!‬
‫• کلمه‌کلیدی ‪extern‬‬
‫– برای توابع و متغیرهای عمومی‪ ،‬به صورت پیش فرض استفاده می‌شود‪،‬‬
‫• عمومی‪ :‬توابع یا متغیرهایی که خارج از هر تابعی تعریف می‌شوند‪،‬‬
‫– در هر تابعی که پس از تعریف شدن آن بیاید‪ ،‬شناخته شده هستند!‬
‫‪105‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫قواعد قلمرو‌‬
‫• قلمرو‌‬
‫– بخش ی از برنامه که یک شناسه را می‌توان در آن استفاده کرد!‬
‫• قلمرو فایل‬
‫– در همه توابع شناخته شده است و در خارج از هر تابعی تعریف شده‬
‫است‪،‬‬
‫– متغیرهای عمومی‪ ،‬توابع و امضای آن‌ها‪،‬‬
‫• قلمرو تابع‬
‫– تنها در بدنه تابع قابل استفاده است‪،‬‬
‫– تنها شناسه‌ها در این قلمرو قرار می‌گیرند‪.‬‬
‫‪106‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫قواعد قلمرو (ادامه)‬
‫• قلمرو بلوک‬
‫– تنها از محل تعریف تا پایان بلوک جاری و کلیه زیربلوک‌های آن قابل‬
‫دسترس ی است‪،‬‬
‫– متغیرهای محلی‪ ،‬پارامترهای توابع‪،‬‬
‫– متغیرهای ‪ static‬دارای قلمرو بلوکی هستند‪،‬‬
‫• قلمرو با رده حافظه دو خصوصیت کامال متفاوت هستند!‬
‫‪107‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
1
// Fig. 3.12: fig03_12.cpp
2
// A scoping example.
3
#include <iostream>
4
5
using std::cout;
6
using std::endl;
7
8
void useLocal( void );
// function prototype
Declared
outside of function;
9
void useStaticLocal( void ); // function prototype
global
variable with
file
10 void useGlobal( void );
// function
prototype
scope.
11
12 int x = 1;
// global variable
Local variable with function
13
scope.
14 int main()
15 {
16
int x = 5;
// local variable to main
17
18
cout << "local x in main's outer
scope
is "block,
<< x giving
<< endl;
Create
a new
x
19
block scope. When the block
20
{ // start new scope
ends, this x is destroyed.
21
22
int x = 7;
23
24
cout << "local x in main's inner scope is " << x << endl;
25
108
26
} // end new scope
Ali Shakiba – http://shakiba.id.ir
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
cout << "local x in main's outer scope is " << x << endl;
useLocal();
useStaticLocal();
useGlobal();
useLocal();
useStaticLocal();
useGlobal();
//
//
//
//
//
//
useLocal has local x
useStaticLocal has static local x
useGlobal uses global x
useLocal reinitializes its local x
static local x retains its prior value
global x also retains its value
cout << "\nlocal x in main is " << x << endl;
return 0;
} // end main
109
Ali Shakiba – http://shakiba.id.ir
// indicates successful termination
43
44
45
46
47
48
49
50
51
52
53
54
55
// useLocal reinitializes local variable x during each call
void useLocal( void )
{
int x = 25; // initialized each time useLocal is called
cout <<
<<
++x;
cout <<
<<
variable (local
endl << "local x is Automatic
" << x
variable
function). This
" on entering useLocal"
<< of
endl;
is
destroyed when the function
"local x is " << x exits, and reinitialized when
" on exiting useLocal"
<< endl;begins.
the function
} // end function useLocal
110
Ali Shakiba – http://shakiba.id.ir
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// useStaticLocal initializes static local variable x only the
// first time the function is called; value of x is saved
// between calls to this function
void useStaticLocal( void )
{
// initialized only first time useStaticLocal is called
static int x = 50;
cout <<
<<
++x;
cout <<
<<
endl << "local static x is " << x
" on entering useStaticLocal" << endl;
"local static x is " << xStatic local variable of
function;
it is initialized
" on exiting useStaticLocal"
<< endl;
} // end function useStaticLocal
71
111
Ali Shakiba – http://shakiba.id.ir
only
once, and retains its value
between function calls.
72
73
74
75
76
77
78
79
80
81
// useGlobal modifies global variable x during each call
void useGlobal( void )
{
cout << endl << "global x is " << x
This function does not declare
<< " on entering useGlobal" << endl;
any variables. It uses the
x *= 10;
global x declared in the
cout << "global x is " << x
beginning of the program.
<< " on exiting useGlobal" << endl;
} // end function useGlobal
local x in main's outer scope is 5
local x in main's inner scope is 7
local x in main's outer scope is 5
local x is 25 on entering useLocal
local x is 26 on exiting useLocal
local static x is 50 on entering useStaticLocal
local static x is 51 on exiting useStaticLocal
112
global x is 1 on entering useGlobal
global x is 10 on exiting useGlobal
Ali Shakiba – http://shakiba.id.ir
local x is 25 on entering useLocal
local x is 26 on exiting useLocal
local static x is 51 on entering useStaticLocal
local static x is 52 on exiting useStaticLocal
global x is 10 on entering useGlobal
global x is 100 on exiting useGlobal
local x in main is 5
113
Ali Shakiba – http://shakiba.id.ir
‫بازگشت‬
‫• توابع بازگشتی‬
‫– توابعی که خود را فراخوانی می‌کنند‪،‬‬
‫– در این توابع معموال یک (یا چند) حالت اولیه حل می‌شوند‪،‬‬
‫• اگر حالتی غیر از حالت اولیه باشد‪:‬‬
‫– مساله به زیر مسائل شکسته شده‪،‬‬
‫– تابع به صورت بازگشتی برای حل کردن هر یک از زیر مساله‌های ک ‌وچکتر‬
‫فراخوانی می‌شود‪،‬‬
‫• این حالت ادامه می‌یابد تا به حالت ابتدای برسد و سپس پاسخ را به صورت‬
‫پایین با باال تولید می‌کند!‬
‫‪114‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫بازگشت (ادامه)‬
‫• مثال‬
‫‪n! = n * ( n – 1 ) * ( n – 2 ) * … * 1‬‬
‫– رابطه بازگشتی‪:‬‬
‫) !) ‪• ( n! = n * ( n – 1‬‬
‫!‪5! = 5 * 4‬‬
‫…!‪4! = 4 * 3‬‬
‫– حالت پایه )‪(1! = 0! = 1‬‬
‫‪115‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
116
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Fig. 3.14: fig03_14.cpp
// Recursive factorial function.
#include <iostream>
using std::cout;
using std::endl;
#include <iomanip>
using std::setw;
Data type unsigned long
can hold an integer from 0 to
4 billion.
unsigned long factorial( unsigned long ); // function prototype
int main()
{
// Loop 10 times. During each iteration, calculate
// factorial( i ) and display result.
for ( int i = 0; i <= 10; i++ )
cout << setw( 2 ) << i << "! = "
<< factorial( i ) << endl;
return 0;
} // end main
Ali Shakiba – http://shakiba.id.ir
// indicates successful termination
25
26
27
28
29
30
31
32
33
34
35
36
37
// recursive definition of function factorial
The base
unsigned long factorial( unsigned long number
) case occurs when
we have 0! or 1!. All other
{
cases must be split up
// base case
if ( number <= 1 )
(recursive step).
return 1;
// recursive step
else
return number * factorial( number - 1 );
} // end function factorial
0! = 1
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! = 5040
8! = 40320
9! = 362880
117
10! = 3628800
Ali Shakiba – http://shakiba.id.ir
‫دنباله فیبوناتچی‬
0, 1, 1, 2, 3, 5, 8... :‫• دنباله فیبوناتچی‬
!‫ حاصل جمع دو عدد قبلی خودش است‬،‫– هر عدد‬
:‫– یک رابطه بازگشتی‬
• fib(n) = fib(n-1) + fib(n-2)
:‫• نمونه کد متناظر‬
long fibonacci( long n )
{
if ( n == 0 || n == 1 ) // base case
return n;
else
return fibonacci( n - 1 ) +
fibonacci( n – 2 );
}
118
Ali Shakiba – http://shakiba.id.ir
‫دنباله فیبوناتچی (ادامه)‬
‫• تعداد فراخوانی‌های بازگشتی‪:‬‬
‫– هر بار فراخوانی بازگشتی‪ ،‬تعداد فراخوانی‌ها را دو برابر می‌کند!‬
‫‪• 30th number = 2^30 ~ 4 billion function calls‬‬
‫– پیچیدگی نمایی!‬
‫‪119‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫بازگشت و تکرار‬
‫• اجرا‬
‫– تکرار‪ :‬حلقه صریح‪،‬‬
‫– بازگشت‪ :‬فراخوانی بازگشتی‪،‬‬
‫• خاتمه‬
‫– تکرار‪ :‬شرط حلقه نادرست شود‪،‬‬
‫– تکرار‪ :‬به حالت پایه برسیم‪.‬‬
‫• در هر دو حالت می‌توان تکرار بی‌نهایت داشت!‬
‫• باید بین سرعت عملکرد و صراحت بیان‪ ،‬تعادل برقرار کرد!‬
‫‪120‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫توابع ‪inline‬‬
‫• توابع ‪inline‬‬
‫– کلمه کلیدی ‪ inline‬قبل از تعریف تابع می‌آید‪،‬‬
‫– باعث می‌شود که کامپایلر به جای فراخوانی تابع‪ ،‬بدنه تابع را به جای هر‬
‫فراخوانی جایگذاری کند‪.‬‬
‫• سربار فراخوانی تابع را کاهش می‌دهد‪،‬‬
‫• کامپایلر می‌تواند ‪ inline‬بودن یک تابع را در نظر نگیرد و آن را فراخوانی کند‪.‬‬
‫– استفاده از آن برای توابع کوچک و پرکاربرد توصیه می‌شود‪،‬‬
‫• مثال‬
‫) ‪inline double cube( const double s‬‬
‫} ;‪{ return s * s * s‬‬
‫– کلمه کلیدی ‪ const‬به کامپایلر می‌گوید که این تابع مقدار ‪ s‬را تغییر‬
‫نمی‌دهد‪.‬‬
‫‪121‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Fig. 3.19: fig03_19.cpp
// Using an inline function to calculate.
// the volume of a cube.
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
// Definition of inline function cube. Definition of function
// appears before function is called, so a function prototype
// is not required. First line of function definition acts as
// the prototype.
inline double cube( const double side )
{
return side * side * side; // calculate cube
} // end function cube
122
Ali Shakiba – http://shakiba.id.ir
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
int main()
{
cout << "Enter the side length of your cube: ";
double sideValue;
cin >> sideValue;
// calculate cube of sideValue and display result
cout << "Volume of cube with side "
<< sideValue << " is " << cube( sideValue ) << endl;
return 0;
// indicates successful termination
} // end main
Enter the side length of your cube: 3.5
Volume of cube with side 3.5 is 42.875
123
Ali Shakiba – http://shakiba.id.ir
‫ارجاع و پارامترهای ارجاعی‬
‫• فراخوانی با مقدار‬
‫– یک کپی از پارامتر را به تابع پاس می‌دهد‪،‬‬
‫– هرگونه تغییر در پارامتر منجر به تغییر در مقدار متغیر اصلی نمی‌شود‪،‬‬
‫– از اثرات جانبی ناخواسته جلوگیری می‌کند‪،‬‬
‫• فراخوانی با ارجاع‬
‫– توابع می‌توانند به صورت مستقیم به داده‌ها دسترس ی داشته باشند‪،‬‬
‫– تغییرات در داده اصلی اعمال می‌شوند‪.‬‬
‫‪124‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
‫ارجاع و پارامترهای ارجاعی (ادامه)‬
‫• پارامترهای ارجاعی‬
‫– مانند این است که نام پارامتر را عوض کرده‌ایم!‬
‫• پارامتر را با ارجاع پاس می‌دهد‪،‬‬
‫– در نمونه اولیه‪ ،‬بعد از نوع داده از عملگر & استفاده می‌شود‪،‬‬
‫) ‪• void myFunction( int &data‬‬
‫• در این تعریف‪ data ،‬ارجاعی به یک متغیر از نوع داده صحیح است!‬
‫– هیچ تغییری در نحوه فراخوانی تابع ایجاد نمی‌شود‪،‬‬
‫• اما‪ ،‬مقدار اصلی می‌تواند تغییر کند!‬
‫‪125‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
126
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Fig. 3.20: fig03_20.cpp
// Comparing pass-by-value and pass-by-reference
// with references.
#include <iostream>
using std::cout;
using std::endl;
int squareByValue( int );
void squareByReference( int & );
Notice the & operator,
indicating pass-by-reference.
// function prototype
// function prototype
int main()
{
int x = 2;
int z = 4;
// demonstrate squareByValue
cout << "x = " << x << " before squareByValue\n";
cout << "Value returned by squareByValue: "
<< squareByValue( x ) << endl;
cout << "x = " << x << " after squareByValue\n" << endl;
Ali Shakiba – http://shakiba.id.ir
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// demonstrate squareByReference
cout << "z = " << z << " before squareByReference" << endl;
squareByReference( z );
cout << "z = " << z << " after squareByReference" << endl;
return 0; // indicates successful termination
} // end main
Changes number, but
original parameter (x) is not
squareByValue multiplies number by itself, stores the
modified.
result in number and returns the new value
of number
//
//
int squareByValue( int number )
{
return number *= number; // caller's argument not modified
} // end function squareByValue
Changes numberRef, an
// squareByReference multiplies numberRef by itself and
alias for the original
// stores the result in the variable to which numberRef
parameter. Thus, z is
// refers in function main
changed.
void squareByReference( int &numberRef )
{
numberRef *= numberRef;
// caller's argument modified
} // end function squareByReference
127
Ali Shakiba – http://shakiba.id.ir
x = 2 before squareByValue
Value returned by squareByValue: 4
x = 2 after squareByValue
z = 4 before squareByReference
z = 16 after squareByReference
128
Ali Shakiba – http://shakiba.id.ir
‫ارجاع و پارامترهای ارجاعی (ادامه)‬
‫• می‌توان از ارجاعات برای تغییر نام متغیرها در طول برنامه استفاده‬
‫کرد!‬
‫– به یک متغیر یکسان اشاره می‌کند‪،‬‬
‫– نمی‌توان از آن در یک تابع استفاده کرد!‬
‫‪int count = 1; // declare integer variable count‬‬
‫‪Int &cRef = count; // create cRef as an alias for count‬‬
‫)‪++cRef; // increment count (using its alias‬‬
‫• ارجاعات باید در هنگام تعریف شدن‪ ،‬حتما مقدار دهی اولیه شوند!‬
‫‪129‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
// Fig. 3.21: fig03_21.cpp
// References must be initialized.
#include <iostream>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
130
x
y
x
y
using std::cout;
using std::endl;
int main()
{
int x = 3;
y declared as a reference to x.
// y refers to (is an alias for) x
int &y = x;
cout << "x = " << x << endl << "y = " << y << endl;
y = 7;
cout << "x = " << x << endl << "y = " << y << endl;
return 0;
} // end main
=
=
=
=
3
3
7
7
Ali Shakiba – http://shakiba.id.ir
// indicates successful termination
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Fig. 3.22: fig03_22.cpp
// References must be initialized.
#include <iostream>
using std::cout;
using std::endl;
int main()
{
int x = 3;
int &y;
Uninitialized reference –
compiler error.
// Error: y must be initialized
cout << "x = " << x << endl << "y = " << y << endl;
y = 7;
cout << "x = " << x << endl << "y = " << y << endl;
return 0;
// indicates successful termination
} // end main
Borland C++ command-line compiler error message:
Error E2304 Fig03_22.cpp 11: Reference variable 'y' must be
initialized in function main()
Microsoft Visual C++ compiler error message:
D:\cpphtp4_examples\ch03\Fig03_22.cpp(11) : error C2530: 'y' :
131
references must be initialized
Ali Shakiba – http://shakiba.id.ir
‫پارامترهای پیش‌فرض‬
‫• فراخوانی توابع بدون ارسال برخی از پارامترها‬
‫– اگر تعداد پارامترهای ارسال شده کمتر از تعداد تعریف شده در امضای‬
‫تابع باشد‪ ،‬پارامترهای سمت راست‪ ،‬مقادیر پیش فرض را اختیار می‌کنند‪،‬‬
‫– مقادیر پیش فرض‬
‫• ثوابت‪ ،‬متغیرهای عمومی و فراخوانی سایر توابع!‬
‫;) ‪int myFunction( int x = 1, int y = 2, int z = 3‬‬
‫)‪– myFunction(3‬‬
‫)‪• x = 3, y and z get defaults (rightmost‬‬
‫)‪– myFunction(3, 5‬‬
‫‪• x = 3, y = 5 and z gets default‬‬
‫‪132‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
133
// Fig. 3.23: fig03_23.cpp
// Using default arguments.
#include <iostream>
using std::cout;
using std::endl;
Set defaults in function
prototype.
// function prototype that specifies default arguments
int boxVolume( int length = 1, int width = 1, int height = 1 );
int main()
{
// no arguments--use default values for all dimensions
cout << "The default box volume is: " << boxVolume();
// specify length; default width and height
cout << "\n\nThe volume of a box with length 10,\n"
<< "width 1 and height 1 is: " << boxVolume( 10 );
// specify length and width; default height
cout << "\n\nThe volume of a box with length 10,\n"
<< "width 5 and height 1 is: " << boxVolume( 10, 5 );
Ali Shakiba – http://shakiba.id.ir
Function calls with some
parameters missing – the
rightmost parameters get their
defaults.
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// specify all arguments
cout << "\n\nThe volume of a box with length 10,\n"
<< "width 5 and height 2 is: " << boxVolume( 10, 5, 2 )
<< endl;
return 0;
// indicates successful termination
} // end main
// function boxVolume calculates the volume of a box
int boxVolume( int length, int width, int height )
{
return length * width * height;
} // end function boxVolume
The default box volume is: 1
The volume of a box with length 10,
width 1 and height 1 is: 10
The volume of a box with length 10,
width 5 and height 1 is: 50
134
The volume of a box with length 10,
width 5 and height 2 is: 100
Ali Shakiba – http://shakiba.id.ir
‫عملگر ‪::‬‬
‫• عملگر یکانی واضح سازی قلمرو )‪(::‬‬
‫– در صورتی که یک متغیر هم‌نام محلی داشته باشیم‪ ،‬دسترس ی به متغیر‬
‫عمومی با همان نام را فراهم می‌کند‪،‬‬
‫– در صورتی که نام‌ها متفاوت باشند‪ ،‬نیازی به استفاده از آن نیست!‬
‫– به صورت ‪ ::variable‬استفاده می‌شود‪:‬‬
‫;‪• y = ::x + 3‬‬
‫‪135‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
1
// Fig. 3.24: fig03_24.cpp
2
// Using the unary scope resolution operator.
3
#include <iostream>
4
5
using std::cout;
6
using std::endl;
7
8
#include <iomanip>
9
10 using std::setprecision;
Access the global PI with
11
::PI.
12 // define global constant PI
13 const double PI = 3.14159265358979;
Cast the global PI to a
14
15 int main()
float for the local PI. This
16 {
example will show the
17
// define local constant PI
difference between float
18
const float PI = static_cast< float >( ::PI );
and double.
19
20
// display values of local and global PI constants
21
cout << setprecision( 20 )
22
<< " Local float value of PI = " << PI
23
<< "\nGlobal double value of PI = " << ::PI << endl;
24
136
25
return 0; // indicates successful termination
Ali Shakiba – http://shakiba.id.ir
26
27
} // end main
Borland C++ command-line compiler output:
Local float value of PI = 3.141592741012573242
Global double value of PI = 3.141592653589790007
Microsoft Visual C++ compiler output:
Local float value of PI = 3.1415927410125732
Global double value of PI = 3.14159265358979
137
Ali Shakiba – http://shakiba.id.ir
‫سربارگذاری توابع‬
‫• سربارگذاری توابع‬
‫– توابع با نام یکسان‪ ،‬اما پارامترهای متفاوت‪،‬‬
‫– وظیفه یکسانی را انجام می‌دهند‪،‬‬
‫• برای مثال‪ ،‬تابعی برای محاسبه مجذور ‪ int‬و ‪ float‬به صورت جداگانه‪:‬‬
‫};‪int square( int x) {return x * x‬‬
‫} ;‪float square(float x) { return x * x‬‬
‫• توابع سربارگذاری شده را با امضایشان از هم تشخیص می‌دهند!‬
‫– بنابراین‪ ،‬تعریف دو تابع با امضای یکسان‪ ،‬اما متفاوت در نوع داده‬
‫بازگشتی‪ ،‬مجاز نیست!‬
‫‪138‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Fig. 3.25: fig03_25.cpp
// Using overloaded functions.
#include <iostream>
using std::cout;
using std::endl;
Overloaded functions have
the same name, but the
different parameters
distinguish them.
// function square for int values
int square( int x )
{
cout << "Called square with int argument: " << x << endl;
return x * x;
} // end int version of function square
// function square for double values
double square( double y )
{
cout << "Called square with double argument: " << y << endl;
return y * y;
} // end double version of function square
139
Ali Shakiba – http://shakiba.id.ir
24
25
26
27
28
29
30
31
32
33
34
35
int main()
{
int intResult = square( 7 );
// calls int version
double doubleResult = square( 7.5 ); // calls double version
cout << "\nThe square of integer 7 is " << intResult
The proper function is called
<< "\nThe square of double 7.5 is " << doubleResult
based upon the argument
<< endl;
(int or double).
return 0;
// indicates successful termination
} // end main
Called square with int argument: 7
Called square with double argument: 7.5
The square of integer 7 is 49
The square of double 7.5 is 56.25
140
Ali Shakiba – http://shakiba.id.ir
141
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Fig. 3.26: fig03_26.cpp
// Name mangling.
// function square for int values
int square( int x )
{
return x * x;
}
// function square for double values
double square( double y )
{
return y * y;
}
// function that receives arguments of types
// int, float, char and int *
void nothing1( int a, float b, char c, int *d )
{
// empty function body
}
Ali Shakiba – http://shakiba.id.ir
23
24
25
26
27
28
29
30
31
32
33
34
// function that receives arguments of types
// char, int, float * and double *
char *nothing2( char a, int b, float *c, double *d )
{
return 0;
}
int main()
{
return 0;
} // end main
_main
@nothing2$qcipfpd
@nothing1$qifcpi
@square$qd
@square$qi
142
Ali Shakiba – http://shakiba.id.ir
// indicates successful termination
Mangled names produced in
assembly language.
$q separates the function
name from its parameters. c
is char, d is double, i is
int, pf is a pointer to a
float, etc.
1
// Fig. 3.27: fig03_27.cpp
2
// Using a function template.
3
#include <iostream>
4
5
using std::cout;
6
using std::cin;
Formal type parameter T
7
using std::endl;
placeholder for type of data to
8
tested by maximum.
9
// definition of function templatebemaximum
10 template < class T > // or template < typename T >
11 T maximum( T value1, T value2, T value3 )
12 {
13
T max = value1;
maximum expects all
14
parameters to be of the same
15
if ( value2 > max )
16
max = value2;
type.
17
18
if ( value3 > max )
19
max = value3;
20
21
return max;
22
23 } // end function template maximum
143
24
Ali Shakiba – http://shakiba.id.ir
144
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
int main()
{
// demonstrate maximum with int values
int int1, int2, int3;
cout << "Input three integer values: ";
cin >> int1 >> int2 >> int3;
// invoke int version of maximum
cout << "The maximum integer value is: "
<< maximum( int1, int2, int3 );
// demonstrate maximum with double values
double double1, double2, double3;
cout << "\n\nInput three double values: ";
cin >> double1 >> double2 >> double3;
// invoke double version of maximum
cout << "The maximum double value is: "
<< maximum( double1, double2, double3 );
Ali Shakiba – http://shakiba.id.ir
maximum called with various
data types.
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// demonstrate maximum with char values
char char1, char2, char3;
cout << "\n\nInput three characters: ";
cin >> char1 >> char2 >> char3;
// invoke char version of maximum
cout << "The maximum character value is: "
<< maximum( char1, char2, char3 )
<< endl;
return 0;
// indicates successful termination
} // end main
Input three integer values: 1 2 3
The maximum integer value is: 3
Input three double values: 3.3 2.2 1.1
The maximum double value is: 3.3
145
Input three characters: A C B
The maximum character value is: C
Ali Shakiba – http://shakiba.id.ir
‫مراجع‬
‫• مراجع درس‪:‬‬
‫– جعفرنژاد قمی‪ ،‬عین ا‪...‬؛ برنامه نویس ی به زبان ‪C++‬؛ انتشارات علوم‬
‫رایانه؛ ویراست چهارم؛ ‪.1391‬‬
‫– جعفرنژاد قمی‪ ،‬عین ا‪ ...‬و کریم‌پور‪ ،‬انیس؛ مبانی کامپیوتر و الگور‌یتم‌ها؛‬
‫انتشارات علوم رایانه؛ ویراست دوم؛ ‪.1391‬‬
‫• برای آماده‌سازی مطالب و اسالیدها از مراجع زیر نیز استفاده‬
‫کرده‌ام‪:‬‬
‫‪– Deitel, P.J. and Deitel, H.M.; C++: How to‬‬
‫‪program; Prentice-Hall; Fifth Edition; 2005.‬‬
‫‪146‬‬
‫‪Ali Shakiba – http://shakiba.id.ir‬‬
147
Ali Shakiba – http://shakiba.id.ir

similar documents