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:
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:
w1
instrukcja
w3
w2
NIE
TAK
w1
START
czytaj n
suma=0
i=0
i>n
suma =suma+x
i=i+1
czytaj x
pisz suma
STOP
#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:
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:
instrukcja
w
NIE
TAK
#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);
}
START
czytaj koniec
suma=0
czytaj x
STOP
NIE
x<>koniec
TAK
suma =suma+x
czytaj x
pisz suma
Pętla do ma postać:
do instrukcja while ( w )
i odpowiada jej schemat blokowy:
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.
instrukcja
w
NIE
TAK
#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);
}
START
czytaj koniec
suma=0
suma =suma+x
pisz suma
STOP
NIE
x<>koniec
TAK
czytaj x
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 –x
2
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: