Pojęcie bitu
Logika w języku C++


 

W języku C++ istnieją dwie wartości logiczne:

 

false - fałsz
true - prawda
 

 

Są to predefiniowane stałe, którymi możemy się posługiwać w wyrażeniach logicznych:

 

false = 0
true = 1
 

 

Przez wyrażenie logiczne rozumiemy wyrażenie, które jest albo prawdziwe (sprowadza się do wartości true lub jest różne od zera) albo fałszywe (sprowadza się do wartości false lub do zera). Na przykład wyrażenie:  a > 10 jest typowym wyrażeniem logicznym. Wartość logiczna (true lub false) tego wrażenia zależy od bieżącej zawartości zmiennej a. Jeśli a faktycznie zawiera wartość większą od 10, to wyrażenie ma wartość logiczną true (1). W przeciwnym razie wartość logiczna wyrażenia to false (0). Poniższy przykład programowy obrazuje te zależności:

 

// Wartości logiczne
// (C)2006 mgr Jerzy Wałaszek
// I LO w Tarnowie

#include <iostream>

using namespace std;

int main()
{
  int a;

  a = 25; cout << (a > 10) << endl;
  a =  5; cout << (a > 10) << endl;
  return 0;
}

 

Wynika z tego, iż w języku C++ wartości logiczne są traktowane jak liczby. Takie podejście znacznie ułatwia programowanie. Umówmy się na przyszłość, iż wyrażenie jest prawdziwe, jeśli ma wartość różną od zera i fałszywe w przypadku przeciwnym.

Wyrażenia logiczne powstają często przy pomocy operatorów porównań:

 

operator opis przykład
< mniejszy niż a < 10
<= mniejszy lub równy a <= 10
== równy a == 10
!= różny a != 10
>= większy lub równy a >= 10
> większy niż a > 10

 

Logika w języku C++ ściśle opiera się na Algebrze Boole'a. Poniżej przedstawiamy dostępne w C++ operatory logiczne odpowiadające bezpośrednio funkcjom logicznym Algebry Boole'a:

 

operator opis przykład opis
! negacja !(a < 10) prawdziwe, gdy a >= 10
|| alternatywa (a == 1) || (a == 2) prawdziwe, gdy a=1 lub a=2
&& koniunkcja (a >= 1) && (a <=2) prawdziwe, gdy a należy do przedziału <1,2>

 

Tabelki tych operatorów są następujące:

 

negacja
a !a
false true
true false
alternatywa
a b a || b
false false false
false true true
true false true
true true true
koniunkcja
a b a && b
false false false
false true false
true false false
true true true

 

Przy obliczaniu wartości wyrażenia logicznego w języku C++ obowiązuje tzw. zasada zwarcia (ang. boolean short circuit). Polega ona na tym, iż wyrażenie jest obliczane tylko do momentu, gdy znana jest już jego wartość końcowa. Ma to głęboki sens. Na przykład:

 

(i < 10) && (a[i] == 12)

 

W tym wyrażeniu pierwszy człon (i < 10) sprawdza zapewne wartość indeksu tablicy. Być może tablica a[] posiada tylko 10 elementów a[0], a[1], ..., a[9]. Jeśli pierwsze wyrażenie jest fałszywe (czyli indeks wskazuje element nie należący do tablicy), to bez względu na wartość drugiego wyrażenia wynik jest również fałszywy (porównaj tabelkę dla && z pierwszym argumentem równym false). Zatem nie ma sensu wyznaczać wartości drugiego członu (a[i] == 12). Dlatego to wyrażenie nie będzie już wyznaczane (z drugiej strony nie ma ono nawet sensu, skoro i indeksuje poza tablicę) - nastąpi "zwarcie" po wyliczeniu pierwszego wyrażenia.


Zastosowanie wyrażeń logicznych

W języku C++ wyrażenia logiczne można stosować w następujących sytuacjach:

 

wyrażenie logiczne ? wartość1 : wartość2

Operator ? wylicza wartość wyrażenia logicznego. Jeśli jest ono prawdziwe, to wynikiem całości jest wartość1. W przeciwnym razie wynikiem jest wartość2. Na przykład wyrażenie:

 

((a > 5) && (a < 10)) ? a : -a

 

daje w wyniku a, jeśli a wpada w przedział otwarty (5,10) i -a w przypadku przeciwnym. Oto proste aplikacje operatora ?:

 

wyrażenie opis
(a > b) ? a : b większa z dwóch liczb a i b
(a < b) ? a : b mniejsza z dwóch liczb
(a > 0) ? a : -a wartość bezwzględna z a

 

if(wyrażenie logiczne) instrukcja1; else instrukcja2;

Instrukcja if (jeśli) jest tzw. instrukcją warunkową, która umożliwia tworzenie rozgałęzień w programie. Dzięki niej komputer może podejmować decyzje, a zatem postępować inteligentnie i dopasowywać swoje działania do aktualnej sytuacji. Instrukcja if jako argument przyjmuje wyrażenie logiczne. Jeśli wyrażenie to ma wartość prawdy (true lub większą od zera), to wykonana zostanie instrukcja1. Jeśli wyrażenie jest fałszywe (ma wartość false lub jest równe zeru), to wykonana zostanie instrukcja2. Zatem w zależności od wyniku wyrażenia logicznego wykonujemy różne instrukcje.

Człon else można pominąć - wtedy instrukcja1 będzie wykonywana warunkowo, gdy wyrażenie logiczne będzie prawdziwe.:

 

if(wyrażenie logiczne) instrukcja1

 

 Poniższy program wczytuje trzy liczby a,b i c i wyznacza największą z nich.

 

// max(a,b,c)
// (C)2006 mgr Jerzy Wałaszek
// I LO w Tarnowie

#include <iostream>

using namespace std;

int main()
{
  int a,b,c,max;

  cin >> a >> b >> c;
  max = a;
  if(b > max) max = b;
  if(c > max) max = c;
  cout << max << endl;
  return 0;
}

 

Jeśli zamiast pojedynczej instrukcji chcemy wykonać więcej różnych operacji, to zastępujemy ją tzw. instrukcją złożoną, czyli grupą instrukcji ujętych w klamry:

 

if(wyrażenie logiczne)
{
   
instrukcja1;
    instrukcja2;
    ...
    instrukcjan;
}
else
{
    ...
}

 

Zwróć uwagę, iż po klamerce zamykającej w instrukcji złożonej nie stosuje się już średnika.

 

while(wyrażenie logiczne) instrukcja;

Instrukcja while służy do tworzenia tzw. pętli warunkowych. Pętla jest to powtarzanie wybranej instrukcji (lub grupy instrukcji) w programie. Jeśli powtarzanie jest uzależnione od jakiegoś warunku, mamy do czynienia z pętlą warunkową. Instrukcja while wylicza wyrażenie logiczne. Jeśli jest ono prawdziwe, to wykonywana jest instrukcja (jeśli instrukcji ma być wykonane więcej niż jedna, to należy zastosować instrukcję złożoną, czyli klamerki). Po wykonaniu instrukcji znów następuje wyliczenie wartości wyrażenia logicznego i jeśli jest prawdziwe, ponowne wykonanie instrukcji. Całość się powtarza dotąd, aż w końcu warunek przestanie być prawdziwy. Wtedy pętla jest przerywana i program przechodzi do wykonania następnej instrukcji poza pętlą.

Poniższy program odczytuje ze standardowego wejścia liczbę, a następnie wyświetla jej kolejne potęgi aż do momentu, gdy przekroczą one wartość 1000.

 

// Pętla while
// (C)2006 mgr Jerzy Wałaszek
// I LO w Tarnowie

#include <iostream>

using namespace std;

int main()
{
  int a,p;

  cin >> a;
  p = a;
  while(p <= 1000)
  {
    cout << p << endl;
    p *= a;
  }
  cout << p << endl;
  return 0;
}

 

Zwróć uwagę, iż pętla while może nie wykonać się ani jeden raz, jeśli wyrażenie logiczne jest już na samym początku fałszywe. Jest to konsekwencja faktu, iż wartość wyrażenia logicznego sprawdzana jest przed wykonaniem obiegu pętli.

 

do instrukcja; while(wyrażenie logiczne);

Instrukcja do...while jest odmianą pętli warunkowej. Instrukcja zawarta w pętli powtarzana jest, jeśli wyrażenie logiczne jest prawdziwe. Jednakże w tym przypadku warunek kontynuacji pętli sprawdzany jest na końcu, po wykonaniu obiegu. Zatem instrukcja zawsze będzie wykonana przynajmniej jeden raz. Czasami taka opcja jest bardzo pożądana.

Powyższy program w wersji do...while znacznie się upraszcza:

 

// Pętla do...while
// (C)2006 mgr Jerzy Wałaszek
// I LO w Tarnowie

#include <iostream>

using namespace std;

int main()
{
  int a,p;

  cin >> a;
  p = 1;
  do
  {
    p *= a;
    cout << p << endl;
  } while(p <= 1000);
  return 0;
}

 

for(instrukcja1; wyrażenie logiczne; instrukcja2) instrukcja3;

Instrukcja for jest ogólną instrukcją pętli warunkowej. Skupia ona w jednym miejscu wszystkie elementy sterujące pętlą:

Całość for(instrukcja1; wyrażenie logiczne; instrukcja2) instrukcja3; tłumaczone jest przez kompilator na następującą sekwencję poleceń języka C++:

instrukcja1;  // przygotowanie pętli
while(wyrażenie logiczne) // pętla warunkowa
{

    instrukcja3; // powtarzana instrukcja
    instrukcja2; // przygotowanie zakończenia danego obiegu
}

Poniżej nasz program wyliczający kolejne potęgi wprowadzonej liczby aż do momentu, gdy przekroczą 1000.

 

// pętla warunkowa for
// (C)2006 mgr Jerzy Wałaszek
// I LO w Tarnowie

#include <iostream>

using namespace std;

int main()
{
  int a,p;

  cin >> a;
  for(p = 1; p <= 1000; p *= a) cout << p << endl;
  cout << p << endl;
  return 0;
}

 

Instrukcja for służy najczęściej do tworzenia tzw. pętli iteracyjnych. Termin iteracja oznacza kolejne zliczanie. Pętla iteracyjna to pętla, w której kolejne obiegi są zliczane, czyli po prostu posiadają swoje numery. Do zliczania obiegów potrzebujemy zmiennej licznikowej. Poniższy program wykorzystuje instrukcję for do utworzenia pętli iteracyjnej, która wykonuje obiegi o numerach od 1 do 9. Numery kolejnych obiegów są wypisywane na standardowym wyjściu.

 

// pętla iteracyjna for
// (C)2006 mgr Jerzy Wałaszek
// I LO w Tarnowie

#include <iostream>

using namespace std;

int main()
{
  for(int i = 1; i <= 9; i++) cout << i << endl;
  return 0;
}

 


Zmienne logiczne

Wartości logiczne można w języku C++ przechowywać w zmiennych logicznych, które deklarujemy na podstawie typu bool:

 

...
bool a,b,c;
...

 

Zmienna logiczna może przechowywać wartości true lub false. W pamięci komputera zajmuje 1 bajt (8 bitów). Poniższy program sprawdza rozmiar typu bool na twoim komputerze. Wynik jest podawany w bajtach.

 

// rozmiar typu logicznego
// (C)2006 mgr Jerzy Wałaszek
// I LO w Tarnowie

#include <iostream>

using namespace std;

int main()
{
  cout << sizeof(bool) << endl;
  return 0;
}

 

Poniższy program demonstruje przykładowe użycie zmiennej logicznej. Sprawdza on, czy liczba 10 występuje nieparzystą liczbę razy w ciągu 400 liczb pseudolosowych z zakresu od 0 do 10. Jeśli tak, wypisuje napis "10 nieparzyste".

 

// Zmienna logiczna
// (C)2006 mgr Jerzy Wałaszek
// I LO w Tarnowie

#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <time.h>

using namespace std;

int main()
{
  bool t;

  srand(time(NULL));
  t = false;
  for(int i = 0; i < 400; i++)
  {
    int x = rand() % 11;
    if(x == 10) t = !t;
    cout << setw(4) << x;
  }
  cout << endl;
  if(t) cout << "10 nieparzyste\n\n";
  return 0;
}

 

Uwaga. Jeśli sprawdzamy zawartość zmiennej logicznej, to nie musimy jej przyrównywać do false lub true, co często robią uczniowie:

 

zamiast powinno być
if(t == true) ... if(t) ...
if(t == false) ... if(!t) ...

 

Jeśli wykorzystujemy operację logiczną do modyfikacji zmiennej, to możemy zastosować tzw. formy skrócone operacji przypisania:

 
zamiast stosuje się
a = a || b; a ||= b;
a = a && b; a &&= b;

 



List do administratora Serwisu Edukacyjnego Nauczycieli I LO

Twój email: (jeśli chcesz otrzymać odpowiedź)
Temat:
Uwaga: ← tutaj wpisz wyraz  ilo , inaczej list zostanie zignorowany

Poniżej wpisz swoje uwagi lub pytania dotyczące tego rozdziału (max. 2048 znaków).

Liczba znaków do wykorzystania: 2048

 

W związku z dużą liczbą listów do naszego serwisu edukacyjnego nie będziemy udzielać odpowiedzi na prośby rozwiązywania zadań, pisania programów zaliczeniowych, przesyłania materiałów czy też tłumaczenia zagadnień szeroko opisywanych w podręcznikach.



   I Liceum Ogólnokształcące   
im. Kazimierza Brodzińskiego
w Tarnowie

©2017 mgr Jerzy Wałaszek

Dokument ten rozpowszechniany jest zgodnie z zasadami licencji
GNU Free Documentation License.