instrukcje sterujące.txt

(14 KB) Pobierz
Instrukcje steruj�ce
Z Wikibooks, biblioteki wolnych podr�cznik�w.
> C > Instrukcje steruj�ce �
Przejd� | Edytuj
< C
Skocz do: nawigacji, wyszukiwania

C jest j�zykiem imperatywnym - oznacza to, �e instrukcje wykonuj� si� jedna po drugiej w takiej kolejno�ci w jakiej s� napisane. Aby m�c zmieni� kolejno�� wykonywania instrukcji potrzebne s� instrukcje steruj�ce.

Na wst�pie przypomnijmy jeszcze, �e wyra�enie jest prawdziwe wtedy i tylko wtedy, gdy jest r�ne od zera, a fa�szywe wtedy i tylko wtedy, gdy jest r�wne zeru.
Spis tre�ci
[ukryj]

    * 1 Instrukcje warunkowe
          o 1.1 Instrukcja if
          o 1.2 Instrukcja switch
    * 2 P�tle
          o 2.1 Instrukcja while
          o 2.2 Instrukcja for
          o 2.3 Instrukcja do..while
          o 2.4 Instrukcja break
                + 2.4.1 Break i p�tle niesko�czone
          o 2.5 Instrukcja continue
    * 3 Instrukcja goto
    * 4 Natychmiastowe ko�czenie programu - funkcja exit
    * 5 Uwagi

[edytuj] Instrukcje warunkowe
[edytuj] Instrukcja if

U�ycie instrukcji if wygl�da tak:

 if (wyra�enie) {
   /* blok wykonany, je�li wyra�enie jest prawdziwe */
 }
 /* dalsze instrukcje */

Istnieje tak�e mo�liwo�� reakcji na nieprawdziwo�� wyra�enia - wtedy nale�y zastosowa� s�owo kluczowe else:

 if (wyra�enie) {
   /* blok wykonany, je�li wyra�enie jest prawdziwe */
 } else {
   /* blok wykonany, je�li wyra�enie jest nieprawdziwe */
 }
 /* dalsze instrukcje */

Przypatrzmy si� bardziej "�yciowemu" programowi, kt�ry por�wnuje ze sob� dwie liczby:

 #include <stdio.h>
 
 int main ()
 {
   int a, b;
   a = 4;
   b = 6;
   if (a==b) {
     printf ("a jest r�wne b\n");
   } else {
     printf ("a nie jest r�wne b\n");
   }
   return 0;
 }

Czasami zamiast pisa� instrukcj� if mo�emy u�y� operatora wyboru (patrz Operatory):

 if (a != 0)
   b = 1/a;
 else
   b = 0;

ma dok�adnie taki sam efekt jak:

 b = (a !=0) ? 1/a : 0;

[edytuj] Instrukcja switch

Aby ograniczy� wielokrotne stosowanie instrukcji if mo�emy u�y� switch. Jej u�ycie wygl�da tak:

 switch (wyra�enie) {
   case warto��1: /* instrukcje, je�li wyra�enie == warto��1 */
     break;
   case warto��2: /* instrukcje, je�li wyra�enie == warto��2 */
     break;
   /* ... */
   default: /* instrukcje, je�li �aden z wcze�niejszych warunk�w nie zosta� spe�niony */
     break;
 }

Nale�y pami�ta� o u�yciu break po zako�czeniu listy instrukcji nast�puj�cych po case. Je�li tego nie zrobimy, program przejdzie do wykonywania instrukcji z nast�pnego case. Mo�e mie� to fatalne skutki:

 #include <stdio.h>
 
 int main ()
 {
   int a, b;
   printf ("Podaj a: ");
   scanf ("%d", &a);
   printf ("Podaj b: ");
   scanf ("%d", &b);
   switch (b) {
     case  0: printf ("Nie mo�na dzieli� przez 0!\n"); /* tutaj zabrak�o break! */
     default: printf ("a/b=%d\n", a/b);
   }
   return 0;
 }

A czasami mo�e by� celowym zabiegiem (tzw. "fall-through") - w�wczas warto zaznaczy� to w komentarzu. Oto przyk�ad:

 #include <stdio.h>
 
 int main ()
 {
   int a = 4;
   switch ((a%3)) {
     case  0:
       printf ("Liczba %d dzieli si� przez 3\n", a);
       break;
     case -2:
     case -1:
     case  1:
     case  2:
       printf ("Liczba %d nie dzieli si� przez 3\n", a);
       break;
   }
   return 0;
 }

