خرید بک لینک

ساختارهای کنترلی (قسمت دوم)

در برنامه نویسی ساخت یافته، هر برنامه از 3 ساختار کنترلی بنام: ساختار ترتیب، ساختار انتخاب و ساختار تکرار تشکیل می گردد. از آنجا كه اين 3 ساختار، نحوه و ترتيب اجراي برنامه را كنترل مي كنند، به آنها ساختارهاي كنترلي گفته مي شود. تا کنون فقط با برنامه هایی سروکار داشته ایم که از ساختار ترتیب استفاده می کرده اند، چرا که دستورهای زبان C در حالت عادی به همان ترتیبی که نوشته شده اند، یکی پس از دیگری اجرا می شوند.

اما زبان C دارای 3 نوع ساختار انتخاب می باشد که عبا رتند از : ساختار if یا ساختار تک انتخابی، ساختار if / else یا ساختار دو انتخابی و ساختار switch یا ساختار چند انتخابی. علاوه براین، این زبان دارای 3 نوع ساختار تکرار بنامهای while، for و do / while نیز می باشد که هریک را بطور کامل شرح خواهیم داد.

آنچه در ادامه مطالب خواهید خواند

1 -ساختار تكرار for

2- حلقه do / while

3- Switch/ case

4- دستورات break و continue

و کاربرد هر یک از آنها همراه با مثال


ساختار تكرار for

همانگونه كه در مثال مربوط به حل مسئله فاكتوريال ديده مي شود، گاهي نياز به حلقه تكراري داريم كه به تعداد دفعات مشخصي تكرار گردد. در چنين مواقعي با استفاده از يك متغير شمارنده، تعداد تكرارها را تا رسيدن به مقدار مورد نظر می شماریم و سپس به حلقه پایان می دهیم. به چنین حلقه هایی، تکرار تحت کنترل شمارنده یا تکرار معین می گوییم، چرا که تعداد تکرار ها از قبل مشخص است. چنین حلقه ای دارای 3 جزء اصلی می باشد:

1- مقداردهی اولیه به متغیر شمارنده حلقه
2- شرط پایان حلقه (پایان شمارش)
3- نحوه افزایش متغیر شمارنده

از آنجا که در تمام حلقه هایی که تکرار معین دارند، همین ساختار استفاده می شود؛ در اکثر زبانهای برنامه سازی یک ساختار تکرار ویژه، بنام حلقه for، برای اینکار در نظر گرفته شده است. اما در این بین، حلقه تکرار for در زبان C دارای ویژگیهای خاصی است که آنرا از سایر زبانها متمایز کرده و به آن قدرت بسیار بالایی داده است. شکل کلی این دستور بصورت زیر است:

for ( ; ; ) ;

وظایف عبارات فوق بشرح زیر است :

1- ، مقداردهی اولیه به متغیر حلقه

2- ، شرط اجرای حلقه

3- ،نحوه افزایش متغیر حلقه

البته همانندموارد قبل بازهم قسمت می تواند یک دستور مرکب باشد. نحوه کار حلقه بدینصورت است که در ابتدای شروع حلقه فقط برای یکبار اجرا می شود. سپس عبارت بررسی می گردد و در صورتیکه درست ارزیابی شود (≠ 0)، آنگاه دستور اجرا شده و سپس به ابتدای حلقه باز می گردد. از اجرای دوم به بعد، ابتدا عبارت اجرا می گردد (یعنی متغیر حلقه افزایش می یابد) و سپس عبارت بررسی می گردد و مجددا درصورت درست بودن، حلقه تکرار می شود. اینکار تا زمانیکه مقدار عبارت نادرست ( = 0) ارزیابی شود، تکرار می گردد. به محض اینکه این اتفاق بیفتد، کنترل اجرا به دستور پس از حلقه انتقال می یابد.
درحقیقت هر حلقه for معادل با حلقه while زیر است:

;
while () {
;
;
}

بعنوان یک مثال ساده، تکه برنامه زیر اعداد بین 0 تا 100 را چاپ می نماید:

int count;
for (count = 0; count <= 100; count ++)
printf(“%d “,count);

اگر بخواهيم تنها مضارب 5 چاپ شوند، حلقه را به شكل زير تغيير مي دهيم:

for (count = 0; count <= 100; count += 5)

