mgr inż. Wacław Libront * Bobowa 2019

ZSO Bobowa, ul. Długoszowskich 1, 38-350 Bobowa, tel: 0183514009, fax: 0183530221, email: sekretariat@zsobobowa.eu, www: zsobobowa.eu

Lekcja 5

WHILE   Pętle logiczne w C++

  1. schemat
  2. suma i średnia
  3. specyfikacja
  4. euklides
  5. fibonacci
  6. sinus
  7. zadania
  8. rozwiązania

Duża część algorytmów działa na dowolnych danych i nie jesteśmy w stanie przewidzieć, ile razy powinna wykonać się pętla (jak w przypadku pętli FOR). Może to być zależne na przykład od wpisywanego z klawiatury tekstu, podawania poprawnych lub błędnych danych, itp. W ogólnym przypadku możemy stwierdzić, że czas działania pętli logicznej będzie zależał od spełnienia (lub nie) określonego warunku logicznego.

Schemat pętli WHILE

warunek logiczny jest sprawdzany przed wykonaniem instrukcji w pętli

while (warunek) instrukcja;
while (warunek) { instrukcje;…; }

najpierw wykonywana jest instrukcja, a potem sprawdzany jest warunek logiczny

do instrukcja; while (warunek);
do { instrukcje;…; } while (warunek);

Przykłady
Wypisz na ekranie liczby naturalne od 1 do 10

// pętla FOR
for (int i=1; i<=10; i++) 
  cout << i << endl;
// pętla WHILE
int i=1;
while (i <= 10){
  cout << i << endl;
  i=i+1;
}
// pętla DO WHILE
int j=1;
do {
  cout << j << endl;
  j=j+1;
} while (j <= 10);

Zadanie - SUMA i ŚREDNIA
Podsumuj i wylicz średnią arytmetyczną oceny wpisywane z klawiatury. Kończymy obliczenia, gdy użytkownik wpisze z klawiatury 0. Sprawdź czy oceny mieszczą się w zakresie od 1 do 6.

#include <stdlib.h>  //system()
#include <iostream>  //cout i cin
#include <iomanip>   //fixed i setprecision()
using namespace std;
int main() {
  setlocale(LC_ALL, "");
  cout << "SUMA i ŚREDNIA OCEN" << endl << endl;
  // zerujemy zmienne aby program nie liczył glupot
  int ile=0;
  float suma=0;
  float srednia=0;
  // zmiennej ocena nie musimy inicjowac
  // bo za pierwszym razem wpisana wartosc z klawiatury
  float ocena;
  do {
    cout << "Wpisz ocenę (0-koniec): ";
    cin >> ocena;
    // ocena musi miescic sie w zakresie 1..6
    if (ocena >= 1 && ocena <= 6){
	ile=ile+1;
	// zmienna SUMA powiekszana o nowa ocena
	suma=suma+ocena;
	//za kazdym razem liczymy srednia
	srednia=suma/ile;
    }
  } while (ocena != 0);
  // koniec petli gdy z klawiatury wpisano zero

  cout << "Ilość ocen:   " << ile << endl;
  cout << "Suma ocen:    " << suma << endl;
  cout << fixed << setprecision(2);
  cout << "Średnia ocen: " << srednia << endl;
  system("pause");
}

Uwagi do programu


Kolejne algorytmy zostaną opisane zgodnie ze specyfikacją wymaganą na maturze.

Zadanie - Wyszukiwanie minimum (maksimum)
Wpisujemy z klawiatury liczby i wyszukujemy minimalną (maksymalną).

Jeden z najbardziej elementarnych algorytmów, stosowany przede wszystkim podczas operacji sortowania.

Specyfikacja

  1. wprowadź liczbę N

  2. zmiennej MIN przypisz N

  3. wprowadź liczbę N

  4. jeżeli N > 0 i N < MIN przypisz MIN=N

  5. jeżeli N>0 wróć do kroku 3

  6. Wypisz liczbę minimalną MIN

int N;
cout << "wpisz liczbę: ";
cin >> N;
int MIN=N;
do {
  cout << "wpisz liczbę: ";
  cin >> N;
  if (N > 0 && N < MIN) MIN=N;
} while (N>0);
cout << "minimalna: " << MIN << endl;

Zadanie - Euklides
Napisz program (funkcję), który policzy największy wspólny dzielnik dwóch liczb wpisanych z klawiatury.

Największy wspólny dzielnik liczb wykorzystywany jest do skracania ułamków (licznik i mianownik dzieli się przez NWD) oraz do obliczania najmniejszej wspólnej wielokrotności NWW (sprowadzanie ułamków do wspólnego mianownika)

Specyfikacja

  1. Wprowadź A i B

  2. Czy A jest różne od B

  3. Dopóki A nie jest równe B powtarzaj punkty 4 i 5

  4. Od liczby większej odejmij mniejszą

  5. Do liczby większej przypisz różnicę

  6. Wyprowadź NWD równe pierwszej liczbie (lub drugiej bo i tak są równe)

cout << "EUKLIDES NWD" << endl;
cout << "NWD Wpisz dwie liczby: ";
int A,B;
cin >> A >> B;
while (A != B) 
  if (A > B) 
    A=A-B; 
  else 
    B=B-A;
cout << "NWD(" << A << "," << B << ")=" << NWD(A,B) << endl;

Zadanie - Fibonacci
Początkowo mamy jedną parę królików. Po miesiącu osiągają dojrzałość płciową i po kolejnym rodzi się nowa para królików. W kolejnym miesiącu znów urodzi się nowa para królików od rodziców, a młode króliki osiągną dojrzałość płciową, by za miesiąc wydać nowe pokolenie. I tak w nieskończoność. Zadaniem programu (funkcji) będzie policzenie, ile par królików będzie w stadzie po N miesiącach?

W kolejnych miesiącach będzie następująca ilość par: 1,1,2,3,5,8,13,21,34,55,89,144 i jest to suma dwóch poprzednich ciągów.

Specyfikacja

  1. F1=0 F2=1 - pierwsze dwa wyrazy

  2. pętla od 0 do N-1

  3. wylicz F2=F2+F1

  4. wylicz F1=F2-F1

  5. F2 zawiera wynik

int FIB(int N){
  int F1=0, F2=1, i=0;
  while (i < N){
    F2=F2+F1;
    F1=F2-F1;
    i++;
  };
return F2;
}
...
cout << "FIBONACCI Ile kroków: " << endl;
int krok;
cin >> krok;
cout << "FIBONACCI(" << krok << ")=" << FIB(krok) << endl;

Zadanie – SINUS
Wartość funkcji trygonometrycznej sin(x) można wyznaczyć za pomocą szeregu Taylora:
Wykorzystując tą definicję napisz funkcję, który policzy wartość sinusa dla argumentu x z dokładnością n, gdzie n oznacza ilość wyrazów w szeregu Taylora. W programie głównym wylicz wartość funkcji dla kolejnych kątów od 0° do 360°, co 30°

Specyfikacja

  1. Wczytaj kąt - K i dokładność - D

  2. wyzeruj sumę początkową - S

  3. zamień kąt K na miarę łukową radiany - R

  4. pętla od 1 do D wykonuje punkt 5

  5. powiększ sumę S o kolejny wyraz szeregu Taylora

  6. S zawiera wynik - wartość funkcji sin(x)

#include <cmath>
...
long long SILNIA(int N){
  long long s=1, i=1;
  while (i <= N) {
    s=s*i;
    i++;
  } 
  return s;
}

double RADIANY(double sto){
  return sto*M_PI/180;
}

double SIN(double x, int n){	
  double s=0;
  double R=RADIANY(x);
  int i=0;
  while (i <= n){
    s=s+pow(-1,i)*pow(R,2*i+1)/SILNIA(2*i+1);
    i++;
  }
  return s;
}
...
cout << "SINUS - Szereg Taylora" << endl;
cout << "Wpisz kąt (stopnie): ";
double K,D;
cin >> K;
cout << "Wpisz dokładność (0-N): ";
cin >> D;
cout << "SIN(" << K << ")=" << SIN(K,D) << endl;
...
//kąty w pętli
int k=0;
while (k <= 360){
  cout.width(5);
  cout << k;
  cout.width(10);
  cout << fixed << setprecision(5);
  cout << SIN(k,8) << endl;
  k=k+30;
}

Zadania

1) Wczytuj z klawiatury oceny, aż do wpisania znaku zera. Na ekranie wyświetlamy za każdym razem sumę i średnią ocen.