Przeanalizujmy teraz dzia�aj�cy przyk�ad:

 #include <stdio.h>
 
 int main ()
 {
   unsigned int dzieci = 3, podatek=1000;
   switch (dzieci) {
      case  0: break; /* brak dzieci - czyli brak ulgi */ 
      case  1: /* ulga  2% */
        podatek = podatek - (podatek/100* 2); 
        break;
      case  2: /* ulga  5% */
        podatek = podatek - (podatek/100* 5);
        break;
      default: /* ulga 10% */
        podatek = podatek - (podatek/100*10);
        break; 
   }
   printf ("Do zap�aty: %d\n", podatek);
 }

[edytuj] P�tle
[edytuj] Instrukcja while

Cz�sto zdarza si�, �e nasz program musi wielokrotnie powtarza� ten sam ci�g instrukcji. Aby nie przepisywa� wiele razy tego samego kodu mo�na skorzysta� z tzw. p�tli. P�tla wykonuje si� dot�d, dop�ki prawdziwy jest warunek.

 while (warunek) {
   /* instrukcje do wykonania w p�tli */
 }
 /* dalsze instrukcje */

Ca�� zasad� p�tli zrozumiemy lepiej na jakim� dzia�aj�cym przyk�adzie. Za��my, �e mamy obliczy� kwadraty liczb od 1 do 10. Piszemy zatem program:

 #include <stdio.h>
 
 int main ()
 {
   int a = 1;
   while (a <= 10) { /* dop�ki a nie przekracza 10 */
     printf ("%d\n", a*a); /* wypisz a*a na ekran*/
     ++a; /* zwi�kszamy a o jeden*/
   }
   return 0;
 }

Po analizie kodu mog� nasun�� si� dwa pytania:

    * Po co zwi�ksza� warto�� a o jeden? Ot� gdyby�my nie dodali instrukcji zwi�kszaj�cej a, to warunek zawsze by�by spe�niony, a p�tla "kr�ci�aby" si� w niesko�czono��.
    * Dlaczego warunek to "a <= 10" a nie "a!=10"? Odpowied� jest do�� prosta. P�tla sprawdza warunek przed wykonaniem kolejnego "obrotu". Dlatego te� gdyby warunek brzmia� "a!=10" to dla a=10 jest on nieprawdziwy i p�tla nie wykona�aby ostatniej iteracji, przez co program generowa�by kwadraty liczb od 1 do 9, a nie do 10.

[edytuj] Instrukcja for

Od instrukcji while czasami wygodniejsza jest instrukcja for. Umo�liwia ona wpisanie ustawiania zmiennej, sprawdzania warunku i inkrementowania zmiennej w jednej linijce co cz�sto zwi�ksza czytelno�� kodu. Instrukcj� for stosuje si� w nast�puj�cy spos�b:

 for (wyra�enie1; wyra�enie2; wyra�enie3) {
   /* instrukcje do wykonania w p�tli */
 }
 /* dalsze instrukcje */

Jak wida�, p�tla for znacznie r�ni si� od tego typu p�tli, znanych w innych j�zykach programowania. Opiszemy wi�c, co oznaczaj� poszczeg�lne wyra�enia:

    * wyra�enie1 - jest to instrukcja, kt�ra b�dzie wykonana przed pierwszym przebiegiem p�tli. Zwykle jest to inicjalizacja zmiennej, kt�ra b�dzie s�u�y�a jako "licznik" przebieg�w p�tli.
    * wyra�enie2 - jest warunkiem zako�czenia p�tli. P�tla wykonuje si� tak d�ugo, jak prawdziwy jest ten warunek.
    * wyra�enie3 - jest to instrukcja, kt�ra wykonywana b�dzie po ka�dym przej�ciu p�tli. Zamieszczone s� tu instrukcje, kt�re zwi�kszaj� licznik o odpowiedni� warto��.

Je�eli wewn�trz p�tli nie ma �adnych instrukcji continue (opisanych ni�ej) to jest ona r�wnowa�na z:

 {
   wyra�enie1;
   while (wyra�enie2) {
     /* instrukcje do wykonania w p�tli */
     wyra�enie3;
   }
 }
 /* dalsze instrukcje */

Wa�n� rzecz� jest tutaj to, �eby zrozumie� i zapami�ta� jak tak naprawd� dzia�a p�tla for. Pocz�tkuj�cym programistom nieznajomo�� tego faktu sprawia wiele problem�w.

W pierwszej kolejno�ci w p�tli for wykonuje si� wyra�enie1. Wykonuje si� ono zawsze, nawet je�eli warunek przebiegu p�tli jest od samego pocz�tku fa�szywy. Po wykonaniu wyra�enie1 p�tla for sprawdza warunek zawarty w wyra�enie2, je�eli jest on prawdziwy, to wykonywana jest tre�� p�tli for, czyli najcz�ciej to co znajduje si� mi�dzy klamrami, lub gdy ich nie ma, nast�pna pojedyncza instrukcja. W szczeg�lno�ci musimy pami�ta�, �e sam �rednik te� jest instrukcj� - instrukcj� pust�. Gdy ju� zostanie wykonana tre�� p�tli for, nast�puje wykonanie wyra�enie3. Nale�y zapami�ta�, �e wyra�enie3 zostanie wykonane, nawet je�eli by� to ju� ostatni obieg p�tli. Poni�sze 3 przyk�ady p�tli for w rezultacie dadz� ten sam wynik. Wypisz� na ekran liczby od 1 do 10.

 
 for(i=1; i<=10; ++i){
  printf("%d", i);
 }
 
 for(i=1; i<=10; ++i) 
  printf("%d", i);
 
 for(i=1; i<=10; printf("%d", i++ ) );

Dwa pierwsze przyk�ady korzystaj� z w�asno�ci struktury blokowej, kolejny przyk�ad jest ju� bardziej wyrafinowany i korzysta z tego, �e jako wyra�enie3 mo�e zosta� podane dowolne bardziej skomplikowane wyra�enie, zawieraj�ce w sobie inne podwyra�enia. A oto kolejny program, kt�ry najpierw wy�wietla liczby w kolejno�ci rosn�cej, a nast�pnie wraca.

 #include <stdio.h>
 int main()
 {
  int i;
  for(i=1; i<=5; ++i){   
    printf("%d", i);
    }  
 
  for( ; i>=1; i--){
    printf("%d", i);
    }
 
  return 0;
 }

Po analizie powy�szego kodu, pocz�tkuj�cy programista mo�e stwierdzi�, �e p�tla wypisze 123454321. Stanie si� natomiast inaczej. Wynikiem dzia�ania powy�szego programu b�dzie ci�g cyfr 12345654321. Pierwsza p�tla wypisze cyfry "12345", lecz po ostatnim swoim obiegu p�tla for (tak jak zwykle) zinkrementuje zmienn� i. Gdy druga p�tla przyst�pi do pracy, zacznie ona odlicza� pocz�wszy od liczby i=6, a nie 5. By spowodowa� wy�wietlanie liczb od 1 do 5 i z powrotem wystarczy gdzie� mi�dzy ostatnim obiegiem pierwszej p�tli for a pierwszym obiegiem drugiej p�tli for zmniejszy� warto�� zmiennej i o 1.

Niech podsumowaniem b�dzie jaki� dzia�aj�cy fragment kodu, kt�ry mo�e oblicza� warto�ci kwadrat�w liczb od 1 do 10.

 
 #include <stdio.h>
 
 int main ()
 {
   int a;
   for (a=1; a<=10; ++a) {
     printf ("%d\n", a*a);
   }
   return 0;
 }

Porada 	Porada
W kodzie �r�d�owym spotyka si� cz�sto inkrementacj� i++. Jest to z�y zwyczaj, bior�cy si� z wzorowania si� na nazwie j�zyka C++. Post-inkrementacja i++ powoduje, �e tworzony jest obiekt tymczasowy, kt�ry jest zwracany jako wynik operacji (cho� wynik ten nie jest nigdzie czytany). Jedno kopiowanie liczby do zmiennej tymczasowej nie jest drogie, ale w p�tli "for" takie kopiowanie odbywa si� po ka�dym przebiegu p�tli. Dodatkowo, w C++ podobn� konstrukcj� stosuje si� do obiekt�w - kopiowanie obiektu mo�e by� ju� czasoch�onn� czynno�ci�. Dlatego w p�tli "for" nale�y stosowa� wy��cznie ++i.
[edytuj] Instrukcja do..while

P�tle while i for maj� jeden zasadniczy mankament - mo�e si� zdarzy�, �e nie wykonaj� si� ani razu. Aby mie� pewno��, �e nasza p�tla b�dzie mia�a co najmniej jeden przebieg musimy zastosowa� p�tl� do while. Wygl�da ona nast�puj�co:

 do {
   /* instrukcje do wykonania w p�tli */
 } whi...
Zgłoś jeśli naruszono regulamin