حتي مي توان مضارب 5 را از آخر به اول چاپ كرد:

for (count = 100; count> = 0; count -= 5)

قسمت شرط مي تواند يك شرط مركب نيز باشد، بعنوان مثال:

for (count = 0; count <100 && sw==1; count ++)

كه در اينصورت در هربار اجراي حلقه، علاوه بر مقدار شمارنده، مقدار متغير sw نيز بررسي مي گردد.

نكته آخر اينكه قسمت مقدار دهي اوليه و افزايش متغير نيز مي توانند شامل چند عبارت باشند كه در اينصورت با كاما از يكديگر جدا مي شوند. بعنوان مثال:

for (a = 0, b = 100; b – a> 50; a++, b--)

در ادامه یک مثال کاملتر برای تشریح این حلقه آمده است:

برنامه 5) برنامه ای بنویسید که تعدادی عدد را از کاربر دریافت و 2 عدد بزرگتر و مجموع آنها را محاسبه و چاپ نماید.

#include
void main() {
int i, n, number;
int sum, max1, max2;
printf(“please enter n : “);
scanf(“%d”,&n);
sum = 0;
max1 = max2 = -1;
for (i=1 ; i
printf(“enter number : “);
scanf(“%d”,&number);
sum += number;
if (number> max1) {
max2 = max1;
max1 = number;
}
else if (number> max2)
max2 = number;
} //end for
printf(“Sum = %d, Maximum 1=%d, Maximum 2= d”, sum, max1, max2);
}

نكته جالب در مورد حلقه for آنستكه مي توان هريك از 3 عبارت فوق را حذف كرد. به مثالهاي زير توجه كنيد:

for (;i<100; i++)

مقداردهي اوليه حذف شده است. اين در صورتي است كه بنحوي قبل از شروع حلقه، مقدار متغير i تعيين شده باشد.

for (i= 0;i<100;)

نحوه افزايش متغير حلقه حذف شده است. اين مورد زماني بكار مي رود كه نحوه افزايش متغير حلقه پيچيده بوده و توسط برنامه نويس در داخل حلقه انجام شود.

for (;i<100;)

هر دو مورد فوق حذف شده است.

for (i=0; ;i++)

شرط ادامه حلقه حذف شده است. اين مورد زياد متداول نيست و ممكن است باعث شود حلقه براي هميشه اجرا شود. در چنين مواردي حتما بايد در داخل حلقه با استفاده از دستور break (كه در قسمتهاي بعدي توضيح داده خواهد شد)، راهي براي خروج از حلقه قرار داده شود.

(;;)for

}

; دستوراول

; دستور دوم

.

.

.

; دستور n ام

}

می بینیم که ، for فاقد مقدار اولیه ، شرط حلقه ، و گام حرکت است. این دستور برای اجرای حلقه ی تکرار بی نهایت(حلقهی تکراری می باشد که شرط پایان ندارد) مورد استفاده قرار می گیرد. برای اتمام این حلقه باید کلیدCTRL+BREAK را فشرد.

حال اگر بخواهیم یک حلقه ی تکرار را در حلقه ای دیگر قرار دهیم،از اصطلاحی به عنوان حلقه های تکرار تو در تو استفاده می کنیم .

یک اصل مهم در رابطه با حلقه های تکرار تو در تو:

این است که ؛ به ازای هر بار اجرای حلقه تکرار خارجی ، حلقه تکرار داخلی به طور کامل اجرا می شود. انتهای حلقه تکرار داخلی ، زودتر از حلقه ی تکرار خارجی مشخص می شود.

مثلا:

for (i=0;i<5;i++

}

.....

for(j=0;j<7;j++)