2) Na wykonanie szkieletu prostopadłościanu zużyto 56 cm drutu. Sprawdź, jakie mogą być poszczególne długości krawędzi.
- napisz funkcję, która liczy długość drutu potrzebnego na wykonanie prostopadłościanu
- w trzech pętlach WHILE zmieniaj krawędzie 1.. 56 cm

 

3) Napisz funkcję, która wyliczy sumę cyfr podanej jako parametr liczby całkowitej. Wykorzystaj dzielenie całkowite i modulo oraz pętlę while.
- zmodyfikuj funkcję tak, aby potrafiła obliczać sumę dla liczb rzeczywistych

4) Napisz funkcję PIERWSZA, która sprawdza, czy podana jako parametr liczba jest pierwsza. Jako wynik otrzymujemy zero-gdy pierwsza lub dzielnik. Z jej pomocą wypisz na ekranie liczby pierwsze w zakresie 1..100

5) Co zostanie wydrukowane po wykonaniu pętli:
a) a = 1; b = 3; while (a < b) { a = 3 * a – 1; b = 2 * b + 1; } cout << a << endl << b;
b) a = 21; b = 3; while (a != b) { a = a – 1; b = b + 1; } cout << a << endl << b;
c) a = 1000; b = 1; while (a > b) { a /= 2; b *= 2; } cout << a << endl << b;
d) a = 81; b = 9; while (a != b) { if (a > b) a -= b; else b -= a; } cout << a << endl << b; 


Przykładowe rozwiązania zadań
Jedynie ciężka umysłowa praca i zrozumienie działania programu może nauczyć programowania!

//zadanie 1
cout << "SUMA i ŚREDNIA OCEN" << endl << endl;
//zerujemy aby program nie liczył glupot
int ile=0;
float suma=0;
float srednia=0;
//nie musimy inicjowac,
//bo za pierwszym razem wpisana wartosc z klawiatury
float ocena;
do {
	cout << "Wpisz ocenę (0-koniec): ";
	cin >> ocena;
	if (ocena >= 1 && ocena <= 6){
		ile=ile+1;
		suma=suma+ocena;
		srednia=suma/ile;
	}
} while (ocena != 0);

cout << "Ilość ocen:   " << ile << endl;
cout << "Suma ocen:    " << suma << endl;
cout << fixed << setprecision(2);
cout << "Średnia ocen: " << srednia << endl;
//zadanie 2
int DRUT(int a, int b, int c){
	return 4*(a+b+c);
}
...
//zadanie 2
cout << "SZKIELET PROSTOPADŁOŚCIANU" << endl;
cout << "długość krawędzi = 56" << endl;
int a=1;
while (a <= 56){
  int b=1;
  while (b <= 56){
    int c=1;
    while (c <= 56){
      if (DRUT(a,b,c) == 56){
      //cout.width(6);
      cout << "a=" << a << " b=" << b << " c=" << c << endl;
      }
      c++;
    }
    b++;
  }		
  a++;
}
cout << endl;
//zadanie 3
int SumaCyfr(int liczba){
  int suma=0,wynik=0;
  while (liczba != 0){
	wynik=liczba % 10;
	liczba=liczba / 10;
	suma=suma+wynik;
  }
  return suma;
}
...
int liczba,wynik;
do{
	cout << "wpisz liczbę: ";
	cin >> liczba;
	cout << SumaCyfr(liczba) << endl;	
} while(liczba != 0);

//zadanie 4
//zero - pierwsza
//dzielnik - nie pierwsza
int PIERWSZA(int liczba){
	if (liczba<2) return 0;
	else{
		int i=2;
		while (liczba%i != 0) i++;
		if (liczba == i) return 0;
		else return i;	
	}
}
...
for (int i=1; i <= 100; i++) {
		cout.width(5);
		cout << i;
		cout.width(5);
		cout << PIERWSZA(i) << endl;
	}
	for (int i=1 ; i<= 100; i++) {
		int p=PIERWSZA(i);
		if (p == 0) cout << i << "  ";
}
//zadanie 5


//SZABLON
#include <stdlib.h>	//system
#include <iostream>	//cout
#include <iomanip>	//fixed
#include <cmath>	//pow
using namespace std;
int main(){
  setlocale(LC_ALL, "");


  system("pause");
}