Pętle W języku C dostępne są trzy instrukcje, umożliwiające
Transkrypt
Pętle W języku C dostępne są trzy instrukcje, umożliwiające
Pętle W języku C dostępne są trzy instrukcje, umożliwiające tworzenie pętli: for, while oraz do. Instrukcja for ma następującą postać: for (w1;w2;w3) instrukcja w1, w2, w3 są wyrażeniami Schemat blokowy pętli for wygląda następująco: w1 NIE TAK w2 w3 instrukcja Instrukcja: for(;;) oznacza pętlę nieskończoną. Oto przykład programu wykorzystującego pętlę for, który oblicza sumę n liczb wprowadzanych z klawiatury: START czytaj n suma=0 i=0 i>n czytaj x suma =suma+x pisz suma STOP i=i+1 #include <stdio.h> int main() { //suma n elementow int n,i; float x, suma=0; printf("podaj liczbe elementow\n"); scanf("%d",&n); for(i=0;i<n;i++) { printf("podaj wartosc %d\n",i+1); scanf("%f",&x); suma+=x; }; printf("suma %d elementow wynosi %f\n",n,suma); } W programie zastosowano zapis: suma+=x; który jest skrócona postacią instrukcji: suma=suma+x; Analogiczny skrócony zapis można stosować również do innych operatorów: -,*,/. I tak instrukcja: iloczyn*=x; jest równoważna instrukcji: iloczyn = iloczyn * x; W pętli for często występuje wyrażenie inkrementacji i++ lub dekrementacji i--. Możliwe jest również zastosowanie zapisu –-i lub ++i. Różnice między nimi wyjaśnia przykład: i=1; k=2; j=i++; l=k--; ---------------------po wykonaniu tych instrukcji: i=2, k=1, j=1, l=2 i=1; k=2; j=++i; l=--k; ---------------------po wykonaniu tych instrukcji: i=2, k=1, j=2, l=1 W instrukcji j=i++ najpierw wykonywane jest podstawienie, zmienna j przyjmuje taką wartość jak zmienna i, a dopiero później zmienna i jest inkrementowana, natomiast w instrukcji j=++i najpierw wykonywana jest inkrementacja zmiennej i, a następnie podstawienie. Pętla while ma postać: while ( w )instrukcja i odpowiada jej schemat blokowy: TAK NIE w instrukcja Instrukcja wykonywania jest dopóki spełniony jest warunek w. Jest ona równoważna pętli: for( ; w; ). Warunek w sprawdzany jest na początku pętli. Przykładem zastosowania pętli while jest program, który wczytuje liczby wprowadzane z klawiatury i sumuje je, aż do napotkania pewnej zadanej wartości, pełniącej rolę stopera Stoper nie powinien być dodany do sumy. Oto schemat blokowy i kod programu: START czytaj koniec suma=0 czytaj x TAK NIE x<>koniec suma =suma+x pisz suma STOP czytaj x #include <stdio.h> int main() { //suma bez konca int i=0; float koniec; float x, suma=0; printf("podaj znacznik konca \n"); scanf("%f",&koniec); printf("podaj pierwsza liczbe\n"); scanf("%f",&x); while(x!=koniec) { suma+=x; printf("podaj wartosc %d\n",i+1); scanf("%f",&x); i++; }; printf("suma konca=%f wynosi %f\n",koniec,suma); } Pętla do ma postać: do instrukcja while ( w ) i odpowiada jej schemat blokowy: instrukcja NIE TAK w Instrukcja wykonywania jest przynajmniej jeden raz, warunek w sprawdzany jest na końcu. Przykładem zastosowania pętli do jest program, który wczytuje liczby wprowadzane z klawiatury i sumuje je, aż do napotkania pewnej zadanej wartości, pełniącej rolę stopera, wraz ze stoperem. START czytaj koniec suma=0 czytaj x suma =suma+x TAK NIE x<>koniec pisz suma STOP #include <stdio.h> int main() { //suma z koncem int i=0; float koniec; float x, suma=0; printf("podaj znacznik konca \n"); scanf("%f",&koniec); do { printf("podaj kolejna wartosc %d\n",i+1); scanf("%f",&x); suma+=x; i++; } while(x!=koniec); printf("suma elementow=%f\n",suma); } Przerwanie działania pętli / instrukcje break, continue/ Instrukcja break powoduje wyjście z najbardziej zagnieżdżonej pętli. Używa się jej w celu przerwania pętli w innym przypadku niż spełnienie warunków zakończenia pętli. Aby przerwać bieżący krok pętli i przejść do następnego stosuje się instrukcję continue. Oto fragment programu ilustrujący zastosowanie obu instrukcji. Zadanie polega na obliczeniu sumy liczb dodatnich, wczytywanych z klawiatury (maksymalnie 10 liczb), przy założeniu, że napotkanie wartości 0 powoduje zakończenie działanie programu. for(i=0;i<10;i++) { scanf(„%d”,&k) if (k==0) break; else if (k<0) continue; s+=k …….. } Natychmiastowe wyjście z całego programu powoduje instrukcja exit. Jako parametr można podać kod zakończenia programu (np.: exit(1)). PRZYKŁAD Poniższy program oblicza wartość silni dla liczb dodatnich wprowadzanych z klawiatury, aż do napotkania liczby 0. #include <stdio.h> #include <stdlib.h> int silnia(int k) //funkcja silnia { int wynik=1; int i; for(i=1;i<=k;i++) wynik*=i; return wynik; } int main() { int i; do { printf("podaj i\n"); scanf("%d",&i); printf("%d ! = %d\n",i,silnia(i)); } while (i!=0); } Program kończy się, gdy zostanie wprowadzona liczba 0 - ostatnią policzoną wartością jest 0!. Dla każdej wprowadzonej wartości wywołana jest funkcja silnia. Zastosowano w niej pętlę for, w której zmienna wynik mnożona jest przez kolejne liczby całkowite. Zmienna wynik zainicjowana jest wartością 1, gdyż jest to element neutralny mnożenia. W funkcji main zastosowano pętlę do, w której wczytywane są kolejne wartości i i dla każdej z nich wywoływana jest funkcja silnia (drugi argument wywołania funkcji printf). ZADANIE: Zbadaj dla jakich wartości argumentu wartość silni jest niepoprawna. Dla zwiększenia zakresu poprawności działania funkcji silnia zmień jej typ na double. PRZYKŁAD Program z kolejnego przykładu tablicuje funkcję sinus w zadanym przedziale z zadaną liczbą podprzedziałów – czyli wyświetla na ekranie tabelę z wartościami argumentów i odpowiadającymi im wartościami funkcji sinus. Wartości funkcji sinus będą liczone dwoma sposobami: korzystając z funkcji bibliotecznej sin(x) oraz z własnej funkcji szereg, wykorzystującej rozwinięcie funkcji w szereg Taylora, które wygląda następująco: Im większa liczba wyrazów szeregu, tym wynik będzie dokładniejszy. Aby wygodnie można było to przetestować w programie zastosowano makrodefinicję define do określenia liczby wyrazów szeregu. Poprawnie napisany program obok kolumny argumentów powinien wyświetlić dwie identyczne, lub nieznacznie różniące się kolumny liczb, będące wartościami funkcji sinus uzyskanymi dwoma sposobami. Oto program i efekt przykładowego wywołania: #include <stdio.h> #include <stdlib.h> #include <math.h> #define li 100 //liczba iteracji do szeregu //tablicowanie fcji sin w <a,b> - szereg + fcja biblioteczna //definicja funkcji szereg; x - parametr formalny double szereg(double x) { double s, w; int i; s=x; w=x; for(i=1;i<=li;i++) { w=-w*x*x/(2*i*(2*i+1)); s=s+w; } return s; } int main() { int lp; double a, b, szsin, krok, x; //<a;b> - przedział, lp - liczba podprzedziałów printf("podaj konce przedzialow i liczbe podprzedzialow\n"); scanf("%lf %lf %d",&a,&b,&lp); krok=(b-a)/lp; printf("krok=%6.2lf\n\n\n",krok); printf(" ----------------------------\n\n"); printf(" x szereg(x) sin(x)\n ---------------------------\n"); for (x=a;x<=b;x+=krok) printf("%10.2lf %7.4lf %7.4lf\n",x,szereg(x),sin(x)); printf(" ----------------------------\n\n"); } Należy zwrócić uwagę na fakt, że w funkcji szereg kolejne wyrazy ciągu liczone są na podstawie wyrazu poprzedniego. Wystarczy pomnożyć go przez –x2 i podzielić przez dwie kolejne liczby całkowite. Obliczanie każdego wyrazu przy pomocy funkcji potęgującej pow byłoby zbyt kosztowne obliczeniowo. A oto efekt działania programu dla przykładowych danych: ZADANIA: 1. Zbadaj efekt działania programu dla różnych liczb wyrazów szeregu. 2. Zmodyfikuj program tak, aby tablicował funkcję cosinus, której rozwinięcie w szereg Taylora jest następujące: