Professional Documents
Culture Documents
استاد:
دکتر باباگلی
تهیه و تنظیم:
بردیا سهامی
ویراست 1
0
فهرست مطالب:
مقدمه
مفاهیم اولیه
ساختارهای کنترلی
حلقه
توابع
آرایه
1
مقدمه
جزوه در دست شما حاصل ساعت ها تالش جهت گردآوری مطالب میباشد .پیشنهاد
میگردد این جزوه را در کنار کتاب برنامه نویسی به زبان ( C++دایتل و دایتل)
مطالعه کنید .امیدواریم این جزوه به درک مطالب درس کمک کند.
مثال های متنوعی در این جزوه وجود دارد که سواالت ساده با یک ستاره ،سواالت
متوسط با دو ستاره و سواالت سخت با سه ستاره مشخص شده اند.
در صورت مشاهده هرگونه مشکل ،خواهشمندیم ایرادات را به ایمیل زیر ارسال
Bardia_Sahami@yahoo.com فرمایید:
2
فصل - 1مفاهیم اولیه
در دنیای برنامهنویسی ،زبانهای برنامهنویسی به سه دسته زبان سطح پایین ،سطح
متوسط و سطح باال دسته بندی میشوند .زبان های سطح پایین نزدیکتر به زبان
ماشین ( 0و )1میباشد و هرچه باالتر میرویم ،زبان های برنامهنویسی بیشتر شبیه
به زبان گفتاریمان میشوند .زبان سطح پایین مانند زبان اسمبلی ،سطح متوسط
مانند سی و سی پالس پالس و زبان سطح باال مثل پایتون .زبان سی پالس پالس
توسعه یافته زبان سی بوده و یکی از زبان های معروف میباشد.
از این حرفها که بگذریم ،میخواهیم نگاهی به ساده ترین برنامه بیندازیم.
>#include <iostream
{ )( int main
;return 0
}
!Hello world
همانطور که می بینید ،این برنامه ،عبارت ! Hello worldرا چاپ میکند .حال به
اجزا آن میپردازیم .زبان سی پالس پالس کدها را خط به خط چک و اجرا میکند و
به خط بعدی میرود .در خط اول عبارت > #include <iostreamرا میبینیم.
در سی پالس پالس ،کتابخانه های پیشفرض و استانداردی وجود دارد که در آنها،
توابع پرکاربرد نوشته شده و در اختیار برنامه نویس قرار گرفتهاند .جهت اضافه کردن
کتابخانهها و استفاده از آنها باید از > #include <Library Nameاستفاده
کنیم iostream .یکی از کتابخانههای پرکاربرد و یکی از مهمترین مسئولیتهای
آن ،چاپ و خواندن مقادیر می باشد.
3
در خط بعدی عبارت ; using namespace stdرا میبینیم که میگوید از
دستورات استاندارد استفاده خواهیم کرد( .همیشه این عبارت را بنویسید).
در خط بعد ،عبارت )( int mainرا می بینیم که یک سری کد در داخل کروشه }{
وجود دارد int main () .تابع اصلی می باشد که کد های اصلی در آن قرار می-
گیرند و اول دستورات این تابع اجرا می شوند.
در خط بعد عبارت ;” cout << “Hello worldرا مشاهده میکنید .برای چاپ
هر متن دلخواه ،از دستور coutاستفاده میکنیم cout .تمام کاراکترهای موجود در
داخل " " را عینا چاپ میکند (مگر در موارد خاص) .عالئم << به معنی چسباندن
کاراکترها به کاراکترهای قبلی میباشد .پس ساختار کلی دستور coutبه شکل زیر
است:
4
در آخر نیز عبارت ; return 0را می بینیم return 0 .بدین معناست که اگر
برنامه به درستی اجرا شود ،تابع mainمقدار صفر را برمیگرداند که به معنای
اجرای صحیح برنامه میباشد.
توجه :سی پالس پالس به کوچک و بزرگ بودن حروف حساس است .بطور
مثال ،استفاده از Coutبجای coutموجب خطا می شود.
نکته :فعال به یاد داشته باشید که در انتهای هر خط از کد باید ; قرار دهید
مگر آنکه کروشه باشد ،یا کامنت باشد ،یا آن خط با #شروع شده باشد.
کامنت گذاری یکی ازکارهای مهم جهت قابل فهم تر کردن برنامه و ساختار ،و قابل
درک کردن آن برای دیگر برنامه نویسان می باشد .سی پالس پالس کامنت ها را در
نظر نگرفته و از آنها می گذرد .برای نوشتن کامنت ،دو راه وجود دارد .یک استفاده
از .//دو استفاده از * /و .*/از //برای کامنت کردن یک خط استفاده می شود
که نوشته های بعد //کامنت می شوند و نوشته های قبل از آن در آن خط اجرا می
شوند .از *( /آغاز) و ( */پایان) برای کامنت گذاشتن یک بلوک یا یک خط استفاده
می شود.
>#include <iostream
{ )( int main
;return 0
}
5
شاید تا االن برایتان پیش آمده است که چگونه می توان در هنگام چاپ کردن یک
متن به خطوط بعدی رفت .در اینجا به چند دنباله گریزها یا Scape Sequences
میپردازیم .دنباله گریزها در داخل خود "" استفاده میشوند و از جمله مواردی
هستند که سی پالس پالس آنها را عینا چاپ نکرده ،بلکه نوعی دستور هستد.
همانطور که گفته شد ،دنباله گریزها در داخل " " قرار داده می شوند.
>#include <iostream
{ )( int main
;return 0
}
Welcome
to
! C++
6
اما از آنجایی که دنباله گریز \nبسیار کاربردی میباشد ،دستوری به نام endlبا
همان کاربرد است اما خارج از گیومه استفاده میشوند .مثال قبل را می توان به
روش زیر نوشت:
<< cout << “Welcome” << endl << “to” << endl << endl
;”!“C++\t
پس ساختار کلی coutرا می توان به شکل زیر نوشت:
;cout << “String1 \n\t\a…” << “String2 \n\t\a…” << … << endl
7
نکته :نام یک متغیر نباید با عدد شروع شود.
;VariableType VariableName
یا
>#include <iostream
{ )( int main
;age = 27
;return 0
}
;int age
;age = 27
نوشت:
>#include <iostream
{ )( int main
;int age
;return 0
}
حال برنامه منتظر می ماند کاربر عددی وارد کند .مثال کاربر عدد 30را وارد میکند.
خروجی به شکل زیر در خواهد آمد(مقادیری که کاربر وارد میکند با | شروع شده):
9
|30
اگر چند متغیر ،مثال به نام ها b ،aو cداشتید و میخواهید به ترتیب مقادیر آنها
را از کاربر بخوانید ،به روش یکی از روش های زیر میتوانید عمل کنید:
10
نکته :اگر عددی اعشاری به متغیری از نوع intنسبت داده شود ،اعشار آن
حذف شده و فقط قسمت صحیح آن ذخیره می شود .و بلعکس اگر به
متغیری از نوع doubleیا ،floatعددی صحیح نسبت داده شود ،نوع متغیر
آنها به intتغییر پیدا می کند.
نکته :تقسیم دو عدد صحیح همواره عددی صحیح خواهد بود .اگر در
تقسیمی ،حداقل یکی از عناصر اعشاری باشد ،حاصل تقسیم عددی اعشاری
خواهد بود.
>#include <iostream
{ )( int main
;int1 = 3/2
;int2 = 3/2.0
;double1 = 3/2
“ = cout << “int1 = “ << int1 << “\nint2 = “ << int2 << “\ndouble1 = “ << double1 << “\ndouble2
;<< doubel2
;return 0
}
int1 = 1
int2 = 1
double1 = 1
double2 = 1.5
11
همانطور که مشاهده میکنید ،در 3 int1و 2هر دو مقداری صحیح هستند و
حاصل تقسیم آنها مقداری صحیح بوده و عدد 1در int1ذخیره میشود.
در ،int2یکی از عوامل تقسیم عددی اعشاریست و حاصل تقسیم 1.5میشود ،اما
چون متغیر ،int2از نوع intمیباشد ،مقدار اعشار آن حذف شده و مقدار 1در
int2ذخیره میشود.
در 3 ،double1و 2هر دو مقداری صحیح هستند و حاصل تقسیم آنها مقداری
صحیح بوده و عدد صحیح 1در double1ذخیره میشود .چون double1عددی
صحیح به آن نسبت داده شده است ،به نوع intتغییر میکند.
در ،double2یکی از عوامل تقسیم عددی اعشاری است و حاصل تقسیم 1.5می-
شود ،و چون double2نیز یک متغیر اعشاریست ،مقدار 1.5در این متغیر ذخیره
میشود.
12
حال به یک مثال ساده دیگر میپردازیم که دو عدد صحیح از کاربر گرفته و مجموع
آنها را نشان میدهد.
>#include <iostream
{ )( int main
;int a, b, sum
;sum = a + b
;return 0
}
حال بطور مثال اگر کاربر عداد 2و 3را وارد کند ،داریم:
Enter a:
|2
Enter b:
|3
2+3=5
همانطور که میبینید ،مقادیر aو bاز کاربر خوانده شده و حاصل جمع آنها در
متغیری به نام sumذخیره میشود ،و سپس مقدار sumرا نمایش میدهیم .البته
بدون متغیر sumهم این کار را انجام داد .متغیر sumرا حذف کرده و خط cout
را بصورت زیر بازنویسی میکنیم.
13
و نتیجه ای مشابه حاصل میشود .پس میتوان بعد از عالئم << در دستور ،cout
یک عبارت ریاضی نیز نوشت.
از اعمال ریاضی میتوان به جمع ( ،)+تفریق ( ،)-ضرب (*) ،تقسیم ( )/و پیمانه یا
باقیمانده ( )%اشاره کرد .برای اولویت دهی به اعمال ریاضی از پرانتز استفاده می
شود.
با توابع ریاضی نیز در فصل های آینده آشنا خواهید شد.
حال میخواهیم به بحث ثابت ها بپردازیم .ممکن است در برنامهتان ،بخواهید از
عددی استفاده کنید که قرار نیست در برنامه تغییر کند .به بیانی دیگر ،این عدد
ثابت خواهد ماند .برای ساخت ثابت ( )constantدو روش وجود دارد:
14
نکته :هنگام ساخت ثابت ،بالفاصله باید مقداردهی شوند و نمیتوان آنها را
رها کرد.
توجه :اگر متغیری هنوز وجود داشته باشد ،نمی توان دوباره متغیر با همان
نام ساخت و موجب ارور می شود.
در برنامه زیر ،به ساخت متغیر و ثابت های جهانی و محلی می پردازیم:
>#include <iostream
{ )( int main
;return 0
}
در آخر هم به مطلب castingمیپردازیم که در فصل های آتی مورد نیاز میباشند.
Castکردن به معنای تبدیل یک متغیر یا یک ثابت از یک نوع به نوع دیگر
(بصورت موقت) .برای اینکار از پرانتز و داخل پرانتز نوع مورد نظر و بعد از پرانتز نام
متغیر را مینویسیم Casting .تنها در همان خط بصورت موفت اجرا میشود و از
آن خط به بعد ،به حالت اول بر میگردد.
ساختار :casting
(Goal VariableType)VariableName
15
گفته شد هر متغیر charیک کاراکتر را در خود نگه میدارد .اعدادی از -128تا
127به هر کاراکتر نسبت داده میشود .مثال عدد نسبت داده شده به کاراکتر 97 ،a
می باشد ،یا عدد نسبت داده شده به کاراکتر @ ،عدد 40می باشد .حال می
خواهیم برنامهای بنویسیم که یک کاراکتر از کاربر خوانده و عدد متناظر با آن با
نشان دهد.
>#include <iostream
{ )( int main
;char n
;int a
;return 0
}
Enter a character:
*|
52
با جستجو در گوگل ،می توانید کدهای نسبت داده شده به کاراکترها را مشاهده
کنید (.)ASCII Table
در آخر این فصل هم ،اشاره ای می کنیم به روش خالصه تر عملیات ریاضی .بطور
مثال a = a * n ،a = a + n ،و ..را میتوان به شکل ،a*=n ،a -=n ،a +=n
a /= nو a %=nنشان داد .به دلیل کاربرد زیاد ،a = a + 1و ،a = a – 1این دو
16
را به صورت a++یا ++aو a--یا --aنیز نشان میدهند .تفاوت a++و ++aبدین
معناست که در a++اول عملیات کلی صورت می گیرد و سپس عملیت جمع بعالوه
یک ،اما در ++aاول aبا 1جمع می شود و سپس دیگر دستورات اجرا می شوند.
مثال اگر a = 5باشد ،در ،b = a++مقادیر نهایی aو 6 bو 5اما در
،b = ++aمقادیر نهایی 6 aو 6 bمی شود.
17
تمرین ها
* :1-1با فرض آنکه امسال سال 2020است ،برنامه ای بنویسید که سن کاربر
دریافت کند و پس از دریافت عدد ،بوق سیستم به صدا در آید و سپس سال تولد
میالدی کاربر را چاپ کند.
* :1-2برنامه ای بنویسید که دو عدد aو bرا از کاربر خوانده ،سپس حاصل
باقیمانده aبر bرا به توان دو رسانده و پس حاصل به اضافه 5را در پیمانه 10
حساب کرده و سپس حاصل را نشان دهد.
* :1-3برنامه ای بنویسید که قدر نسبت ،dتعداد nو جمله اول a0را دریافت
کرده و مجموع کل عناصر دنباله حسابی را نمایش دهد.
*
* *
* *
* *
*
* :1-7برنامه ای بنویسید که روز و ماه تولد را بصورت عددی 4رقمی وارد کرده و
ماه و روز تولد را جدا کرده و به شکل روبرو نمایش دهدMah: ab Saal: cd :
18
فصل - 2ساختارهای کنترلی
تا اینجا با مفاهیم اولیه زبان سی پالس پالس آشنا شدهایم .حال میخواهیم به
عملگرهای مقایسه بپردازیم .از فصل قبل به یاد دارید که صفر به معنای نادرست و
یک به معنای درست است .عملگرها مقایسه:
:== .1برابر
:!= .2نابرابر
:|| .5یا ریاضی – برای دو عبارت شرطی ،حداقل یکی از شرط ها درست باشند
نکته :برای نشان دادن بازه نمیتوان ،بطور مثال ،از 1 < a < 5استفاده کرد.
بجای آن باید از "یا" و "و" ریاضی استفاده کردa > 1 && a < 5 .
توجه :گذاشتن فاصله در داخل این عملگرها (مثال نوشتن = ! بجا =!) سبب
خطا میشود.
{ )If (Condition
;Codes
}
19
ساختار کلی دستور ifبدین صورت است .اگر شرط موجود در پرانتز درست (یک)
باشد ،کد داخل بلوک ifاجرا شده و اگر شرط موجود در پرانتز نادرست (صفر) باشد،
دستورات موجود در بلوک ifاجرا نمیشود و سی پالس پالس از آن میگذرد.
توجه :نوشتن عملگر انتساب (=) بجای عملگر مقایسه (==) سبب خطای
منطقی می شود.
توجه :گذاشتن ; بعد از پرانتز دوم ،ifسبب خطای منطقی شده و در هیچ
حالتی دستورات موجود در بلوک ifاجرا نمیشود.
با ساختار ifآشنا شدید و گفته شد اگر شرط درست باشد ،دستورات اجرا شده
وگرنه ،سی پالس پالس از آن گذشته و اتفاقی نمی افتد .اما اکثر اوقات نیاز است که
در صورت نادرست بودن شرط ،کدی دیگر اجرا شود .در اینجا از از ساختار else
استفاده می شود ،که در صورت اجرا نشدن ifقبلی ،اجرا خواهد شد.
{ )If (Condition
;Codes
{ } else
;Codes
}
20
برای فهم بیشتر ،به برنامه زیر که فرد یا زوج بودن عدد وارد شده را بررسی میکند،
دقت کنید.
>#include <iostream
{ )( int main
;int a
{ )if (a % 2 == 0
{ } else
}
;return 0
}
|7
FARD
برای مثال ،زمانی که کاربر عدد 7را وارد میکنید ،اول عدد 7در متغیر aذخیره
میشود .سپس حاصل باقیمانده تقسیم 7به 2را در شرط ifحساب میکند .چون
باقیمانده 1شده است و برابر با 0نیست ،دستور ifاجرا نمی شود .و چون دستور if
اجرا نشده است ،دستور elseاجرا می شود .اما اگر عددی مثل 4وارد می شد،
چون حاصل تقسیمش بر 2صفر بوده و شرط ifدرست می شد ،بلوک دستورات if
اجرا می شد ،و به علت اجرا شدن دستورات ،ifدیگر elseاجرا نمیشد.
تا اینجای کار با شرایطی که دو حالت دارند آشنا شدید و آموختید که به کمک ifو
elseمیتوان این دو حالت را بررسی کنید .اما برای مواقعی که سه یا بیشتر حالت
وجود دارد ،باید چه کرد؟ در این شرایط ،از ساختار else-ifاستفاده میکنیم که به
21
کمکش ،می توانیم شرایطی که بیشتر از 2حالت برایشان امکان دارند را بررسی
کنیم:
22
>#include <iostream
{ )( int main
;double a
{ )} else if (a >= 10 )// Or (a >= 10) && (a < 17
{ } else
}
;return 0
}
|12
Passed
گاهی نیاز است که چند شرط مختلف را بررسی کنیم .در این صورت از به روش
درختی ،النهای یا Nested ifsاستفاده میشود .روش همان روش قبلیست ،اما
چند ifتو در تو داریم.
بعضی اوقات ،تعداد ifها بسیار زیاد میشود .در صورتی که مقادیر مورد بحث،
مقادیری گسسته باشند ،می توان از ساختار switchاستفاده کرد که عملکردی
مشابه ifدارد اما کمی خالصهتر است .از switchبرای مقادیر پیوسته (مثل بازه
نمرات در مثال قبلی) نمی توان استفاده کرد (یا اینکه بسیار دشوار می شود).
ساختار switchبصورت زیر است:
{ )switch (Expression
case Condition1:
;Codes
;break
case Condition2:
;Codes
;break
…
24
case ConditionN:
;Codes
;break
default:
;Codes
}
برای درک بهتر ،مثال زوج یا فرد بودن را با Switchپیاده سازی میکنیم.
>#include <iostream
{ )( int main
;int a
{ )switch (a
case 0:
;break
case 1:
;break
}
;return 0
}
26
تمرین ها
* :2-1برنامه ای بنویسید که دو عدد بگیرد و بگوید آیا اولی مضربی از دومی است
یا خیر.
* :2-2برنامه ای بنویسید که 5عدد بگیرد و کوچک ترین و بزرگ ترین آنها را چاپ
کند.
* :2-3برنامه ای بنویسید که 3عدد اعشاری b ،aو cرا از یک معادله درجه دو
بگیرد و ریشه های آن معادله را بیابد.
* :2-4مسعود نوجوان درشتی است و قد و وزن اون زیاد است .بهخاطر همین
همیشه برای عبور از درها با چالش روبرو است (معموال درهایی که ارتفاعشان بلند
است ،عرض کوچکی دارند و درهایی که عرضشان بزرگ است ،ارتفاع کوتاهی
دارند).حال مسعود میخواهد خانه بخرد و از صاحبخانه اندازهی عرض و ارتفاع در
ورودی خانه را گرفته است و میخواهد بداند که آیا میتواند از در خانه عبور کند یا
نه و برای حل این مسئله از شما کمک میخواهد .دقت کنید که مسعود همیشه
صاف وارد خانه میشود و به هیچوجه برای رد شدن از در ،انعطافی از خود نشان
نمیدهد .اگر می توانند از درب در شوند YES ،و در غیر این صورت کلمه NOرا
چاپ کند( .کوئرا کالج)
** :2-5سه ظرف خیلی بزرگ داریم که در ابتدا به ترتیب در آنها a ,b ,cلیتر
شیر وجود دارد .در هرگام می توانیم دو ظرف انتخاب کرده و مقداری شیر (می
تواند این مقدار اعشاری هم باشد) از یک ظرف به ظرف دیگر منتقل کنیم (از
آنجایی که ظرفها خیلی بزرگ هستند و ما نیز خیلی حواسجمع هستیم ،حتی
یک قطره شیر نیز هدر نمیرود و همهی آن داخل ظروف باقی میماند).
27
هدف برابر کردن مقدار شیر در هر سه ظرف است ،کمینه تعداد حرکات الزم را در
خروجی چاپ کنید .سه عدد به شما داده می شود که بیانگر مقدار شیر هر ظرف
است .در تنها خط خروجی کمینه تعداد گام های الزم برای برابر کردن مقدار شیر
در هر سه ظرف را چاپ کنید( .کوئرا کالج)
* :2-6برنامه ای بنوسید که کاربر با وارد کردن شماره صندلی و ردیف ،بگوید که
اول باید کاربر در سالن به راست حرکت یا چپ .سپس بگوید کاربر باید چند دریف
به پایین رود و چند صندلی باید طی کند تا به صندلی خودش برسد .اگر صندلی 1
تا 10بود ،کاربر از راست (راست کاربر) و اگر از 11تا 20بود از چپ برود( .کوئرا
کالج)
** :2-6برنامه ای بنویسید که کاربرد طول و عرض رئوس یک مستطیل افقی در
صفحه دکارتی را به شما بدهد ،و برنامه طول و عرض گوشه چهارم را نمایش دهد.
28
*** :2-7بعد از مدتها که لیته توانست با فیته تماس بگیرد و قرار بگذارند .لیته
در نقطه aشهر زندگی میکند و فیته نقطه bرا برای اولین قرار انتخاب کردهاست.
نوع اول :نقطه xو x + 1را با یک مسیر دو طرفه به هم متصل میکند( .به
ازای هر xصحیح)
هم چنین میدانیم فاصله طی کردن یک مسیر بین دو نقطه به ازای هرنوع قطار
دقیقا یک دقیقه است .وظیفه شما به عنوان دوست و رفیق لیته این است که به او
بگویید زودترین زمان ممکن رسیدن لیته به محل قرار چقدر است .سه عدد صحیح
b ،aو kدر ورودی داده می شود( .کوئرا کالج)
29
: مشکل(ها) قطعه برنامه رو بگویید:2-10*
30
فصل – 3حلقه ها
بعضی اوقات نیاز است کاری را بصورت پشت سر هم انجام دهید .مثال می خواهید
اعداد یک تا هزار را چاپ کنید .واضح است نوشتن دستور coutبرای هر عدد کاری
طاقت فرساست و بسیار زمان گیر است .بدین منظور ،استفاده از حلقه های تکرار
کار ما را بسیار آسان میکنند .در سی پالس پالس چند نوع حلقه تکرار همچون
do-while ،while ،forو foreachوجود دارد که در اینجا سه مورد اول را
معرفی میکنیم.
در آغاز با حلقه تکرار whileشروع میکنیم .همانطور که از فصلهای قبلی به یاد
دارید a++ ،برابر a = a + 1است .ساختار کلی whileبصورت زیر است:
{ )while (Condition
;Codes
}
نحوه کار حلقه whileبدین صورت است که اول شرط آن بررسی میشود .سپس
وارد حلقه شده و دستورات موجود در آن اجرا میشود .پس از انجام دستورات،
دوباره به شرط بر میگردد و دوباره شرط را بررسی میکند .اگر درست بود ،دوباره
دستورات اجرا میشوند .این کار تا جایی پیش میرود که شرط حلقه نادرست شود.
در این صورت دیگر دستورات اجرا نشده و سی پالس پالس از این حلقه میگذرد و
کدهای بعدی را اجرا میکند.
در مورد حلقهها ،دو دستور مهم وجود دارد که یکی از آن ها را در فصل قبلی
دیدید .اولی breakو دومی continueاست .زمانی که می خواهید یک حلقه به
پایان رسد و دیگر اجرا نشود ،از دستور breakاستفاده میشود .زمانی که بخواهیم
31
که بعضی از دستورات اجرا نشوند ،از continueاستفاده می شود .با این دو
دستور مهم در مثال های آتی بیشتر آشنا می شوید.
>#include <iostream
{ )( int main
;int i = 1
;i++
}
;return 0
}
به کمک حلقه تکرار ،whileتوانستیم اعداد یک تا هزار را بسادگی چاپ کنیم.
روش کار این برنامه بدین صورت است که نخست شرط iکوچکتر از 1000بررسی
میشود .از آنجایی که iبرابر یک و کوچکتر از هزار است ،وارد حلقه شده و iچاپ
می شود .سپس یک واحد به iاصافه میشود و iمیشود .2سپس دوباره شرط
بررسی میشود .چون 2کوچکتر از 1000است ،وارد حلقه شده و عدد 2نیز چاپ
میگردد .سپس یک واحد به iاضافه شده و مقدار آن 3میشود .این کار همینطور
پیش میرود و اعداد چاپ میشوند .بعد از چندین مرحله 1000 i ،می شود و این
عدد چاپ میشود ،سپس یک واحد به iاضافه میشود و مقدار 1001 iمی شود .در
این حالت شرط حلقه whileدرست نبوده و سپس برنامه از حلقه whileمیگذرد
و برنامه پایان مییابد.
32
حال برای درک بهتر breakو continueبه دو مثال زیر دقت کنید .گفته شد
breakباعث از شکسته شدن حلقه و continueباعث اجرا نشدن بعضی
دستورات در شرایط خاص میباشد.
>#include <iostream
{ )( int main
;int i = 1
{ )if (i == 3
;break
}
;i++
}
;return 0
}
1
2
در این برنامه ،می خواهیم اعداد یک تا پنج را چاپ کنیم .اول عدد یک چاپ می-
شود i .برابر 3نیست ،پس ifاجرا نشده و یک مقدار به آن اضافه میگردد .به همین
صورت برای عدد .2پس از چاپ عدد ،2به iیک مقدار اضافه میشود و مقدارش
برابر 3میشود 3 .هنوز کوچکتر از 5است ،پس دوباره برنامه وارد حلقه میشود.
این بار iبرابر 3است و دستور ifاجرا میشود .دستور breakحلقه را میشکند و
بدین معناست که دستورات داخل حلقه بعد از آن اجرا نمیشوند و برنامه از حلقه
بیرون میآید و ادامه کد ها ،یعنی return 0اجرا شده و برنامه پایان میپذیرد.
33
پس در صورت استفاده از ،breakدستورات داخل حقله بعد از آن اجرا نمیشود و
حلقه پایان مییابد و دستورات بعد از حلقه اجرا می شوند.
>#include <iostream
{ )( int main
;int i = 0
;i++
{ )if (i == 3
;continue
}
}
;return 0
}
1
2
4
5
مانند مثال قبل ،قصد داریم اعداد یک تا 5را چاپ کنیم .بطور مشابه ،اعداد 1و 2
چاپ میشوند .بعد از چاپ عدد ،2مقدار iبرابر 3شده و وارد حلقه میشود ،اما این
بار شرط ifدرست بوده و وارد بلوک ifمیشود .اما این بار بعد آن ،دستور
،continueوجود دارد .این بدین معناست که دستورات بعد ( continueچاپ
34
عدد) اجرا نشده و حلقه برای اعداد بعدی تکرار میشود .در هر دو حالت
continueو ،breakدستورات بعد آنها اجرا نمیشوند ،اما در ،continueفقط
برای یک حالت خاص اجرا نمیشود ولی در ،breakحلقه کال از بین میرود و
برنامه از آن میگذرد.
در این برنامه میخواهیم میانگین معدلهای یک کالس 30نفره را حساب کنیم .اما
برای دانشجویان 15 ،5و 21بعالت اینکه معدلشان بسیار پایین است ،از آنها صرف
نظر خواهیم کرد .بجای ساختن 30متغیر ،می توان تنها با دو سه متغیر و حلقه
تکرار ،این کار را انجام داد.
>#include <iostream
{ )( int main
;i++
;continue
}
cout << sum/27.0; // Or cast it: (double)sum/27; in case sum became integer
;return 0
}
در این برنامه ،ابتدا به کمک حلقه تکرار ،whileنمرات دانشجویان را خوانده و
مجموع آن را در sumذخیره میکنیم .در مورد دانشجویان شماره 15 ،5و ،21
بعلت وجود ،continueدستور بعد ،continueیعنی ; sum +=aاجرا نشده و
معدل های آن سه تاثییری ندارد .وقتی که نمره نفر سی ام نیز دریافت شد ،چون i
35
31می شود ،برنامه از حلقه بیرون آمده و میانگین نهایی را چاپ میکند .از آنجایی
که احتمال دارد مجموع نمرات وارد شده عددی صحیح باشد ،محض احتیاط آن را
تقسیم بر عددی اعشاری میکنیم که حاصل عددی اعشاری شود.
{ do
;Codes
;)} while (Condition
به زبانی دیگر ،ابتدا کد داخل حلقه اجرا شده و سپس شرط حلقه بررسی میگردد.
حال میخواهیم با حلقه forآشنا شویم .به حالت کلی حلقه whileدوباره نگاهی
بیاندازید:
;int counter
{ )while (Condition
;Codes
;counter++
}
این قطعه کد از حلقه whileبرابر با حلقه forاست:
همانطور که میبینید ،در پرانتز حلقه ،forسه جمله وجود دارد .جمله اول می گوید
که شمارنده یا counterات را تعریف کن .جمله سوم میگوید که شمارنده ات قرار
است چگونه حرکت کند .یکی یکی؟ دوتا دوتا؟ و جمله دوم نیز شرط حلقه است.
برای درک بهتر ،می توانید ساختار whileبا forرا در باال مقایسه کنید.
{ )( int main
for (int i = 1; i <= n; i++) { // Creating counter called i and = 1; condition; How counter moves.
;p *= i; // p = p * i
}
;return 0
}
37
|5
از حلقه های تکرار در بعضی از دیگر جاها مانند محاسبه سری نیز میتوان استفاده
کرد که مثال های مربوط به آن در تمرین ها وجود دارد .کلید تسلط بر حلقه ها،
حل مسئله میباشد.
توجه :در پراتنتز مربوط به ،forاز ; باید استفاده شود ،نه .,
>#include <iostream
{ )( int main
;char a
{ )switch (a
case ‘a’:
;aCount++
;break
case ‘b’:
;bCount++
;break
38
case ‘c’:
cCount++;
break;
default:
} // End of loop
return 0;
|a
|b
|b
|a
|c
|d
Invalid character
|c
|a
A: 3
B: 2
C: 2
39
در آخر هم می خواهیم مفاهیم ،long ،unsigned ،signed ،over flowو
shortرا با توجه به اینکه در حل سری ها شاید بکار آید را معرفی میکنیم .در
ابتدا به signedو unsignedمیپردازیم .همانطور که گفتیم ،هر متغیری،
اعدادی مثبت و منفی را میپذیرد ،اما اگر در شرایطی که میدانیم کاربر قرار نیست
عددی منفی وارد کند (مثل سن) ،میتوان هنگام ساخت برنامه ،عبارت unsigned
را به پشت آن اضافه کرد .سپس این متغیر تنها مقادیر نامنفی را ذخیره میکند.
ضمنا اگر متغیر به طور مثال اگر از حدود -32000تا 32000را ذخیره میکرد ،با
unsignedکردن آن ،مقادیر 0تا 64000را میپذیرد.
حال فرض کنید که متغیری داریم که اعداد -128تا 127را در خود ذخیره می
کند .اگر مقدار 127را به این متغیر نسبت دهیم و سپس یک واحد به آن اضافه
کنیم ،چون عدد 128از حجمش بزگتر است overflow ،رخ میدهد و کمترین
مقدار یعنی -128در این متغیر ذخیره میشود .حال فرض کنید اگر مقدار متغیر
127باشد و سپس سه واحد به آن اضافه کنیم ،ابتدا overflowرخ میدهد و
مقدارش -128می شود و سپس بعالوه 2واحد باقیمانده میشود و مقدار نهایی
-126در آن ذخیره میشود.
برای جلوگیری از overflowباید ازمتغیر هایی با حجم باالتر استفاده کرد .بدین
منظور ،برای متغیر های از نوع intمیتوان با استفاده از عبارت های shortو
،longحجم آن را تعیین کرد .بطور مثال در حالت عادی ،حجم 4 intبایت است.
40
متغیر ،short intحجمش 2بایت و long intحجمش 8بایت میباشد که
بیشترین مقدار ممکن برای intاست .برای اعداد اعشاری نیز کوچکترین مقدار
،floatسپس doubleو سپس long doubleمی باشد .دقت کنید short
short double ،doubleو ...وجود ندارند .پس به طور کلی می توان نوشت:
بهتر است در مواقعی که نیاز به ذخیره اعداد صحیح بزرگ داریم ،از long intیا
unsigned long intو برای اعداد اعشاری از long doubleیا unsigned
long doubleاستفاده کنیم( .مانند مثال قبلی درباره محاسبه فاکتوریل)
در آخر هم به یک مثال مهم میپردازیم .در این مثال میخواهیم به کمک حلقه
های تکرار ،یک عدد که نمیدانیم چند رقمیست از کاربر دریافت کنیم و ارقام آن را
جدا کرده و چاپ کنیم.
41
>#include <iostream
{ )( int main
;x = x / 10
}
;return 0
}
|542
2
4
5
به ساختار برنامه باال دقت کنید .در اینجا چون تعداد ارقام را نمیدانیم ،از حلقه
whileاستفاده کردهایم .نخست رقم یکان عدد ،542یعنی 2را به کمک x % 10
چاپ میکنیم .سپس عدد 542را بر 10تقسیم کرده ،حاصل 54.2میشود ،اما
بعلت اینکه متغیر intاست ،به 54تغییر یافته و عدد 54در xذخیره میگردد .عدد
54بزرگتر از صفر بوده و دوباره وارد حلقه میشود .رقم یکان ،54یعنی 4به روش
قبل چاپ میشود .سپس 54دوباره بر 10تقسیم شده و مشابها ،عدد 5ذخیره می-
گردد .هنوز عدد 5بزرگتر از صفر است ،پس دوباره وارد حلقه شده و باقیمانده
تقسیم 5بر ،10یعنی همان 5چاپ میشود .این بار ،در تقسیم عدد 5بر ،10
حاصل 0.5میشود اما بعلت اینکه از متغیر integerاستفاده میکنیم ،مقدار صفر
42
ذخیره میگردد .شرط دوباره چک شده و از آنجایی که شرط حلقه صحیح نمیباشد،
برنامه از حلقه میگذرد و برنامه پایان مییابد.
43
تمرین ها
;n = 1
)while (n < 10
;cout << n++ << endl
44
* :3-5برنامه ای بنویسید تا زمانی که کاربر عدد -1را وارد نکرده است ،از کاربر
لیتر مصرفی و مسافت پیموده شده را از کاربر بگیرد و نهایتا میانگین نسبت مسافت
پیموده شده به لیتر (مصرف سوخت) را بگوید.
** :3-6در یک شرکت ،کارمندان باید ماهی حداقل 35تا 40ساعت کار کنند .اگر
کارمندی بیش از 40ساعت کار کند ،به ازای هر ساعت اضافه کاری ،ساعتی 1.5
برابر حقوق عادی می گیرد .مثل اگر شخصی در ماه 42ساعت کار کرده باشد و
حقوق ساعتی او 10دالر باشد 400 ،دالر حقوق پایه و 5ساعت اضافه کاری1.5 ،
برابر حقوق عادی یعنی 15دالر دریافت می کند ،و بابت دو ساعت 30 ،دالر و
مجموعا 430دالر دریافت می کند .مالیت برای تمامی کارکنان 9درصد بوده و
افرادی که کمتر از 35ساعت کار کرده اند ،بیست درصد از حقوق ساعتی آنها کم
می شود .مثال بجای ساعتی 10دالر 8 ،دالر دریافت میکند .برنامه ای بنویسید که
تا زمای که عدد 1-وارد نشده است ،از کاربر تعداد ساعت و حقوق ساعتی را دریافت
کرده و حقوق دریافتی خالص را چاپ کند.
* :3-7به کمک حلقه های تو در تو ،برنامه ای بنویسید که با دریافت دو عدد mو
،nو به کمک دنباله گریز ،\tجدول ضرب mدر nرا ترسیم کند.
* :3-8برنامه ای بنویسید که عددی از کاربر گرفته و بگویید عدد چند رقمی است.
** :3-9برنامه ای بنویسید که بگویید وارد شده خودمقلوب است یا نه .عدد
خودمقلوب به عددی میگویند که چه از راست و چه از چپ خوانده شود ،یک عدد
است ،مانند 1001یا .121
* :3-10برنامه ای بنویسید که عددی مثبت از کاربر بگیرد و اعداد اول قبل از آن را
نمایش دهد.
45
** :3-11به کمک حلقه های تکرار ،برنامه ای بنویسید که مصتطیل زیر را چاپ
کند.
****
* *
* *
****
* :3-13به کمک حلقه های تکرار ،اشکال زیر را چاپ کنید.
** :3-14برنامه ای بنویسید که عددی صحیح به هنوان مجموع اضالع مثلث از
کاربر گرفته و بگوید که آیا می توان با مجموع داده شده ،مثلثی قائم الزاویه با طول
صحیح ساخت؟ اگر می شود ،اندازه صحیح آن سه ضلع را چاپ کند ،در غیر
اینصورت کلمه NOرا چاپ کند.
* :3-15مقدار سری های زیر را بدست آورید x( .و ،nتعداد جمالت ،را کاربر وارد
میکند)
46
𝟏 𝟏
… e = 1 + 𝟏! + 𝟐! +
*** :3-17برنامه ای به کمک حلقه های تکرار بنویسید که شکل زیر را چاپ کند.
*
***
*****
*******
*****
***
*
*** :3-18برنامه ای بنویسید که عددی از کاربر گرفته و لوزی مشابه مسال قبلی
به ارتفاع عدد وارد شده چاپ نماید.
** :3-19حنا وارد مسابقه هندونهخوری شده است .در این مسابقه nهندوانه وجود
دارد که به ترتیب با شمارههای 1تا nنامگذاری شدهاند ،همچنین وزن هندوانه i
ام w ،است( .وزن هندوانهها متمایز است).
47
حنا در هر مرحله از این مسابقه دو هندوانهای که کمترین شماره را دارند را انتخاب
میکند و هندوانهای که سبکتر است را میخورد .حنا به این کار ادامه میدهد تا
فقط یک هندوانه باقی بماند.
بعد از مسابقه حنا به این فکر رفته که آخرین هندوانه چه شمارهای داشت اما از
آنجا که خیلی هندوانه خورده ،فکرش کار نمیکند .به حنا کمک کنید و با
گرفتن wها شماره آخرین هندوانه را بگویید.
در سطر بعدی وزن هندوانه ها آمده است .شماره هندوانه ای که در آخر باقی میماند
را چاپ کنید( .کوئرا کالج)
** :3-20برنامه ای بنویسید که عددی از کاربر گرفته و اولین عدد توان دو بزرگتر
از آن عدد را چاپ کند.
** :3-21برنامه ای بنویسید که عددی از کاربر دریافت کند و بگوید آیا عدد وارد
شده کامل است یا نه .عدد کامل به عددی گفته می شود که مجموع مقسوم علیه
های غیر خودش ،برابر با خودش باشد .بطور مثال ،مقسوم علیه های غیر خود عدد
1 ،6و 2و 3می باشد که مجموع آنها برابر عدد 6است.
** :3-22برنامه ای بنویسید که دو عدد مثبت دریافت کرده و اعداد اول بین آن
بازه را نمایش دهد.
** :3-23برنامه ای بنویسید که 5عدد گرفته و ک.م.م و ب.م.م دو عدد بزرگتر را
نشان دهد.
48
* :3-24برنامه ای بنویسید که عددی از کاربر گرفته و مقسوم علیه های مثبت آن
را نشان دهد.
* :3-25برنامه ای بنویسید که دو عدد را بگیرد و تمام حالت های مکمن برای
همنشینی را چاپ کند .بطور مثال پیمانه های مکمن برای دو عدد 1و ،2 ،1 ،13
6 ،4 ،3و 12می باشد.
اگر nنفر کاندید شده باشند ( )2≤nابتدا طی مراسمی با قرعه کشی به هر
کاندیدی یک عدد از 1تا nتعلق میگیرد .کاندیدها به ترتیب شمارههایشان ،دور
میزی مینشینند و یکی در میان با شروع از شمارهی 2حذف میشوند.
حاال شما برنامهای بنویسید که شمارهی کاندید پیروز را با گرفتن تعداد کاندیدها از
ورودی چاپ کند( .کوئرا)
** :3-27تابع ) f(nبه این صورت تعریف میشود :کمارزشترین رقم ناصفر عدد .n
برای مثال کم ارزشترین رقم ناصفر اعداد 4650و ،347به ترتیب 5و 7میباشد.
پس f(4650)=5و .f(347)=7
حال عدد nرا به شما داده و شما باید )! f(nرا خروجی دهید.
49
فصل – 4تابع
تا به حال با کلیات اولیه زبان C++آشنا شده اید .در این فصل به بحث توابع می-
پردازیم.
همانطور که در فصل اول گفتیم ،کتابخانه های استاندارد C++دارای برخی توابع
پرکاربرد هستند که با اضافه کردن کتابخانه ها ،می توانید از توابع آنها استفاده کنید.
یکی از کتابخانه های پرکاربرد ،کتابخانه ریاضی ( mathیا )math.hمیباشد که با
includeکردن آن ،میتوان از توابعش استفاده کرد .به عنوان مثال میتوانید تابع
تولید عدد ردنوم و کتابخانه مربوط به آن را در اینترنت جستجو کنید .برخی از توابع
کتابخانه ریاضی .sqrt(x) ،pow(x, y) ،cos(x) ،sin(x) :تابع )( ،powتابع توان
بوده و حاصل xبه توان yرا باز میگرداند .تابع )( sqrtنیز مقدار جذر xرا باز
میگرداند .در مثال باال ،به xها و ،yورودی یا آرگومان تابع میگویند ،که با اعمال
تغییرات بر روی مقادیر ورودی ،یک خروجی به ما باز میگردانند .توجه کنید که
بعضی از توابع ورودی خاصی ندارند (مانند تابع )( deleteکه متغیر ها را پس از
اتمام برنامه از حافظه پاک میکند).
برای استفاده از توابع ،باید آنها را فراخواند .برای این کار باید نام تابع را نوشته و
سپس آرگومان ها تابع را داخل پرانتزها مینویسیم .اگر تابع آرگومان نداشته باشد،
50
پرانتز را خالی گذاشته ،و اگر بیش از یک آرگومان داشته باشد ،آنها را با کاما از
یکدیگر جدا میکنیم .واضح است که ترتیب آرگومان ها مهم است ،مثال مقدار
) pow(x, yبا ) pow(y, xمتفاوت است.
در اینجا با دو نوع تابع آشنا می شویم .نوع اول توابع voidمیباشند .توابع void
مقداری را به تابع mainبر نمیگرداند ،مانند تابعی که پیامی را در خروجی چاپ
میکند .نوع دوم توابعی هستند که مقداری را بر میگردانند .مانند تابع فاکتوریل که
عدد nرا به آن داده و ! nرا محاسبه کرده و به تابع mainباز میگرداند.
توابع را میتوان در دو قسمت ،قبل و بعد تابع .mainاگر تابع را بعد از تابع main
بنوسیم ،باید به C++اعالم کنیم که همچین تابعی وجود دارد ،چون دستورات خط
به خط اجرا میشوند و اگر تابع ما بعد از mainباشد ،باید اعالم گردد .شکل کلی
توابع:
51
{ )… Type FunctionName (Input Argument 1, 2,
;Codes
}
در قسمت typeباید مشخص کنیم تابع ما چه چیزی بر میگرداند .اگر چیزی بر
نمیگرداند ،void ،اگر عددی صحیح باز میگرداند از ،intاگر عددی اعشاری باز
میگرداند ،از ،floatاگر کاراکتری را باز میگرداند از charو ...استفاده می کنیم.
نکته :آرگومان ها و متغیرهای داخل تابع محلی می باشند ،بدین معنا که این
متغیر ها تنها در تابع مورد استفاده قرار میگیرند و فقط مربوط به همان تابع
اند .بطور مثال اگر متغیر aدر تابع mainو متغیر aدر یک تابع داشته
باشید ،این دو از هم مجزا بوده و ربطی به هم ندارند ،یعنی متغیرها محلی اند.
{ )( int main
{ )if (n % 10 == 0
;counter++
}
;n = n / 10
}
}
{
{ )long int fact (int a
p *= i; // p = p * i
}
;return p
}
|5
1
توجه :هنگام تعریف آرگومان های تابع ،هر آرگومان باید بصورت جداگانه
تعریف شود .در مثال باال آرگومان ما int aاست ،یعنی ورودیی به نام aاز
نوع .intاگر نیاز به چند ورودی داشتیم باید مثال بصورت
)Type FunctionName (int a, int b, int c, float d
نوشت .نوشتن بصورت int a, b, cبرای آرگومان ها اشتباه است.
54
تمرین ها
تمام مثال های حل شده در فصل های قبلی را می توان با تابع نوشت .به عنوان
تمرین می توانید مثال ها و تمرین های فصل های قبل را به کمک تابع حل کنید.
55
فصل – 5آرایه
شاید تا به حال در سوالی نیاز بود که تعداد زیادی داده را در متغیر های مختلف
ذخیره کنید .به کمک آرایه ها ،محل ها متوالی از حافظه هستند که نام و نوعشان
یکسان بوده .برای دسترسی به هر عنصر آرایه ،باید از نام و اندیسش استفاده کنیم.
برای ساخت یک آرایه یک بعدی به روش زیر عمل میکنیم:
56
دوباره آنها را نمایش داده و، دانشجو را گرفته5 حال فرض کنید میخواهیم نمره
. دانشجو را نشان دهیم5 سپس میانگین این
#include <iostream>
int main () {
sum += score[i];
cout << “Student ” << i + 1 << “ score:” << score[i] << endl;
return 0;
|10
|15.5
|13
|18.25
|20
Student 1 score: 10
Student 3 score: 13
Student 5 score: 20
Avg= 15.35
57
در ابتدا یک آرایه 5عضوی به نام scoreو از نوع floatساختهایم .یک متغیر
sumبرای محاسبه میانگین نیز ساختهایم .همانطور گه گفتیم ،اندیس آرایه از صفر
شروع میشود و تا n-1پیش میرود ،پس باید از یک حلقه forاز 0تا 4استفاده
کرد .در حلقه بعدی هم به همین شکل از 0تا 4شروع میشود .دقت کنید از
آنجایی که دانشجو صفرم معنی ندارد و شماره دانشجویان i + 1است ،پس در
coutنیز Student i + 1باید چاپ شود ،نه .iدر آخر نیز میانگین را حساب می-
کنیم .توجه کنید که هنگام دسترسی به یک عنصر ،داخل کروشه میتوان عبارت
ریاضی نوشت ،اما مقدار نهایی آن باید در بازه تعریف شده اندازه آرایه باشد.
تا اینجا با آرایه های یک بعدی آشنا شدید .حال میخواهیم به آرایه های دو بعدی
بپردازیم .آرایه های دو بعدی را میتوان به ماتریسی تشبیه کرد که اندیسهایش
بجای یک ،از صفر شروع میشوند.
58
for (int i = 0; i <= m; i++) {
for (int j = 0; j <= n; j++) {
codes
}
}
حال میخواهیم به. عناصر سطر اول را پر میکندj حلقه، استi = 0 مثال زمانی که
فیزیک و، نمرات سه درس ریاضی، دانشجو4 عنوان مثال برنامه ای بنویسیم که از
میانگین هر درس و معدل هر دانشجو را،شیمی را خوانده و بصورت جدولی نمرات
.نشان دهد
#include <iostream>
int main()
float score[4][3], sum[4] = {0.0, 0.0, 0.0, 0.0}, sumsubject[4] {0.0, 0.0, 0.0, 0.0}, avg = 0.0;
sum[i] += score[i][j];
cout << "Student Number\t" << "Math\t" << "Physics\t" << "Chemistry\t" << "Average" <<
endl;
sumsubject[i] += score[j][i];
return 0;
|19
|18.5
|13.5
|16.25
|14.5
|17
|13.75
|14.5
|16
|17
|11.5
|9
Student Number Math Physics Chemistry Average
60
به مثال باال و توضیحات توجه کنید .در این مثال 4دانشجو با 3نمره وجود دارند.
پس به یک آرایه 2بعدی با 4سطر (تعداد دانشجویان) و 3ستون (تعداد دروس)
نیاز داریم .به همین دلیل یک آرایه دو بعدی ] score[4][3ساختیم .حال به کمک
یک حلقه تو در تو ،نمره هر درس را میخوانیم که در ] ،score[i][jبه معنای نمره
درس jام دانشجو iام است .یک آرایه یک بعدی 4عضوی ( 4دانشجو) به نام sum
ساخته ایم که مجموع نمرات هر دانشجو را در خود ذخیره میکند .واضح است که با
تقسیم ] sum[iبر ( 3تعداد دروس) معدل هر دانشجو بدست میآید .نمرات و
معدل هر دانشجو را در حلقه دوم چاپ میکنیم .در خط آخر ،میانگین هر درس و
در درایه آخر ،میانگین کلی را درج میکنیم .برای اینکار ،آرایه ای با نام
sumsubjectساختهایم که مثال تمام نمرات ریاضی دانشجویان را در خود ذخیره
کرده و با تقسیم ] sumsubject[iبر ،4میانگین هر درس به دست می آید .نکته
ای که وجود دارد ،در حلقه های قبلی بصورت سطری پیمایش میکردیم ،یعنی در
] ،score[i][jدر یک سطر iثابت و jتغییر میکرد ،اما برای جمع دروس ،باید
بصورت ستونی پیمایش کنیم ،که برای اینکار در ] score[i][jدر هر ستون باید j
ثابت باشد و به مقدار iاضافه گردد .برای اینکار یا میتوانیم در حلقه تو در تو ،حلقه
بیرونی را jبنامیم و حلقه درونی را ،iیا اینکه اگر حلقه بیرونی iاست ،بصورت
] score[j][iپیمایش کنیم تا بتوانیم جمع نمرات هر ستون را حساب کنیم( .با
توجه به حدکثر مقادیر iو .)jحال میانگین هر درس را با تقسیم بر 4نشان می-
دهیم .برای محاسبه آخرین درایه که میانگین کلی است ،می توان یا از آرایه sum
استفاده کرد یا از sumsubjectاستفاده کرد ،که بعنوان مثال ما از مورد دومی
استفاده کردهایم .الزم به ذکر است که میتوان بعضی از دستورات را دی حلقه های
قبلی استفاده نمود و کد را خالصه تر کرد ،اما برای واضح بودن ،سعی شد دستورات
کمتری در هر حلقه باشد.
61
نکته :آرایه }… a[N] = {0, 0, 0,معادل }{ = ] a[Nاست .در مثال باال می
توانستیم از }{ نیز استفاده کنیم.
با روش حلقه های تو در تو برای مقداردهی به آرایه دو بعدی آشنا شدید .برای
مقداردهی در داخل برنامه میتوانید به روش زیر عمل کنید.
}} … A[m][n] = {{a00, a01 … a0n}, {a10, a11, …a1n} … {am0, am1,
اگر آرایه ای در تابع mainداشته باشید و میخواهید به یک تابع ،آرایه ارسال
کنید ،نخست باید یک آرایه بعنوان آرگومان و یک آرگومان دیگر برای اندازه آرایه
ساخت:
گاهی نیاز است که در یک آرایه ،داده ای را بیابید .برای اینکار روش های متنوعی
وجود دارد که به ذکر دو مثال میپردازیم .در روش اول ،مقایسه هر عنصر از آرایه با
عندصر مورد نظر است .برای اینکار با یک حلقه ساده ،یک به یک عناصر آرایه را با
داده مطلوب مقیاسه میکنیم.
در روش دوم ،فرض کنید آرایه ای مرتب دارید .نخست عنصر وسط را با داده مطلوب
62
مقایسه میکنیم . .اگر هم که همان عنصر وسطی بود که یعنی عنصر مطلوب را
یافته ایم .اگر داده مطلوب از آن عدد کوچک تر باشد ،پس باید در نیمه اول به
دنبال آن بگردیم (بدلیل مرتب بودن آرایه) .اگر از عنصر وسط بزرگتر بود ،باید در
نیمه دوم به دنبال آن عنصر بگردیم .سپس برای بازه های دیگر این کار را تکرار
کرده تا به عنصر مطلوب برسیم .واضح است که سرعت این روش از روش باالیی
بیشتر است (چون بعضی از داده ها اصال بررسی نمی شوند) .به مثال زیر دقت کنید.
>#include <iostream
)(int main
{
;int a[] = {1, 3, 4, 5, 6, 8, 11, 13, 15, 16}, high, low, mid, x = 15
;low = 0
;high = 9
{ )]if (x == a[mid
;found = true
;break
}
}
}
}
{ )if (!found
};return 0
Found! Index is 8
در اینجا ما به xیک مقدار اولیه دادهایم ،اما می شد کاربر عدد را وارد کند که فرقی
ندارد .در اینجا سه متغیر low ،highو midداریم که highمنظور اندیس
ماکسیمم بازه mid ،اندیس مینیمم بازه و midعنصر وسطی است .بطور مثال به
دنبال عدد 15در این آرایه ایم .نخست مقادیر max ،minو midآرایه مشخص
می گردند که ] a[0مینیمم و ] a[9ماکسیمم و ] a[4عنصری وسطی است .سپس
متغیر xبا ] a[4مقایسه میگردد .چون آرایه مرتب بوده و xاز ] a[4بزرگتر است،
پس یعنی باید در نیمه دوم به دنبال xباشیم .پس برای نیمه دوم ،به ترتیب ] a[5و
] a[9را بعنوان مینیمم و ماکسیم و ] a[7را نیز بعنوان عنصر وسطی انتخاب
میکنیم .دوباره عنصر xرا با ] ،a[7عنصر وسط ،مقایسه میکنیم x .از ] a[7بزرگتر
است ،پس باید در نیمه دوم (] a[7تا ] )a[9به دنبال xباشیم .دوباره مینیمم را
] a[8فرض کرده و ماکسیمم همان ] ،a[9فرض میکنیم .اندیس عنصر وسط =
8 = (8+9)/2سپس ] a[8با xمقایسه شده و عنصر مطلوب پیدا میگردد .شرط
حلقه whileبدین صورت است که اندیس lowنباید از اندیس highبزگتر شود،
مثال اگر عدد مورد نظر 15نبود ،در مرحله بعد هم lowهم 9 ،highشده و در
مرحله بعد 10 lowو 9 highمیشود که تناقض است و بدین معناست که عنصر
مربوطه در آرایه وجود ندارد.
در آخر این فصل هم به مرتب کردن آرایه ها میپردازیم .برای مرتب کردن آرایه ها
میتوانید از توابع آماده (همچون )sortاستفاده کنید .یکی از الگوریتمهای معروف
Bobble Sortمیباشد .در این روش عنصر iام را عنصر بعدی اش مقایسه می-
کنید .اگر عنصر اول کوچکتر از دومی بود ،جای آنها را با هم عوض میکنید .اینکار
را آنقدر ادامه میدهیم که کل آرایه مرتب گردد .اگر آرایه ای nعضو داشته باشد و
64
در بد ترین حالت اگر عضو آخر کوچکترین باشد ،بدترین حالت می باشد ،که در هر
بار ،فقط یکبار عقب می آید .یعنی در هر بار سورت کردن ،در بدترین حالت ،جای
یک عنصر تعیین میگردد .پس به تعداد عناصرش سورت کردن را تکرار کنیم .بدین
منظور باید از یک حلقه تو در تو استفاده کرد در بدترین حالت نیز عناصر را مرتب
کند .فرض کنید آرایه زیر را میخواهیم مرتب کنیم.
5از 13کوچکتر است ،پس کاری نمیکنیم 7 .از 13کوچکتر است پس جای این دو
رو عوض میکنیم 5, 7, 13, 2, 9, 1.سپس 13را با 2مقایسه و جابجا می کنیم.
5, 7, 2, 13, 9, 1حال جای 13و 9را جابجا میکنیم 5, 7, 2, 9, 13, 1 .و در
آخر نیز جای 13و 1را عوض میکنیم .همانطور که میبینید ،جای اصلی عدد 13
در یکبار سورت کردن مشخص شد .پس باید nبار ( nاندازه آرایه) آن را سورت
کنیم تا جای همه عناصر مشخص گردند 5 5, 7, 2, 9, 1, 13 .کوچکتر از 7هست
پس کاری نمیکنیم 7 .بزرگتر از 2است ،پس باید جایشان را با هم عوض کنیم5, .
7 .2, 7, 9, 1, 13کوچک تر از 9بوده و کاری با آن نداریم ،حال جای 1را با 9
عوض کرده و میشود ،5, 2, 7, 1, 9, 13که در دومین سورت ،مکان دومین عنصر
نیز پیدا شد .حال اگر این روش را 6بار (اندازه آرایه) تکرار کنیم ،آرایه مرتب می-
شود .کد مربوط به مرتب سازی بدین شکل است:
}
}
}
65
تمرین ها
* :5-2برنامه ای بنویسید که آرایه ای 10عضوی از کاربر گرفته و 3عدد بزرگ این
اعداد را مشخص کند.
* :5-3تمرین 5-2را بگونه ای انجام دهید که kامین عدد بزرگ را اعالم کنید k .را
نیز کاربر وارد می کنید.
** :5-4به کمک سه تابع ،میانه ،مد و میانگین یک مجموعه عدد 20تایی را حساب
کنید.
** :5-7برنامه ای بنویسید که آرایه ای 10عضوی از کاربر گرفته و اعداد زوج را
بصورت صعودی در اول آرایه و اعداد فرد را بصورت صعودی در آخر آرایه بگذارد.
* :5-8برنامه ای بنویسید که آرایه ای 20عضوی از کاربر بگیرد ،سپس یک عدد از
کاربر بگیرد و بگوید چند بار آن عدد در آرایه تکرار شده است.
* :5-9برنامه ای بنویسید که آرایه ای 20عضوی بگیرد و اعضای منحصر بفرد آرایه
را نشان دهد( .تکراری نباشند)
66
** :5-10به کمک تابع بازگشتی ،کوچکترین عضو یک آرایه 10عضوی را اعالم
کنید.
###
67