قبل از نوشتن يك برنامه كه بتواند مسئلهاي را به طور دقيق حل كند، ضروري است كه درك صحيحي از مسئله داشته باشيم و بوسيله يك طراحي دقيق به آن اقدام كنيم. به هنگام نوشتن يك برنامه، سازماندهي انواع بلوكهاي ايجاد كننده برنامه به منظور بهبود قوانين عملي ساخت برنامه بسيار مهم است. در اين فصل و فصل بعدي در مورد تئوري و قواعد علمي برنامهنويسي ساختيافته بحث خواهيم كرد. تكنيكهاي معرفي شده در اين فصل در اكثر زبانهاي سطح بالا نظير كاربرد دارند. با معرفي مفاهيم مطرح شده در اينجا متوجه مزيت عبارتهاي كنترل در ايجاد و دستكاري شيها خواهيد شد. عبارتهاي كنترل معرفي شده در اين فصل در ايجاد سريع و آسانتر شيها كمك كننده هستند.
در اين فصل به معرفي عبارات
if
،
if..else
و
while
در زبان
C++
خواهيم پرداخت. سه بلوك سازنده كه به برنامهنويسان امكان ميدهند تا منطق مورد نياز توابع عضو را براي انجام وظايف مشخص كنند. بخشي از اين فصل و فصلهاي 5 و 7 را براي توسعه دادن كلا
س
GradeBook
معرفي شده در فصل سوم اختصاص دادهايم. در واقع، يك تابع عضو به كلاس
GradeBook
اضافه ميكنيم كه از عبارات كنترلي براي محاسبه ميانگين نمرات دانشجويان استفاده ميكند. مثال ديگر به معرفي روشهاي تركيب عبارات كنترلي براي حل مسئله مشابه است. همچنين به معرفي عملگرهاي تخصيصدهنده و عملگرهاي افزاينده و كاهنده در
C++
خواهيم پرداخت. اين عملگرها سبب كوتاه شدن عبارات و گاهاً سادگي كار ميشوند.
2-4 الگوريتم
هر مسئله محاسباتي و كامپيوتري ميتواند با يك سري از اعمال اجرائي كه به ترتيب اجرا ميشوند، حل شود. از روالها براي حل مسائل كمك گرفته ميشود و عبارات:
1- فعاليتها از نوع اجراي هستند و
2- فعاليتها به ترتيب اجرا ميشوند،
تعريف الگوريتم ميباشند. با ذكر مثالي كه در زير آمده ميتوانيد ترتيب اجرا و فعاليتها را ببينيد و متوجه شويد كه ترتيب اجرا چقدر مهم است. الگوريتم
“rise - and - shine”
در ارتباط با مراحلي است كه يك شخص از هنگام برخواستن از خواب تا رفتن به سركار انجام ميدهد، مراحل: (1) برخواستن از تختخواب، (2) پوشيدن لباس راحتي، (3) دوش گرفتن، (4) پوشيدن لباس، (5) خوردن صبحانه، (6) رفتن به محل كار. اين روتين در مورد نحوه انجام كار و ضوابط تصميمگيري ميتواند موثر باشد حال اگر ترتيب اجرا به صورت زير جابجا شود:
(1) برخواستن از تختخواب، (2) پوشيدن لباس راحتي، (3) پوشيدن لباس، (4) دوش گرفتن، (5) خوردن صبحانه، (6) رفتن به محل كار. در اين حالت شخص مورد نظر، بايستي به محل كار با لباس خيس برود.
مشخص كردن عبارات اجرائي در يك برنامه كامپيوتري، كنترل برنامه
(program control)
ناميده شود، كه به اجراي صحيح و مرتب عبارات گفته ميشود.
3-4 شبهكد
شبهكد
(pseudocode)
يك زبان مصنوعي و فرمال است كه به برنامهنويس كمك ميكند تا الگوريتم خود را توسعه دهد. شبهكد مخصوصاً براي ايجاد الگوريتمهاي مفيد است كه ميخواهيم آنها را تبديل به برنامههاي ساخت يافته كنيم شبهكد، همانند زبان روزمره انگليسي است و مزيت آن درك آسان توسط كاربر است، اگر چه جزء زبانهاي برنامهنويسي اجرائي نيست. برنامههاي شبهكد توسط كامپيوتر قابل اجرا نيستند. با اين همه، شبهكدها، ميتوانند قبل از نوشتن يك برنامه به زبان اجراي مانند
C++
، برنامهنويس را در راه صحيح قرار دهند.
مهندسي نرمافزار
شبهكد به برنامهنويسان كمك ميكند تا در زمان فرآيند طراحي برنامه يك مفهوم منطقي از برنامه بدست آورند. برنامه شبهكد ميتواند در مرحله بعد به زبان ++
C
برگردانده شود.
شبهكدهايي كه از آنها استفاده ميكنيم، فقط از كاراكترها تشكيل شدهاند و برنامهنويس ميتواند آنها را در يك برنامه ويرايشگر، تايپ كند. شبهكد، فقط شامل عبارات اجرائي است. زماني كه شبهكد تبديل به كدهاي
C++
شود، برنامه حالت اجرايي پيدا خواهد كرد. اعلانها جزء عبارات اجرائي نيستند. براي مثال، اعلان
int i;
فقط به كامپايلر نوع متغير
i
را نشان داده و كامپايلر مكاني در حافظه به اين متغير اختصاص ميدهد. اما اين اعلانها هيچ عمل اجرائي نظير ورودي، خروجي يا يك عمل محاسباتي را در زماني كه برنامه اجرا ميشود، از خود نشان نميدهند. تعدادي از برنامهنويسان ليستي از متغيرها تهيه كرده و منظور از كاربرد هر متغير را در ابتداي شبهكد قرار ميدهند.
اكنون به مثالي از شبه كد نگاه ميكنيم كه ميتواند براي كمك به برنامهنويس در ايجاد يك برنامه جمع معرفي شده در شكل 5-2 (فصل دوم) نوشته شده باشد. اين شبه كد (شكل 1-4) متناظر با الگوريتمي است كه دو عدد صحيح از كاربر دريافت، آنها را با هم جمع و مجموع آنها را به نمايش در ميآورد. با اينكه ليست كامل شبه كد را به نمايش درآوردهايم، اما شما را با نحوه ايجاد يك شبه كد از صورت مسئله آشنا خواهيم كرد.
1
Prompt the user to enter the first integer
2
Input the first integer
3
4
Prompt the user to enter the second integer
5
Input the second integer
6
7
Add first integer and second integer
8
Display result
شكل 1-4 | شبه كد برنامه جمع شكل 5-2.
خطوط
1-2
متناظر با عبارات موجود در خطوط
13-14
از شكل 5-2 هستند. دقت كنيد كه عبارات شبه كد، عبارات ساده انگليسي هستند كه هر وظيفه در
C++
را بيان ميكنند. به همين ترتيب، خطوط
4-5
متناظر با عبارات موجود در خطوط
16-17
و خطوط
7-8
متناظر با عبارات موجود در خطوط
19
و
21
از شكل 5-2 هستند.
چندين نكته مهم در شبه كد شكل 1-4 وجود دارد. دقت كنيد كه شبه كد فقط متناظر با كد موجود در تابع
main
است، به اين دليل كه معمولاً از شبه كد براي الگوريتمها استفاده ميشود، نه براي كل برنامه. در اين مورد، از شبه كد براي عرضه الگوريتم استفاده شده است. تابع موجود در اين كد به اندازه خود الگوريتم مهم نيست. به همين دليل، خط
23
از شكل 5-2 (عبارت
return
) در شبه كد وارد نشده است. عبارت
return
در انتهاي هر تابع
main
قرار دارد و در الگوريتم اهميتي ندارد. سرانجام، خطوط
9-11
از شكل 5-2 در شبه كد وجود ندارد چرا كه اعلان متغيرها جزء عبارات اجرايي نيستند.
4-4 عبارات كنترل
معمولاً، عبارات موجود در يك برنامه يكي پس از ديگري و به ترتيبي كه نوشته شدهاند اجرا ميشوند، كه به اينحالت اجراي ترتيبي ميگويند. انواع متفاوتي از عبارات كه بزودي درباره آنها بحث خواهيم كرد، برنامهنويسان را قادر ميسازند تا با مشخص كردن عبارتي كه بايستي قبل از عبارت ديگري اجرا شود، اين توالي اجرا را در دست گيرند، كه به اينحالت، كنترل انتقال ميگويند.
در دهه 1960، به دليل وجود مشكلات فراوان در ايجاد نرمافزارهاي كاربردي، استفاده از روشهاي كنترل انتقال به عنوان يك زمينه بكار گرفته شد و نشانه آن عبارت
goto
بود. اين عبارت به برنامهنويس اجازه ميدهد تا كنترل را به يك مكان ويژه در كل برنامه انتقال دهد. عقيدهاي كه برنامهنويسي ساخت يافته نام گرفته بود، تقريباً با برنامهنويسي حذف
goto
يا كاهش آن
(goto-less)
مترادف شده است.
با تحقيقات
Jacopini
و
Bohm
كه نشان داد كه برنامهها بايستي بدون
goto
نوشته شوند، دعوت از برنامهنويسان به طرف برنامهنويسي كاهش استفاده از
goto
آغاز گرديد. اما تا سال 1970 برنامهنويسي ساخت يافته جدي گرفته نشد. در نتيجه بكار بردن اين روش، توسعه نرمافزار و كاهش بودجههاي ساخت آن مشخص شد. كليد تمام اين موفقيتها برنامههاي ساخت
يافتهاي بودند كه هم وضوح بالاتر و خطاگيري آسانتري داشتند.
Bohm
و
Jacopini
نشان دادند كه تمام برنامهها در سه عبارت كنترلي ميتوانند نوشته شوند:
·
عبارت توالي
(sequence structure)
·
عبارت انتخاب
(selection structure)
·
عبارت تكرار
(repetition structure)
ساختار توالي در
C++
ساختار توالي بصورت توكار در
C++
وجود دارد. مگر اينكه آن را به نحوه ديگري هدايت كنيد. كامپيوتر مبادرت به اجراي عبارات
C++
يكي پس از ديگري و به ترتيبي كه نوشته شدهاند ميكند، كه اين حالت اجراي ترتيبي يا متوالي است. دياگرام فعاليت
UML (Unified Modeling language)
به نمايش درآمده در شكل 2-4 نشاندهنده يك ساختار توالي است كه در آن دو محاسبه به ترتيب انجام ميشود. زبان
C++
اجازه ميدهد تا به هر اندازه كه لازم داريم از ساختار توالي استفاده كنيم. همانطوري كه بزودي مشاهده خواهيد كرد، در هر كجا كه يك عمل ميتواند موجود باشد، ميتوانيم چندين عمل را به صورت توالي جايگزين كنيم.
در اين شكل، دو عبارت مبادرت به افزودن يك نمره به متغير مجموع
(total)
و مقدار
1
به متغير
counter
ميكنند. چنين عباراتي را ميتوان در يك برنامه محاسبه ميانگين نمره چند دانشجو مشاهده كرد. براي محاسبه ميانگين، مجموع نمرات به تعداد نمرات تقسيم ميشود. از متغير شمارنده
(counter)
براي نگهداري تعداد نمرات وارد شده استفاده ميشود. در بخش 8-4 با عبارات مشابهي مواجه خواهيد شد.
دياگرامهاي فعاليت بخشي از
UML
هستند. يك دياگرام فعاليت مبادرت به مدلسازي روندكار (فعاليت) يك بخش از سيستم نرمافزاري ميكند. چنين روندهايي ميتوانند در برگيرنده بخشي از يك الگوريتم، همانند يك ساختار توالي در شكل2-4 باشند.دياگرامهاي فعاليت مركب از نمادهاي معنيدار، همانند نمادهاي وضعيت عمل (يك مستطيل كه گوشههاي چپ و راست آن به سمت بيرون انحناء داده شدهاند)، لوزيها و دايرههاي كوچك است. اين نمادها توسط فلشهاي انتقال به يكديگر متصل ميشوند كه نشاندهنده روند فعاليت ميباشند.
همانند شبه كد، دياگرامهاي فعاليت به برنامهنويسان در توسعه و عرضه الگوريتمها كمك ميكنند، اگر چه برخي از برنامهنويسان شبه كد را ترجيح ميدهند. دياگرامهاي فعاليت به وضوح نحوه عملكرد ساختارهاي كنترل را نشان ميدهند.
به دياگرام فعاليت ساختار متوالي در شكل 2-4 توجه كنيد. اين دياگرام حاوي دو نماد وضعيت عمل است كه نشاندهنده اعمالي هستند كه اجرا ميشوند. هر وضعيت عمل حاوي يك بيانكننده عمل است،
"add grade to total"
و
"add 1 to counter"
كه مشخصكننده عملي هستند كه انجام خواهند شد. ساير اعمال ميتوانند محاسباتي يا ورودي/ خروجي باشند.
شكل 2-4 | دياگرام فعاليت يك ساختار توالي.
فلشها در دياگرام فعاليت، بنام فلشهاي انتقال شناخته ميشوند. اين فلشها نشاندهنده انتقال هستند و بر اين نكته دلالت دارند كه ترتيب اجراي اعمال به چه صورتي است. براي مثال در شكل 2-4 ابتدا
grade
با
total
جمع شده و سپس
1
به
counter
افزوده ميشود.
دايره توپر ساده كه در بالاي دياگرام فعاليت قرار گرفته نشاندهنده وضعيت اوليه فعاليت است، ابتداي روندكار قبل از اينكه برنامه عمليات مدل شده را انجام دهد. دايره توپر احاطه شده با يك دايره توخالي كه در پايين دياگرام فعاليت ديده ميشود، نشاندهنده وضعيت پاياني است، پايان روندكار پس از اينكه فعاليتهاي خود را انجام داده است.
همچنين شكل 2-4 شامل مستطيلهاي با گوشههاي خم شده به داخل (سمت راست-بالا) است. اين مستطيلها، در
UML
، نكته
(note)
ناميده ميشوند. نكتهها توضيحات اضافي در ارتباط با هدف نمادها در دياگرام ارائه ميكنند. از نكتهها ميتوان در هر دياگرام
UML
و نه تنها در دياگرامهاي فعاليت استفاده كرد. در شكل 2-4 از نكتههاي
UML
براي نمايش كد
C++
مرتبط با هر وضعيت عمل در دياگرام فعاليت استفاده شده است. خط نقطه چين مبادرت به متصل نمودن هر نكته با عنصري ميكند كه در ارتباط با آن توضيح ارائه مينمايد. معمولاً دياگرامهاي فعاليت، كد
C++
پيادهسازي كننده فعاليت را عرضه نميكنند. اما از اين نكتهها به اين منظور در اينجا استفاده كردهايم تا رابطه دياگرام با كد
C++
مربوطه را بهتر نشان دهيم. براي كسب اطلاعات بيشتر در مورد
UML
به بخش مبحث آموزشي مهندسي نرمافزار كه در انتهاي فصل 1 الي 7، 9، 10، 12 و 13 قرار دارند مراجعه كرده يا از وب سايت
www.uml.org
بازديد نماييد.
عبارات انتخاب در
C++
زبان
C++
سه نوع عبارت انتخاب تدارك ديده است كه در مورد آنها در اين فصل و فصل بعدي توضيح خواهيم داد. در عبارت انتخاب
if
اگر شرط برقرار باشد عبارت يا عبارات داخل بدنه اجرا شده و در صورتيكه شرط برقرار نباشد از روي آن عبارات بدون اجراي آنها عبور خواهد شد. عبارت
if..else
در صورتيكه شرط برقرار باشد، عبارت (يا دنبالهاي از عبارات) را انجام داده و در صورتيكه شرط برقرار نباشد، عمل اجراي متفاوتي را به انجام ميرساند (يا اجراي توالي از عبارات). عبارت
switch
كه در فصل 5 به بررسي آن خواهيم پرداخت با توجه به ارزش يك عبارت، يكي از چندين عمل اجرائي را به اجرا در ميآورد.
عبارت
if
را عبارت تك انتخابي
(single-selection)
مينامند، چرا كه يك عمل را انتخاب و اجرا يا آنرا رد ميكند. عبارت
if..else
را عبارت دو انتخابي
(double-selection)
مينامند، چرا كه انتخابي مابين دو حالت متفاوت انجام ميدهد. عبارت
switch
، عبارت چند انتخابي
(multiple-selection)
ناميده ميشود، چرا كه از ميان موارد متفاوت انتخاب خود را انجام ميدهد.
عبارات تكرار در
C++
C++
سه نوع عبارت تكرار بنامهاي زير تدارك ديده است:
·
while
·
do..while
·
for
عبارت تكرار
while
، در اين فصل معرفي خواهد شد و عبارات
do..while
، و
for
در قسمت هاي بعدي توضيح داده خواهند شد. كلمات
if
،
else
،
switch
،
while
،
do
و
for
همگي جزء كلمات كليدي
C++
هستند (
جدول
شكل 3-4). با بسياري از اين كلمات كليدي در اين آموزش آشنا خواهيد شد.
خطاي برنامهنويسي
استفاده از كلمه كليدي بعنوان يك شناسه خطاي نحوي خواهد بود.
خطاي برنامهنويسي
نوشتن يك كلمه كليدي با حروف بزرگ خطاي نحوي است تمام كلمات كليدي در
C++
فقط شامل حروف كوچك هستند.
C++ Keywords
|
Keywords common to the C and C++ programming languages
|
auto
|
break
|
case
|
char
|
const
|
continue
|
default
|
do
|
double
|
else
|
enum
|
extern
|
float
|
for
|
goto
|
if
|
int
|
long
|
register
|
return
|
short
|
signed
|
sizeof
|
static
|
struct
|
switch
|
typedef
|
union
|
unsigned
|
void
|
volatile
|
while
|
|
|
|
C++ only keywords
|
asm
|
bool
|
catch
|
class
|
const_cast
|
delete
|
dynamic_cast
|
explicit
|
false
|
friend
|
inline
|
mutable
|
namespace
|
new
|
operator
|
private
|
protected
|
public
|
reinterpret_cast
|
and
|
static_cast
|
template
|
this
|
throw
|
true
|
try
|
typeid
|
typename
|
using
|
virtual
|
wchar_t
|
and_eq
|
bitand
|
bitor
|
export
|
not
|
not_eq
|
or
|
or_eq
|
xor_eq
|
شكل 3-4 | كلمات كليدي
C++
خلاصهاي بر عبارات كنترلي در
C++
C++
داراي سه عبارت كنترلي است، كه از اين به بعد از آنها بعنوان عبارات كنترلي ياد خواهيم كرد: عبارت توالي، عبارات انتخابي (سه نوع-
if, if..else
و
switch
)
و عبارات تكرار(سه نوع-
while, for
و
do..while
)
. هر برنامه
C++
از تركيب اين
عبارات كنترلي
ايجاد ميشود. همانند عبارت توالي در شكل 2-4، ميتوانيم هر عبارت كنترلي را بصورت يك دياگرام فعاليت مدلسازي كنيم.
هر دياگرام حاوي يك حالت اوليه و يك حالت پاياني است، كه به ترتيب نشاندهنده نقطه ورودي
(entry point)
به عبارت كنترلي و نقطه خروجي
(exit point)
آن ميباشند. عبارات كنترلي تكورودي/تكخروجي ايجاد آسانتر برنامهها را ممكن ميسازند. نقطه خروجي يك عبارت كنترلي را ميتوان به نقطه ورودي عبارت كنترلي ديگري متصل كرد و به همين ترتيب ادامه داد. اين فرآيند همانند قرار دادن بلوكهاي بر روي هم است، از اينرو اين روش، عبارت كنترلي پشته
(control structure stacking)
نام دارد. اين روش يكي از روشهاي موجود براي متصل كردن عبارات كنترلي به يكديگر است. يك روش ديگر عبارت كنترلي تودرتو يا آشيانهاي
(control structure nesting)
ميباشد كه در آن يك عبارت كنترلي ميتواند در درون عبارت ديگري قرار گيرد. بنابر اين الگوريتمها در برنامههاي
C++
فقط متشكل از سه نوع عبارت كنترلي تركيب شده با اين دو روش هستند.
مهندسي نرمافزار
هر برنامه را ميتوان با هفت نوع عبارت كنترلي ايجاد كرد (توالي،
if
،
if..
else
،
switch
،
while
،
do..while
و
for
) كه به دو روش با هم تركيب ميشوند (عبارت كنترلي پشهاي و تو در تو يا آشيانهاي).
5-4 عبارت انتخاب
if
در يك عبارت انتخاب، هدف برگزيدن يكي از گزينههاي موجود براي انجام آن است. براي مثال، فرض كنيد كه شرط قبولي در يك امتحان نمره
60
است از (
100
). عبارت شبهكد آن بصورت زير ميباشد:
If student’s grade is greater than or equal to 60
Print “Passed”
شرط
“student’s grade is greater than or equal to 60”
ميتواند برقرار باشد يا نباشد. اگر شرط برقرار باشد عبارت
“Passed”
به معني قبول شدن به نمايش در ميآيد و عبارت پس از شبهكد به ترتيب اجرا ميشود (بياد داشته باشيد كه شبهكد يك زبان برنامهنويسي واقعي نيست). اگر شرط برقرار نباشد عبارت چاپ ناديده گرفته ميشود و عبارت شبهكد بعدي به ترتيب اجرا خواهد شد. عبارت موجود در بدنه عبارت
if
رشته "
Passed
" را ب
ه
چاپ ميرساند. همچنين به دندانهدار بودن اين عبارت در اين عبارت انتخاب دقت كنيد. دندانه گذاري امري اختياري است، اما بكارگيري آن بسيار توصيه ميشود چرا كه ارتباط عبارتهاي مختلف برنامه را بخوبي نشان ميدهند. كامپايلر
C++
كاراكترهاي
whitespace
يعني كاراكترهاي فاصله،
tab
و خطوط جديد بكار رفته در ايجاد دندانهها و فاصلهگذاري عمودي را بجز كاراكترهاي
whitespace
بكار رفته در رشتهها، در نظر نميگيرد.
برنامهنويسي ايدهال
سعي كنيد از روش دندانهگذاري ثابتي در برنامههاي خود استفاده كنيد تا خوانايي برنامه افزايش يابد.
ميتوان اين عبارت شبهكد
if
را در زبان
C++
بصورت زير نوشت
if (grade >= 60 )
cout << “Passed”;
اگر به كد
C++
دقت كنيد متوجه شباهت نزديك آن با شبهكد خواهيد شد و نقش شبهكد به عنوان يك ابزار توسعه برنامه بخوبي آشكار ميشود.
در شكل 4-4 دياگرام فعاليت عبارت تكانتخابي
if
نشانداده شده است. اين دياگرام حاوي يكي از مهمترين نمادها در يك دياگرام فعاليت است. نماد لوزي يا نماد تصميم نشان ميدهد كه بايد در آن نقطه تصميمي اتخاذ گردد. نماد تصميمگيري بر اين نكته دلالت دارد كه روند كار در امتداد مسيري به كار ادامه خواهد داد كه توسط نماد وابسته نگهبان شرط تعيين ميشود (آيا شرط برقرار است يا خير). هر فلش يا بردار انتقال خارج شده از يك نماد تصميم داراي يك نگهبان شرط است (در درون براكتهاي مربعي در بالا يا كنار فلش انتقال جاي ميگيرد). اگر شرط يك نگهبان شرط برقرار باشد، روند كار وارد وضعيت عملي ميشود كه فلش انتقال به آن اشاره ميكند. در شكل 4-4 اگر
grade
بزرگتر يا برابر
60
باشد، برنامه كلمه
"Passed"
را بر روي صفحه نمايش چاپ كرده و سپس انتقال به وضعيت پاياني در اين فعاليت ميرسد. اگر
grade
كوچكتر از
60
باشد، بلافاصله برنامه به وضعيت پاياني منتقل ميشود، بدون اينكه پيغامي چاپ كند.
شكل 4-4 | دياگرام فعاليت عبارت
if
.
در فصل اول آموختيم، تصميمگيري ميتواند براساس شرطهايي صورت گيرد كه حاوي عملگرهاي رابطهاي يا برابري هستند. در واق
ع
، در
C++
يك شرط ميتواند بر پايه هر عبارتي ارزيابي گردد، اگر عبارت با صفر ارزيابي شود، با آن همانند
false
(عدم برقراري شرط
) رفتار خواه
د شد و اگر عبارت با مقداري غير از صفر ارزيابي گردد، با آن همانند
true
(برقراري شرط) رفتار ميشود. زبان
C++
داراي نوع داده بولي
(
bool)
براي متغيرهايي است كه فقط قادر به نگهداري مقادير
true
و
false
هستند، كه هر دو جزء كلمات كليدي در
C++
ميباشند.
قابليت حمل
براي حفظ سازگاري با نسخههاي قبلي
C
كه از اعداد صحيح براي مقادير بولي استفاده ميكردند، ميتوان براي عرضه يك مقدار بولي
true
از هر مقدار غيرصفري استفاده كرد (معمولاً كامپايلرها از
1
استفاده ميكنند). براي عرضه يك مقدار بولي
false
نيز ميتوان از مقدار صفر استفاده كرد.
دقت كنيد كه عبارت
if
يك عبارت تكورودي
/
تكخروجي است. همچنين دياگرامهاي مابقي عبارات كنترلي نيز حاوي نمادهاي وضعيت اوليه، فلشهاي انتقال، وضعيت اجرا، تصميمگيري و وضعيت پاياني هستند. به اين نحوه نمايش عبارات كنترلي روش مدل برنامهنويسي اجرائي/تصميمگيري گفته ميشود.
ميتوانيم هفت صندوق را تصور كنيم كه هر كدام فقط حاوي دياگرامهاي فعاليت
UML
خالي از يكي از هفت نوع عبارت (ساختار) كنترلي است. وظيفه برنامهنويس جفتوجور كردن برنامه با سرهمبندي كردن دياگرام فعاليت به هر تعداد از هر نوع عبارت كنترلي تصريح شده در الگوريتم است كه فقط به دو روش قابل انجام است، روش پشتهاي و تودرتو. در ادامه وضعيتهاي عمل و تصميمگيري را با عبارات اجرايي و نگهبانان شرط به روش مقتضي پر ميكند. در ارتباط با نوشتن انواع روشهايي كه ميتواند در عبارات اجرايي و تصميمگيري بكار گرفته شوند، صحبت خواهيم كرد.
شكل 4-4 | دياگرام فعاليت عبارت تك انتخابي
if
.
6-4 عبارت انتخاب
if..else
همانطوري كه گفته شد عبارت انتخاب
if
فقط در صورت برقرار بودن شرط، عملي را به اجرا در ميآورد، در غير اينصورت از روي عبارت يا عبارات پرش ميكند. عبارت انتخاب
if..else
اين امكان را به برنامهنويس ميدهد كه تعيين كند چه اعمالي در برقرار بودن شرط اجرا شوند و چه اعمالي در حالت برقرار نبودن شرط به اجرا در آيند. براي مثال، در شبهكد زير
If Student’s grade is greater than or equal to 60
Print “Passed”
Else
Print “Failed”
اگر نمره دانشآموز برابر 60 يا بالاتر باشد، عبارت
“Passed”
به نمايش در ميآيد و اگر كمتر از آن باشد عبارت "
Failed
". در هر دو حالت پس از انجام عمل چاپ، عبارت شبهكد بعدي به اجرا گذاشته خواهد شد.
عبارت شبهكد
if..else
مطرح شده را ميتوان در زبان
C++
و به فرم زير نوشت:
if (grade >= 60 )
cout << “Passed”;
else
cout << “Failed”;
به دندانهدار بودن بدنه شرط
else
دقت كنيد كه با خطوط بالاي خود در شرط
if
يكسان قرار گرفتهاند.
برنامهنويسي ايدهال
دندانهدار نوشتن هر دو قسمت بدنه عبارت
if..else
خوانائي برنامه را افزايش ميدهد.
در شكل 5-4 روند كنترل جريان در يك عبارت (ساختار)
if..else
نشان داده شده است. مجدداً توجه كنيد (در كنار وضعيت اوليه، فلشهاي انتقال و وضعيت پاياني) كه نمادهاي بكار رفته در اين دياگرام فعاليت عبارتند از نمادهاي عمل و تصميمگيري و تاكيد ما بر مدلسازي عمل/ تصميمگيري است. مجدداً به صندوقهاي خالي از دياگرامهاي فعاليت عبارات انتخاب دوگانه فكر كنيد كه برنامهنويس ميتواند به روش پشتهاي يا تودرتو با ساير دياگرامهاي فعاليت ساختارهاي كنترلي بكار گيرد تا مبادرت به پيادهسازي الگوريتم كند.
شكل 5-4 دياگرام فعاليت عبارت دو انتخابي
if..else
عملگر شرطي
(?:)
زبان
C++
حاوي عملگر شرطي
(?:)
، است كه قرابت نزديكي با عبارت
if..else
دارد. عملگر شرطي
C++
تنها عملگر
ternary
است، به اين معني كه سه عملوند دريافت ميكند. عملوندها به همراه عملگر شرطي تشكيل عبارت شرطي را ميدهند. عملوند اول نشاندهنده شرط ميباشد، عملوند دوم مقداري است كه در صورت
true
بودن شرط انتخاب ميشود و عملوند سوم مقداري است كه در صورت برقرار نبودن شرط يا
false
بودن آن انتخاب ميشود. براي مثال عبارت زير
cout << (grade >= 60 ? ”Passed” : ”Failed” );
حاوي يك عبارت شرطي،
ا
ست كه در صورت برقرار بودن شرط
grade >= 60
رشته
“Passed”
ارزيابي ميشود، اما اگر شرط برقرار نباشد، رشته
“Failed”
بكار گرفته خواهد شد. از اينرو
عملكرد اين عبارت شرطي دقيقا همانند عملكرد عبارت
if..else
قبلي است. عملگر شرطي از تقدم پايينتري برخوردار است و از اينرو معمولا كل عبارت شرطي را در درون پرانتزها قرار ميدهند.
اجتناب از خطا
براي اجتناب از مشكل اولويت و روشن شدن مطلب، سعي كنيد عبارات شرطي (كه در عبارات بزرگ شركت ميكنند) را در درون پرانتزها قرار دهيد.
مقادير موجود در يك عبارت شرطي قادر به اجرا شدن نيز هستند. براي مثال عبارت شرطي زير مبادرت به چاپ
"Passed"
يا
"Failed"
ميكند.
grade >= 60 ? cout << "Passed" : cout << "Failed";
اين عبارت به صورت زير تفسير ميشود «اگر
grade
بزرگتر يا مساوي
60
باشد، پس
cout<<"Passed"
، در غير اينصورت
".cout<<"Faild"
همچنين اين عبارت قابل مقايسه با عبارت
if..else
قبلي است. عبارات شرطي را ميتوان در مكانهاي از برنامه كه امكان استفاده از
if..else
وجود ندارد، بكار گرفت.
عبارات تودرتوي
if..else
عبارت تودرتوي
if..else
براي تست چندين شرط با قرار دادن عبارتهاي
if..else
در درون عبارتهاي
if..else
ديگر است. براي مثال، عبارت شبهكد زير، حرف
“A”
را براي نمرههاي بزرگتر يا برابر
90
،
“B”
را براي نمرههاي در محدودة
80-89
،
“C”
را براي نمرههاي در محدودة
70-79
،
“D”
را براي نمرههاي در محدودة
60-69
و
“F”
را ساير نمرات به چاپ ميرساند.
If student’s grade is greater then or equal to 90
Print “A”
Else
If student’s grade is greater than or equal to 80
Print “B”
Else
If student’s grade is greater than or equal to 70
Print “C”
Else
If student’s grade is greater than or equal to 60
Print “D”
Else
Print “F”
عبارت شبهكد بالا را ميتوان در زبان
C++
و به فرم زير نوشت:
if (studentGrade>=90) // 90 and above gets "A"
cout << “A”;
else
if (studentGrade>=80) // 80-89 gets "B"
cout << “B”;
else
if (strudentGrade>=70) // 70-79 gets "C"
cout << “C”;
else
if (studentGrade>=60) // 60-69 gets "D"
cout << “D”;
else // less than 60 gets "F"
cout << “F”;
اگر مقدار
studentGrade
بزرگتر يا مساوي
90
باشد، اولين شرط از پنج شرط برقرار شده و فقط عبارت
cout
قرار گرفته در بدنه اولين شرط به اجرا در ميآيد. پس از اجراي اين عبارت از بخش
else
خارجي عبارت
if..else
عبور خواهد شد.
برنامهنويسي ايدهال
قبل و بعد از هر عبارت كنترل يك خط خالي قرار دهيد تا بتوان عبارتهاي كنترل را از ساير نقاط برنامه تشخيص داد.
اكثر برنامهنويسان
C++
ترجيح ميدهند كه عبارت
if..else
را با استفاده از كلمه كليدي
else if
و بصورت زير در برنامههاي خود بنويسند:
if (studentGrade>=90) // 90 and above gets "A"
cout << “A”;
else if (studentGrade>=80) // 80-89 gets "B"
cout << “B”;
else if (studentGrade>=70) // 70-79 gets "C"
cout << “C”;
else if (studentGrade>=60) // 60-69 gets "D"
cout << “D”;
else // less than 60 gets "F"
cout << “F”;
هر دو حالت معادل يكديگرند، اما نوع آخر در نزد برنامهنويسان از محبوبيت بيشتري برخوردار است. چرا كه از دندانهدار كردن عميق كد به طرف راست اجتناب ميشود.
كارائي
يك عبارت
if..else
تودرتو ميتواند بسيار سريعتر از يك سري عبارت
if
عمل كند، چرا كه احتمال دارد شرطي در ابتداي عبارت
if..else
برقرار شود و كنترل برنامه زودتر از اين قسمت خارج گردد.
كارائي
در يك عبارت
if..else
تودرتو، شرطهايي كه امكان برقرار شدن
(true)
آنها بيشتر است در ابتداي عبارت
if..else
تودرتو قرار دهيد. در اينحالت امكان اجراي سريعتر عبارت
if..else
فراهم ميآيد.
مشكل
dangling-else
هميشه كامپايلر
C++
يك
else
را با يك
if
در نظر ميگيرد، مگر اينكه خلاف آنرا با استفاده از براكتها مشخص كنيد. به اين مشكل
dangling-else
ميگويند. براي مثال،
if ( x > 5 )
if ( y > 5 )
cout << "x and y are > 5";
else
cout << "x is <=5";
به نظر ميرسد بر اين نكته دلالت دارد كه اگر
x
بزرگتر از
5
باشد، عبارت
if
تودرتو تعيين ميكند كه آيا
y
نيز بزرگتر از
5
است يا خير. اگر چنين باشد، رشته
"x and y are > 5"
در خروجي چاپ ميشود. در غير اينصورت اگر
x
بزرگتر از
5
نباشد، بخش
else
از عبارت
if..else
رشته
"x is <=5"
را چاپ خواهد كرد.
با اين همه امكان دارد عبارت
if
تودرتوي فوق مطابق با انتظار كار نكند. تفسير كامپايلر از عبارت بصورت زير خواهد بود
if ( x > 5 )
if ( y > 5 )
cout << "x and y are > 5";
else
cout << "x is <=5";
كه در آن بدنه اولين عبارت
if
يك عبارت
if..else
تودرتو است. اين عبارت مبادرت به تست بزرگتر بودن
x
از
5
ميكند. اگر چنين باشد، اجرا با تست
y
بزرگتر از
5
ادامه مييابد. اگر شرط دوم برقرار باشد، رشته
"x and y are >5"
به نمايش در خواهد آمد. با اين همه اگر شرط دوم برقرار نباشد، رشته
"x is <=5"
به نمايش در ميآيد، حتي اگر بدانيم كه
x
بزرگتر از
5
است.
براي اينكه عبارت فوق بنحوي كار كند كه از انتظار داريم، بايستي كل عبارت بصورت زير نوشته شود:
if ( x > 5 )
{
if ( y > 5 )
cout << "x and y are > 5";
}
else
cout << "x is <=5";
براكتها به كامپايلر نشان ميدهند كه دومين
if
در بدنه اولين
if
قرار دارد و
else
در ارتباط با اولين
if
ميباشد.
بلوكها
معمولا عبارت انتخاب
if
فقط منتظر يك عبارت در بدنه خود است. به همين ترتيب، هر يك از بخشهاي
else
و
if
در يك عبارت
if..else
انتظار مقابله با يك عبارت در بدنه خود را دارند. براي وارد كردن چندين عبارت در بدنه يك
if
يا در بخشهاي
if..else
، عبارات را در درون براكتها
( { } )
قرار دهيد. به مجموعهاي از عبارات موجود در درون يك جفت براكت، بلوك ميگويند.
مهندسي نرمافزار
يك بلوك ميتواند در هر كجاي برنامه كه يك عبارت منفرد ميتواند در آنجا قرار داده شود، جاي گيرد.
مثال زير شامل يك بلوك در بخشي از
else
يك عبارت
if..else
است.
if (studentGrade>=60)
cout << “Passed.\n”;
else
{
cout << “Failed.\n”;
cout << "You must take this course again.\n"
}
در اين مورد، اگر
studentGrade
كمتر از
60
باشد، برنامه هر دو عبارت موجود در بدنه
else
را اجرا كرده و پيغامهاي زير را چاپ ميكند.
Failed
You must take this course agein.
به براكتهاي احاطهكننده دو عبارت در ضابطه
else
دقت كنيد. اين براكتها مهم هستند. بدون اين براكتها، عبارت
cout << "You must take this course again.\n";
در خارج از بدنه بخش
else
قرار ميگيرد و صرفنظر از اينكه شرط برقرار باشد يا خير، اجرا خواهد شد. اين مثال نمونهاي از يك خطاي منطقي است.
خطاي برنامهنويسي
فراموش كردن يك يا هر دو براكت كه تعيين محدودة يك بلوك هستند، ميتواند موجب خطاي نحوي يا منطقي در برنامه شود.
برنامهنويسي ايدهال
هميشه از براكتها در عبارت
if..else
(يا هر عبارت كنترلي) استفاده كنيد تا جلوي حوادث ناخواسته گرفته شود، بويژه به هنگام افزودن عباراتي به يك
if
يا ضابطه
else
در ادامه كار. براي اينكه جلوي فراموشكاري گرفته شود، برخي از برنامهنويسان در همان ابتداي كار و قبل از اينكه حتي عبارتي تايپ كرده باشد، براكتهاي شروع و پايين را تايپ ميكنند و سپس عبارات مورد نظر را در درون آنها قرار ميدهد.
همانند يك بلوك كه ميتواند در هر كجاي كه يك عبارت منفرد وجود دارد جايگزين گردد، همچنين امكان داشتن عبارت
null
(يا عبارت تهي) وجود دارد. عبارت تهي با جايگزين كردن يك سيمكولن (
;
) بجاي يك عبارت مشخص ميشود.
خطاي برنامهنويسي
قرار دادن يك سيمكولن بلافاصله پس از شرط در يك عبارت
if
موجب رخ دادن خطاي منطقي در عبارات
if
تك انتخابي و خطاي نحوي در عبارات
if..else
دو انتخابي خواهد شد.