Prezentowane materiały są przeznaczone dla uczniów szkół ponadgimnazjalnych. Autor artykułu: mgr Jerzy Wałaszek, wersja1.0 |
©2011 mgr
Jerzy Wałaszek
|
Pomoce:
Instalacja Code::Blocks
Języki wysokiego poziomu
Struktura programu w języku C++
Zmienne i strumienie
W logice występują jedynie dwie wartości: prawda i fałsz.
W języku C++ zdefiniowane są specjalne stałe do reprezentowania wartości logicznych:
prawda | = true | = 1 |
fałsz | = false | = 0 |
// Wartości logiczne // (C)2010 mgr Jerzy Wałaszek // I LO w Tarnowie //--------------------------- #include <iostream> using namespace std; int main() { cout << false << endl << true << endl; return 0; } |
Oczywiście zamiast true można stosować 1, a zamiast false 0 - jednakże posługiwanie się tymi stałymi zwiększa czytelność programu.
Wyrażenie logiczne (ang. logical expresion) jest wyrażeniem, które może przyjmować tylko wartości logiczne true lub false. Tego typu wyrażenia powstają z operatorami porównań.
Operator | Nazwa | Przykład |
---|---|---|
== | równe | a == 15 |
!= | różne | a != b |
< | mniejsze | a < 15 |
<= | mniejsze lub równe | b + 5 <= a |
> | większe | a + 15 > c |
>= | większe lub równe | a >= b + c |
// Operatory porównań // (C)2010 I LO w Tarnowie //--------------------------- #include <iostream> using namespace std; int main() { int a = 4; cout << (a == 4) << endl << (a == 3) << endl; return 0; } |
// Operatory porównań // (C)2010 I LO w Tarnowie //--------------------------- #include <iostream> using namespace std; int main() { int a = 4; cout << (a != 4) << endl << (a != 3) << endl; return 0; } |
// Operatory porównań // (C)2010 I LO w Tarnowie //--------------------------- #include <iostream> using namespace std; int main() { int a = 4; cout << (a < 5) << endl << (a < 3) << endl; return 0; } |
// Operatory porównań // (C)2010 I LO w Tarnowie //--------------------------- #include <iostream> using namespace std; int main() { int a = 4; cout << (a >= 5) << endl << (a >= 3) << endl; return 0; } |
Instrukcja warunkowa pozwala wykonywać instrukcje programu w zależności od określonego warunku logicznego. Posiada ona następującą składnię:
if(warunek) instrukcja1;
else instrukcja2;
if - jest słowem kluczowym języka C++ oznaczającym instrukcję warunkową
warunek - jest wyrażeniem logicznym lub arytmetycznym, które zostaje obliczone przez instrukcję if i którego wartość decyduje o sposobie wykonania następnych instrukcji.
instrukcja1 - jest dowolną instrukcją języka C++, która zostanie wykonana przez program tylko wtedy, gdy warunek będzie miał wartość logiczną true (lub różną od zera). Jeśli warunek ma wartość false (lub zerową), to instrukcja1 zostanie pominięta.
else - słowo kluczowe języka C++, składnik instrukcji warunkowej if.
instrukcja2 - jest dowolną instrukcją języka C++, która zostanie wykonana tylko wtedy, gdy warunek będzie miał wartość false (lub zero).
Zwróć uwagę, że zawsze wykonywana jest tylko jedna z instrukcji zawartych w instrukcji warunkowej if. Ta własność pozwala komputerowi działać logicznie, dostosowywać operację do zastanych warunków. To dzięki niej programy są "inteligentne".
// Znajdowanie większej z dwóch liczb // (C)2010 I LO w Tarnowie //----------------------------------- #include <iostream> using namespace std; int main() { int a,b; cin >> a >> b; if(a > b) cout << a; else cout << b; cout << endl; return 0; } |
// Badanie znaku liczby // (C)2010 I LO w Tarnowie //------------------------ #include <iostream> using namespace std; int main() { int a; cin >> a; if(a > 0) cout << "DODATNIA\n"; else if (a == 0) cout << "ZERO\n"; else cout << "UJEMNA\n"; return 0; } |
Często zdarza się tak, iż w instrukcji warunkowej potrzebna nam jest tylko instrukcja1. W takim przypadku fragment z else można pominąć.
if(warunek) instrukcja;
instrukcja
jest wykonywana tylko wtedy, gdy
warunek jest prawdziwy. Gdy warunek ma wartość false,
to
instrukcja
zostaje pominięta.
// Obliczanie wartości bezwzględnej // (C)2010 I LO w Tarnowie //--------------------------------- #include <iostream> using namespace std; int main() { int a; cin >> a; if(a < 0) a = -a; cout << a << endl; return 0; } |
// Wyszukiwanie największej liczby z trzech // (C)2010 I LO w Tarnowie //----------------------------------------- #include <iostream> using namespace std; int main() { int a,b,c,x; cin >> a >> b >> c; x = a; if(b > x) x = b; if(c > x) x = c; cout << x << endl; return 0; } |
Jeśli w ramach instrukcji warunkowej if chcemy wykonać nie pojedynczą instrukcję ale kilka instrukcji, to stosujemy tzw. instrukcję blokową - dowolny ciąg instrukcji ujęty w klamerki. Po klamwrkach nie musimy już wstawiać średników:
if(warunek)
{
ciąg instrukcji wykonywany, gdy warunek ma
wartość true
}
else
{
ciąg instrukcji wykonywanych, gdy warunek ma
wartość false
}
// Porządkowanie dwóch liczb // (C)2010 I LO w Tarnowie //-------------------------- #include <iostream> using namespace std; int main() { int a,b,x; cin >> a >> b; if(a > b) { x = a; a = b; b = x; } cout << a << " " << b << endl; return 0; } |
Pętla (ang. loop) to cykliczne powtarzanie wykonywania wybranej instrukcji lub grupy instrukcji w programie. Obiegiem pętli (ang. loop pass) nazywamy pojedynczy cykl wykonania powtarzanej instrukcji lub grupy instrukcji. Pętla warunkowa (ang. conditional loop) wykonuje powtarzanie obiegów w zależności od wybranego warunku. W języku C++ mamy dwie podstawowe instrukcje pętli warunkowych. Pierwsza z nich to pętla typu while:
while(warunek) instrukcja;
while
- słowo
kluczowe języka C++ oznaczające instrukcję pętli warunkowej
warunek
- dowolne wyrażenie arytmetyczne.
Warunek jest prawdziwy (true), jeśli ma wartość
różną od zera. Warunek jest fałszywy (false),
jeśli ma wartość zero.
instrukcja
- powtarzana w pętli instrukcja.
Pętla typu while działa następująco. Na początku każdego obiegu komputer oblicza wartość warunku. Jeśli wynik jest różny od zera, to zostaje wykonana instrukcja i komputer rozpoczyna nowy obieg od ponownego obliczenia wartości warunku. Jeśli warunek ma wartość równą zero, instrukcja w pętli nie zostaje wykonana i pętla kończy działanie.
// Kolejne liczby naturalne od 1 do 10 // (C)2010 I LO w Tarnowie //------------------------ #include <iostream> using namespace std; int main() { int i; i = 1; while(i <= 10) cout << i++ << endl; return 0; } |
// Kolejne liczby naturalne od 10 do 1 // (C)2010 I LO w Tarnowie //------------------------ #include <iostream> using namespace std; int main() { int i; i = 10; while(i >= 1) cout << i-- << endl; return 0; } |
Ponieważ warunek jest sprawdzany na początku każdego obiegu pętli przed wykonaniem instrukcji zawartej w pętli, to jeśli jest on już od początku fałszywy, pętla nie wykona ani jednego obiegu.
// Fałszywy warunek // (C)2010 I LO w Tarnowie //------------------------ #include <iostream> using namespace std; int main() { int i; i = 11; while(i <= 10) cout << i++ << endl; return 0; } |
// Fałszywy warunek // (C)2010 I LO w Tarnowie //------------------------ #include <iostream> using namespace std; int main() { int i; i = 0; while(i >= 1) cout << i-- << endl; return 0; } |
Drugi rodzaj pętli warunkowej to pętla do while:
do instrukcja; while(warunek);
do
- słowo kluczowe języka C++ oznaczające początek pętli warunkowej
instrukcja
- powtarzana w pętli instrukcja. Zwróć uwagę, że musi
ona kończyć się średnikiem.
while
- słowo kluczowe
oznaczające sekcję sprawdzania warunku.
warunek
- dowolne wyrażenie arytmetyczne. Warunek
jest prawdziwy (true), jeśli ma wartość różną od
zera. Warunek jest fałszywy (false), jeśli ma
wartość zero.
Pętla typu do...while nieznacznie różni się od pętli while. W każdym obiegu najpierw wykonywana jest instrukcja, a dopiero po jej wykonaniu komputer oblicza i sprawdza warunek. Jeśli ma on wartość różną od zera, to wykonywany jest następny obieg pętli, Jeśli warunek ma wartość zero, pętla nie wykonuje dalszych obiegów i jest przerywana.
// Kolejne liczby naturalne od 1 do 10 // (C)2010 I LO w Tarnowie //------------------------ #include <iostream> using namespace std; int main() { int i; i = 1; do cout << i++ << endl; while(i <= 10); return 0; } |
// Kolejne liczby naturalne od 10 do 1 // (C)2010 I LO w Tarnowie //------------------------ #include <iostream> using namespace std; int main() { int i; i = 10; do cout << i-- << endl; while(i >= 1); return 0; } |
Ponieważ warunek kontynuacji jest sprawdzany w pętli do...while na końcu obiegu po wykonaniu powtarzanej instrukcji, to pętla wykonuje zawsze przynajmniej jeden obieg bez względu na wartość warunku - czyli inaczej niż pętla while, która przy fałszywym warunku nie wykonywała się ani jeden raz.
// Fałszywy warunek // (C)2010 I LO w Tarnowie //------------------------ #include <iostream> using namespace std; int main() { int i; i = 11; do cout << i++ << endl; while(i <= 10); return 0; } |
// Fałszywy warunek // (C)2010 I LO w Tarnowie //------------------------ #include <iostream> using namespace std; int main() { int i; i = 0; do cout << i-- << endl; while(i >= 1); return 0; } |
Jeśli w pętli chcemy powtarzać więcej niż jedną instrukcję, to stosujemy instrukcję blokową (po klamerce zamykającej nie musimy wstawiać średnika):
while(warunek) |
do |
// Kolejne liczby parzyste od 2 do n // (C)2010 I LO w Tarnowie //------------------------ #include <iostream> using namespace std; int main() { int i,n; cin >> n; i = 2; while(i <= n) { cout << i << " "; i += 2; } cout << endl; return 0; } |
// Kolejne liczby nieparzyste od 2 do n // (C)2010 I LO w Tarnowie //------------------------ #include <iostream> using namespace std; int main() { int i,n; cin >> n; i = 1; while(i <= n) { cout << i << " "; i += 2; } cout << endl; return 0; } |
// Sumy kolejnych liczb od 1 do n // (C)2010 I LO w Tarnowie //------------------------ #include <iostream> using namespace std; int main() { int i,n,s; cin >> n; i = 1; s = 0; while(i <= n) { s += i++; cout << s << endl; } return 0; } |
// Kolejne potęgi liczby 2 // (C)2010 I LO w Tarnowie //------------------------ #include <iostream> using namespace std; int main() { unsigned long long i,n; cin >> n; i = 1; while(i <= n) { cout << i << endl; i *= 2; } return 0; } |
// Silnia n! // (C)2010 I LO w Tarnowie //------------------------ #include <iostream> using namespace std; int main() { int i,n,s; cin >> n; s = i = 1; while(i <= n) { s *= i++; cout << s << endl; } return 0; } |
Obiegi wykonywane przez pętlę można numerować. Obieg numerowany nazywamy iteracją. Iteracja wymaga dodatkowej zmiennej, która przechowuje numer wykonywanego przez pętlę obiegu. Zmienna ta nosi nazwę licznika pętli (ang. loop counter). Pętlę iteracyjną możemy utworzyć przy pomocy poznanych dotychczas pętli warunkowych.
Przykład:
Poniższe pętle wykonują 10 obiegów. Obiegi zliczane są przez zmienną i, która pełni tutaj rolę licznika pętli.
... i |
... i |
Ponieważ pętle iteracyjne pojawiają się w programach bardzo często, w języku C++ istnieje specjalna instrukcja do ich łatwej realizacji. Składnia tej instrukcji jest następująca:
for(prolog; kontynuacja; epilog)
instrukcja;
lub z instrukcją złożoną:
for(prolog; kontynuacja; epilog)
{
Ciąg instrukcji;
}
prolog | - | instrukcja wykonywana przed rozpoczęciem pierwszej
iteracji. Najczęściej służy do inicjalizacji licznika pętli. Przykład:
|
kontynuacja | - | warunek kontynuacji pętli. Jeśli wyrażenie to ma wartość
różną od 0, to pętla wykona obieg. Warunek jest sprawdzany na początku
każdej iteracji. Przykład:
|
epilog | - | instrukcja wykonywana po zakończeniu każdej iteracji.
Najczęściej wykorzystuje się ją do modyfikacji licznika pętli. Przykład:
|
instrukcja | - | instrukcja powtarzana w każdej iteracji pętli. Przykład:
|
W poniższych przykładach zakładamy, iż wszystkie niezbędne zmienne zostały wcześniej odpowiednio zadeklarowane.
Pętla wypisuje kolejne liczby całkowite od 1 do 10:
for(i = 1; i <= 10; i++) cout << i << endl;
Pętla wypisuje liczby od 10 do 1 w kierunku odwrotnym:
for(i = 10; i >= 1; i--) cout << i << endl;
Pętla wypisuje kolejne liczby parzyste od 4 do 26:
for(i = 4; i <= 26; i += 2) cout << i << endl;
Poniższy fragment programu wypisuje wiersz zbudowany z 20 znaków X:
for(i = 0; i < 20; i++) cout << "X";
cout << endl;
Jeśli powtórzymy ten fragment programu 20 razy, to otrzymamy kwadrat z literek X. Instrukcją powtarzaną w pętli może być druga pętla - otrzymamy wtedy układ zagnieżdżony:
for(j = 0; j < 20; j++)
{
for(i = 0; i < 20; i++) cout << "X";
cout << endl;
}
Pętla wewnętrzna jest sterowana zmienną i. Jej zadaniem jest wyświetlenie jednego wiersza 20 znaków X. Pętla ta jest powtarzana 20 razy przez pętlę zewnętrzną sterowaną zmienną j. W efekcie w oknie konsoli pojawia się 20 wierszy, każdy zbudowany z 20 literek X:
XXXXXXXXXXXXXXXXXXXX |
W pętlach zagnieżdżonych muszą być stosowane różne zmienne liczników pętli.
Jeśli ilość wykonań pętli wewnętrznej uzależnimy od numeru obiegu pętli zewnętrznej, to otrzymamy trójkąt:
for(j = 0; j < 20; j++)
{
for(i = 0; i <= j; i++) cout << "X";
cout << endl;
}
X |
Zastanów się, jak zmienić podane pętle, aby uzyskać następujące wydruki w oknie konsoli:
XXXXXXXXXXXXXXXXXXXX |
X |
XXXXXXXXXXXXXXXXXXXX |
W wyrażeniach możemy stosować funkcje logiczne, których w języku C++ mamy trzy:
NIE - Negacja/Zaprzeczenie logiczne (ang. not)
w | !w |
0 | 1 |
1 | 0 |
Jest to funkcja jednoargumentowa, której argumentem jest wyrażenie w. Wynikiem jest wartość przeciwna do wartości logicznej wyrażenia w.
LUB - Alternatywa/Suma logiczna (ang. or)
w1 | w2 | w1 || w2 |
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 1 |
Jest to funkcja dwuargumentowa. Wynik jest równy true tylko wtedy, gdy dowolny z argumentów jest prawdziwy (ma wartość różną od zera). Jeśli oba argumenty są fałszywe (równe zero), to wynikiem jest false. Nazwa suma logiczna pochodzi z podobieństwa wyniku tej funkcji do operacji dodawania liczb nieujemnych. Suma dwóch liczb nieujemnych jest różna od 0, jeśli dowolna z sumowanych liczb jest różna od 0. Suma wynosi 0, jeśli oba argumenty są równe 0.
I - Koniunkcja/Iloczyn logiczny (ang. and)
w1 | w2 | w1 && w2 |
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
Jest to funkcja dwuargumentowa. Wynik jest równy true tylko wtedy, gdy oba argumenty są prawdziwe (różne od zera). W przeciwnym razie wynik jest równy false. Nazwa iloczyn logiczny pochodzi z podobieństwa wyniku tej funkcji do operacji mnożenia. Wynik mnożenia jest niezerowy, jeśli wszystkie mnożone liczby są niezerowe.
Funkcje logiczne można łączyć:
a || b || c || d
a && b && c && d
a && (b || c)
!(a || b && c)
Wykorzystując funkcję LUB utwórz pętle, które tworzą następujące wydruki
(zastanów się dla jakich i,j ma być wyświetlana spacja lub
znak X):
XXXXXXXXXXXXXXXX |
XXXXXXXXXXXXXXXX |
XXXXXXXXXXXXXXXX |
XXXXXXXXXXXXXXXX |
I Liceum Ogólnokształcące |
Pytania proszę przesyłać na adres email: i-lo@eduinf.waw.pl
W artykułach serwisu są używane cookies. Jeśli nie chcesz ich otrzymywać,
zablokuj je w swojej przeglądarce.
Informacje dodatkowe