ساختارهای کنترلی در برنامه نویسی ساختیافته، هر برنامه از 3 ساختار کنترلی بنام: ساختار ترتیب، ساختار انتخاب و ساختار تکرار تشکیل می گردد. از آنجا كه این 3 ساختار، نحوه و ترتیب اجرای برنامه را كنترل می كنند، به آنها ساختارهای كنترلی گفته می شود. تا کنون فقط با برنامه هایی سروکار داشته ایم که از ساختار ترتیب استفاده می کرده اند، چرا که دستورهای زبان C در حالت عادی به همان ترتیبی که نوشته شده اند، یکی پس از دیگری اجرا می شوند. اما زبان C دارای 3 نوع ساختار انتخاب می باشد که عبا رتند از : ساختار if یا ساختار تک انتخابی، ساختار if / else یا ساختار دو انتخابی و ساختار switch یا ساختار چند انتخابی. علاوه براین، این زبان دارای 3 نوع ساختار تکرار بنامهای while، for و do / while نیز می باشد که هریک را بطور کامل شرح خواهیم داد. قرارداد: توجه کنید که در هنگام تشریح یک دستور، خود دستور با رنگ آبی و عملگرهای آن مانند () با رنگ قرمز نشان داده می شوند. قسمتهایی که در داخل <> قرار می گیرند، عبارت یا دستوری هستند که باید در هنگام استفاده جایگزین گردند. ساختار انتخاب if این دستور به شکل زیر استفاده می شود: if (<expresion>) <statement>; نحوه کار بدینصورت است که ابتدا عبارت موجود در قسمت <expression> ارزیابی می شود. در صورتیکه درست ارزیابی گردد، دستور قسمت <statement> اجرا خواهد شد و در صورتیکه نادرست باشد، بدون اینکه دستور قسمت <statement> را اجرا کند به دستور بعدی خواهد رفت. این دستور می تواند بصورت زیر نیز استفاده گردد: if (<expresion>) <statement 1>; else <statement 2>; در اینصورت ابتدا عبارت موجود در قسمت <expression> ارزیابی می شود. در صورتیکه درست ارزیابی گردد، دستور قسمت <statement 1> اجرا خواهد شد، و در صورتیکه نادرست باشد، دستور قسمت <statement 2> اجرا خواهد شد. در هر حال فقط یکی از این دو قسمت اجرا خواهد گردید. دقت کنید که پرانتز استفاده شده پس از دستور if برخلاف برخی زبانهای دیگر، اجباری است. علاوه براین، در این دستور نیازی به استفاده از then نمی باشد. بعنوان مثال چنانچه متغیر grade حاوی نمره دانشجو باشد و بخواهیم بر مبنای نمره وی، پیغام مناسبی چاپ کنیم، می توانیم از دستور زیر استفاده کنیم: if (grade> = 10) printf(“Passed !”); else printf(“Failed!”); در حالت عادی دستور if منتظر یک دستور در بدنه خود می باشد، اما چنانچه می خواهید چندین دستور را در بدنه یک دستور if دهید، باید آنها را در داخل آکولاد باز وبسته { } قرار دهید. این مجموع دستورات را یک دستور مرکب می گویند. بطور کلی در زبان C هرجا که می توان یک دستور قرار داد، می توان از یک دستور مرکب نیز استفاده کرد. به یک دستور مرکب، بلوک نیز گفته می شود. بنابراین صورت کلی دستور if به شکل زیر است: if (<expression>) { <statement 1> ; <statement 2> ; …. <statement n> ; } else { <statement 1> ; <statement 2> ; ……. <statement m> ; } توجه کنید که وجود قسمت else اختیاری است و در ضمن ممکن است یکی از دو قسمت دارای دستور ساده و دیگری دارای دستور مرکب باشد. بعنوان یک مثال کاملتر به برنامه زیر توجه کنید: برنامه 1) برنامه ای بنویسید که ضرایب یک معادله درجه 2 را دریافت و ریشه های آن را محاسبه و چاپ نماید. #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <math.h> void main() { int a, b, c; float x1, x2, delta; clrscr(); printf(“Please enter a, b and c : “); scanf(“%d %d %d”, &a, &b, &c); if (a==0) { printf(“wrong equation!”); exit(1) ; } delta = b*b – 4*a*c; if (delta <0) printf(“No answer !”); else if (delta == 0) { x1 = -b / (2*a); printf(“There is one answer, x = %f”,x1); } else { delta = sqrt(delta); x1 = (-b+delta) / (2*a); x2 = (-b-delta) / (2*a); printf(“There are two answers, x1= %4.2f and x2= %4.2f”, x1, x2); } } Please enter a, b and c : 3 -7 2 There is two answers, x1 = 2.00 and x2 = 0.33 چندین نكته درمورد برنامه بالا قابل ذكر است. 1- در این برنامه از 2 تابع جدید استفاده شده است.اولی تابع sqrt كه یك عدد را به عنوان ورودی دریافت و جذر آن را باز می گرداند. این تابع در فایل math.h تعریف شده است. و دیگری تابع exit كه باعث می شود اجرای برنامه خاتمه یابد. این تابع نیز در فایل stdlib.h تعریف شده است. 2- به نحوه دندانه گذاری در برنامه دقت كنید، هرجا كه بلوك جدیدی ایجاد شده است، دستورات آن حدود 3 كاراكتر جلوتر نوشته شده اند. اینكار باعث می شود كه خوانایی برنامه افزایش یابد. 3- توجه كنید كه همانطور كه قبلا نیز گفته شد، خروجی یك عبارت مقایسه ای، یك عدد است كه 0 نشانه نادرست و هر عدد دیگر نشانه درست است. بنابراین در قسمت شرط یك دستور if می توان بجای یك عبارت مقایسه ای، هر عبارت دیگری كه یك مقدار عددی بازگرداند نیز قرار داد! بعنوان مثال می توان بجای دستور if (a==0) … از دستور زیر استفاده كرد: if (!a) … دراینصورت چنانچه a برابر صفر باشد، نادرست تلقی خواهد شد و در نتیجه نقیض آن یعنی ! ، درست محسوب می گردد. یك روش متداول استفاده از دستور if، استفاده از if های تودرتو می باشد كه در مثال بالا نیز دیده می شود. دراینحالت مجموعه ای از عبارات if-else-if بصورت متداخل قرار داده می شوند. بعنوان نمونه به مثال زیر توجه كنید: if (grade> = 18) printf("good!"); else if (grade> = 15) printf("medium!"); else if (grade> = 12) printf("rather weak!"); else if (grade> = 10) printf("weak"); else printf("failed!"); در چنین دستوری، كلیه شرطها بترتیب از بالا به پایین بررسی شده و به محض اینكه یكی از آنها درست باشد، دستور مربوط به آن اجرا شده و از بقیه دستورات صرفنظر می گردد. درصورتیكه هیچ یك از شرطها درست نباشد، دستور مربوط به آخرین else اجرا می گردد. درچنین حالتی توصیه می گردد كه شرطهای نادر را كه امكان وقوع آنها كم است، در انتهای كار بررسی نمایید، تا تعداد مقایسه كمتری صورت پذیرد. مشكلی كه در مورد if های تودرتو پیش می آید، مسئله تعیین if مربوط به هر else است. بعنوان مثال در مورد دستور زیر، else به كدام if تعلق دارد؟ if (a <b) if (c <d) <statement1>; else <statement2>; همانطور كه از دندانه گذاری نیز مشخص است، else مربوط به دومین if می باشد. یعنی <statement 2> درصورتی اجرا خواهد شد كه a<b درست باشد، اما c<d درست نباشد. بطور كلی طبق قوانین گرامری، هر else مربوط به نزدیكترین if قبل از خود می باشد. اما سوال این است كه اگر بخواهیم else به if اول بازگردد از چه روشی استفاده نماییم. دراینصورت می توان از یكی از دو روش زیر استفاده كرد: if (a < b) if (a <b) { if (c <d) <statement 1> ; if (c <d) <statement1>; else ; } else <statement2>; else <statement2>; بعنوان یك مثال دیگر، به نمونه زیر دقت كنید: if (<c1>) { if (<c2>) if (<c3>) <statement2>; else <statement 3>; // this refer to if (<c3>) } else <statement 4>;//this refer to if <c1> برنامه 2) برنامه ای بنویسید كه 3 عدد را دریافت و حداكثر آنها را چاپ كند. #include <stdio.h> void main() { int a, b, c, max; printf("Please enter 3 numbers :"); scanf("%d %d %d",&a, &b, &c); if (a> b) if (a> c) max = a; else max= c; else if (b> c) max = b; else max = c; printf("Maximum is %d",max); } ساختار تكرار while همانطور كه در بخش الگوریتمها نیز گفته شد، یك ساختار تكرار باعث می شود تا زمانیكه شرط خاصی برقرار است، عملیات مشخصی تكرار گردد. دستور while نیز باعث ایجاد یك حلقه تكرار به شكل زیر می گردد: while (<expression>) <statement>; این دستور باعث می شود تا زمانیكه شرط موجود در قسمت <expression> درست است، دستور قسمت <statement> تكرار شود، و به محض اینكه شرط نادرست گردد، كنترل اجرا به دستور بعد از حلقه می رود. بازهم دستور موجود در قسمت <statement> می تواند یك دستور مركب باشد، دراینصورت دستور بصورت زیر درخواهد آمد: while (<expression>) { <statement1>; <statement2>; ……. <statementn>; } برنامه 3) برنامه ای بنویسید كه یك عدد را دریافت و فاكتوریال آن را محاسبه و چاپ نماید. #include <stdio.h> void main() { int i,number; long int factorial; printf("Please enter number :"); scanf("%d",&number); factorial = 1; i = 1; while (i <= number) { factorial *= i; i ++; } printf("Factorial of %d is %ld"number,factorial); } برنامه 4) برنامه ای بنویسید كه یك متن را از كاربر دریافت و آن را با حروف بزرگ چاپ كند. #include <stdio.h> void main() { char ch; ch = getch() ; while (ch != 13) { if (ch>= 'a' && ch <= 'z') ch -= 32; putch(ch); ch = getch(); } } ساختار تكرار for همانگونه كه در مثال مربوط به حل مسئله فاكتوریال دیده می شود، گاهی نیاز به حلقه تكراری داریم كه به تعداد دفعات مشخصی تكرار گردد. در چنین مواقعی با استفاده از یك متغیر شمارنده، تعداد تكرارها را تا رسیدن به مقدار مورد نظر می شماریم و سپس به حلقه پایان می دهیم. به چنین حلقه هایی، تکرار تحت کنترل شمارنده یا تکرار معین می گوییم، چرا که تعداد تکرار ها از قبل مشخص است. چنین حلقه ای دارای 3 جزء اصلی می باشد: 1- مقداردهی اولیه به متغیر شمارنده حلقه 2- شرط پایان حلقه (پایان شمارش) 3- نحوه افزایش متغیر شمارنده از آنجا که در تمام حلقه هایی که تکرار معین دارند، همین ساختار استفاده می شود؛ در اکثر زبانهای برنامه سازی یک ساختار تکرار ویژه، بنام حلقه for، برای اینکار در نظر گرفته شده است. اما در این بین، حلقه تکرار for در زبان C دارای ویژگیهای خاصی است که آنرا از سایر زبانها متمایز کرده و به آن قدرت بسیار بالایی داده است. شکل کلی این دستور بصورت زیر است: for (<exp1> ; <exp2> ; <exp3> ) <statement>; وظایف عبارات فوق بشرح زیر است : 1- <exp1>، مقداردهی اولیه به متغیر حلقه 2- <exp2>، شرط اجرای حلقه 3- <exp3>،نحوه افزایش متغیر حلقه البته همانندموارد قبل بازهم قسمت <statement> می تواند یک دستور مرکب باشد. نحوه کار حلقه بدینصورت است که در ابتدای شروع حلقه <exp1> فقط برای یکبار اجرا می شود. سپس عبارت <exp2> بررسی می گردد و در صورتیکه درست ارزیابی شود (≠ 0)، آنگاه دستور <statement> اجرا شده و سپس به ابتدای حلقه باز می گردد. از اجرای دوم به بعد، ابتدا عبارت <exp3> اجرا می گردد (یعنی متغیر حلقه افزایش می یابد) و سپس عبارت <exp2> بررسی می گردد و مجددا درصورت درست بودن، حلقه تکرار می شود. اینکار تا زمانیکه مقدار عبارت <exp2> نادرست ( = 0) ارزیابی شود، تکرار می گردد. به محض اینکه این اتفاق بیفتد، کنترل اجرا به دستور پس از حلقه انتقال می یابد. درحقیقت هر حلقه for معادل با حلقه while زیر است: <exp1> ; while (<exp2>) { <statement>; <exp3>; } بعنوان یک مثال ساده، تکه برنامه زیر اعداد بین 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 <stdio.h> 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<n ; 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<1 |