{

…..

{

.....

{

(حلقه ی تکرار با اندیس i ، حلقه ی خارجی و حلقه با اندیس j ، حلقه ی داخلی می باشد)

ناگفته نماند که اگر حلقه های تکرار تو در تو ، از یکجا شروع و به یکجا ختم شوند، حلقه ی خارجی نیاز به { } ندارد.

مثلا:

for(i=0;i<5;i++)

(++ for(j=0;j<=8;j

}

.....

{

حلقه do / while

همانگونه كه در قسمت الگوريتمها توضيح داده شد، در بعضي مواقع لازم است كه شرط ، در انتهاي حلقه بررسي گردد. دستور do / while از نوع حلقه هايي است كه ابتدا دستورات را اجرا كرده و سپس شرط ادامه حلقه را بررسي مي نمايد. شكل كلي اين دستور بصورت زير است:

do
;
while () ;

نحوه كار اين حلقه به اين صورت است كه ابتدا دستور اجرا مي گردد، سپس شرط حلقه بررسي شده و درصورتيكه درست بود، به ابتداي حلقه باز گشته و آن را مجددا اجرا مي كند. البته دستور مي تواند يك دستور مركب باشد.

بعنوان يك مثال كوچك، ممكن است شما از كاربر خواسته ايد كه اعلام كند آيا مايل به ادامه هست يا خير؟ وي بايد پاسخ y يا n بدهد، اما ممكن است يك حرف اشتباه (مانند m) وارد كند. قصد داريم تكه برنامه اي بنويسيم كه عمل دريافت پاسخ را تا زمانيكه يك حرف درست وارد شود، تكرار كند. مسلم است كه بايد ابتدا يك پاسخ وارد شود و سپس درستي آن بررسي گردد.

char answer;
do {
printf("Do you want to continue (y/n) ?");
answer = getch();
} while (answer != 'y' && answer != 'n') ;

بعنوان يك نمونه كاملتر به مثال زير توجه كنيد.

برنامه 6) فرض كنيد نمرات يك گروه از دانشجويان بصورت درجه بندي (A, B, C and D) آماده شده است. برنامه اي بنويسيد كه نمرات دانشجويان را دريافت و در پايان درصد هريك از نمرات را محاسبه و چاپ نمايد. در ضمن از آنجا كه تعداد دانشجويان از قبل مشخص نيست، كاربر در انتهاي نمرات، حرف Q (مخفف Quit) را وارد مي نمايد.

#include
void main() {
int aCount, bCount, cCount, dCount, n;
char grade;
aCount = bCount = cCount = dCount = n = 0;
do {
printf("Enter grade (Q for Quit) : ");
grade = getch() ;
n ++;
if (grade == 'A') aCount ++;
else if (grade == 'B') bCount ++;
else if (grade == 'C') cCount ++;
else if (grade == 'D') dCount ++;
else if (grade == 'Q') n --;
else {
printf("Wrong grade, try again.\n");
n --;
}
} while (grade != 'Q' ) ;
printf("Statistics :\n");
printf("Grade A : %f percent\n", float(aCount)/float(n));
printf("Grade B : %f percent\n", float(bCount)/float(n));
printf("Grade C : %f percent\n", float(cCount)/float(n));
printf("Grade D : %f percent\n", float(dCount)/float(n));
} // end main

Switch/ case

اگر مجددا به برنامه 6 دقت كنيد، خواهيد ديد كه در بعضي موارد قصد داريم برحسب مقادير مختلف يك عبارت (در اينجا مقدار متغير grade)، عمليات متفاوتي را انجام دهيم. گرچه اينكار با استفاده از دستورات if / else متداخل قابل انجام است، اما ساختار مناسبتري نيز براي اينكار وجود دارد، كه به آن ساختار چندانتخابي مي گوييم. شكل كلي ان ساختار بصورت زير است:

switch () {
case : ;
;
…
;
case : ;
;
…
;
…
default : ;
;
…
;
}

برنامه 7) برنامه 6 را با استفاده از دستور switch / case بازنويسي نماييد. برنامه را بگونه اي بنويسيد كه حروف بزرگ و كوچك هردو مورد قبول واقع شود.

#include
void main() {
int aCount, bCount, cCount, dCount, n;
char grade;
aCount = bCount = cCount = dCount = n = 0;
do {
printf("Enter grade (Q for Quit) : ");
grade = getch() ;
n ++;
switch (grade) {
case 'A' :
case 'a' : aCount ++; break ;
case 'B' :
case 'b' : bCount ++; break ;
case 'C' :
case 'c' : cCount ++; break ;
case 'D' :
case 'd' : dCount ++; break ;
case 'Q' :
case 'q' : n--; break ;
default : printf("Wrong grade, try again.\n");
n --;
} //end switch
} while (grade != 'Q' ) ;
printf("Statistics :\n");
printf("Grade A : %f percent\n", float(aCount)/float(n));
printf("Grade B : %f percent\n", float(bCount)/float(n));
printf("Grade C : %f percent\n", float(cCount)/float(n));
printf("Grade D : %f percent\n", float(dCount)/float(n));
} // end main

برنامه 8) برنامه اي بنويسيد كه يك عدد، يك عملگر و يك عدد ديگر را از كاربر دريافت و پس از اعمال عملگر برروي دو عدد، حاصل را چاپ نمايد.

#include
void main() {
int number2, number2, result;
char op ;
printf("Please enter number1 operator number2 : ");
scanf("%d %c %d",&number1, &number2, &op, &number3);
result = 0;
switch (op) {
case '+' : result = number1 + number2 ; break;
case '-' : result = number1 - number2 ; break;
case '*' : result = number1 * number2 ; break;
case '/' : if (number2 != 0) result = number1 / number2 ;
else printf("There is no answer!\n");
break;
case '%' : if (number2 != 0) result = number1 % number2 ;
else printf("There is no answer!\n");
break;
default : printf("invalid operator!\n");
}
printf("Result = %d",&result);
}

انتقال کنترل غیر شرطی

دستور if شرطی را بررسی کرده و بر اساس نتیجه ی شرط دستوراتی را نیز انجام می دهد. در زبان برنامه نویسی C دستورالعملهایی وجود دارند که بدون تست شرطی می توانند کنترل اجرای برنامه را از نقطهای به نقطه ی دیگر منتقل کنند . این دستورات را انتقال کنترل غیر شرطی می گویند.

دستورات کنترل غیر شرطی شامل دستور break،continue و goto می باشد

دستورات break و continue

اين دستورات قادرند مسير اجراي برنامه را در يك حلقه تكرار تغيير دهند. البته اين تغيير مسير بصورت كنترل شده بوده و همانند دستور goto نمي توان به هرجاي دلخواه پرش كرد.

چنانچه دستور break در يك ساختار while، for، do/while ويا switch بكار رود، باعث مي شود كه بلافاصله كنترل اجراي برنامه از ساختار خارج شده و به اولين دستور پس از ساختار برود. قبلا كاربرد اين دستور را در switch ديده ايد. در اينجا به مثال زير دقت كنيد:

برنامه 9) برنامه 5 را بگونه اي تغيير دهيد كه فقط اعداد مثبت را بپذيرد، و درصورتيكه عدد منفي وارد شد، بلافاصله به عمليات خاتمه داده و نتايج تا همين نقطه را چاپ نمايد.

#include
void main() {
int i, n, number;
int sum, max1, max2;
printf(“please enter n : “);
scanf(“%d”,&n);
sum = 0;
max1 = max2 = -1;
for (i=1 ; i
printf(“enter number : “);
scanf(“%d”,&number);
if (number <0) break; // this is the difference
sum += number;
if (number> max1) {
max2 = max1;
max1 = number;
}
else if (number> max2)
max2 = number;
} //end for
printf(“Sum = %d, Maximum 1=%d, Maximum 2= d”, sum, max1, max2);
}

اما دستور continue فقط در حلقه هاي while، for و do/while بكار مي رود. نحوه عمل آن بدين صورت است كه به محض آنكه كنترل اجرا به اين دستور برسد، بلافاصله از باقيمانده حلقه صرفنظر كرده و مجددا به ابتداي حلقه باز مي گردد و اجراي آن را از سر مي گيرد. در مورد حلقه for، پس از بازگشت به ابتداي حلقه، عمل افزايش مقدار متغير حلقه نيز صورت مي پذيرد.

بعنوان مثال، چنانچه بخواهيم برنامه 9 را بگونه اي تغيير دهيم كه از اعداد منفي صرفنظر كند و آنها را در محاسبات لحاظ نكند، كافيست دستور

if (number <0) break;

را به دستور زير تبديل كنيم:

if (number <0) continue;

دراينصورت، چنانچه عدد منفي باشد، بدون اينكه محاسبات بعدي انجام شوند، كنترل به ابتداي حلقه بازگشته و عدد بعدي را دريافت مي كند.

از مقالات مسعود اشرفی

برچسب: نویسنده: rfmw تاريخ: دوشنبه 30 شهريور 1388 ساعت: 16:7

صفحه بندی