This is an old revision of the document!
for
.if
oraz jej wariantami (if-else
, if-else if-else
).%
(modulo).Oprócz operatorów arytmetycznych istnieją również operatory, które stosuje się do porównywania danych – podobnie jak w matematyce.
Poniższa tabela zestawia operatory relacyjne i podaje ich znaczenie (zwróć szczególną uwagę na operator równy oraz różny):
Operator | Opis |
---|---|
== | równy |
> | większy |
< | mniejszy |
>= | większy lub równy |
<= | mniejszy lub równy |
!= | różny |
Wynik relacji fałszywej wynosi zawsze 0
.
Wynik relacji prawdziwej wynosi zawsze 1
.
Język C nie udostępnia typu logicznego (o wartościach prawda i fałsz); zamiast tego reprezentuje te wartości korzystając z typu
int
.
Przykład użycia operatorów relacyjnych:
#include <stdio.h> int main(void) { int a = 12; int b = 34567; int r1 = (a < b); int r2 = (a == b); printf("a < b = %d\n", r1); printf("a == b = %d\n", r2); return 0; }
Pętla for
(ang. dla) pozwala na wykonywanie fragmentu programu określoną ilość razy.
Wykorzystuje ona trzy wyrażenia rozdzielone średnikami:
Pętla for
kończy się jedną instrukcją prostą lub złożoną.
Pętla for
to “pętla z warunkiem wejścia”, co oznacza że pętla może nie wykonać się ani razu, jeśli na samym początku warunek nie został spełniony.
Ogólna postać pętli for
:
for (inicjalizacja; test; aktualizacja) instrukcja
Przykład 1 – Wielokrotne wypisywanie na ekran
#include <stdio.h> int main() { int i; for(i = 1; i <= 10; i++) { printf("%d\n", i); } return 0; }
Przykład 2 – Obliczanie silnii
#include <stdio.h> int main() { int s, n, i; printf("Podaj liczbę naturalną n: "); scanf("%d", &n); s = 1; for(i = 2; i <= n; i++) { s = s * i; } printf("%d! = %d\n", n, s); return 0; }
Zadanie 1
Napisz program, który oblicza sumę liczb całkowitych z zakresu od 1 do 10 przy pomocy pętli for
.
Zadanie 2
Napisz program, który wczytuje dwie liczby całkowite ($a$ i $b$, przy czym $a \Leftarrow b$) i oblicza sumę liczb z przedziału $\langle a, b \rangle$.
Często chcemy, aby działanie programu zależało od pewnego warunku, na przykład “jeśli dzielnik wynosi 0, to wyświetl komunikat o błędzie, w przeciwnym razie oblicz wartość dzielenia”. Do realizacji takich zadań służy m.in. instrukcja warunkowa if
.
Instrukcja warunkowa podejmuje decyzję “którą instrukcję wykonać w następnej kolejności” na podstawie wartości wyrażenia podanego w warunku . Bardzo często jako warunku używa się wyrażenia relacyjnego.
W języku C warunek uznawany jest za spełniony (prawdziwy), jeśli jego wartość jest różna od 0 (a więc niekoniecznie wynosi 1!).
Ogólna postać instrukcji if
:
if (wyrażenie) instrukcja
Przykład 1
#include <stdio.h> int main() { int wiek = 60; if(wiek > 50) { printf("Warunek spelniony - osoba ma ponad 50 lat.\n"); } if(wiek == 50) { printf("Warunek spelniony - osoba ma rowno 50 lat.\n"); } return 0; }
PS. Po co te “wąsiki”? - Przeczytaj kolejny fragment laboratorium.
Uwaga
Programistom zdarza się przez nieuwagę zamiast ==
napisać =
. Ponieważ wartość wyrażenia przypisania wynosi tyle, co przypisywana wartość – czyli to, co stoi po prawej stronie – stąd wyrażenie to jest prawdziwe gdy tylko przypisujemy dowolną wartość różną od 0
:
#include <stdio.h> int main() { int wiek = 60; if(wiek > 50) { printf("Warunek spelniony - osoba ma ponad 50 lat.\n"); } if(wiek = 50) { // czy na pewno chodzilo o operator przypisania '='? printf("Warunek spelniony - osoba ma rowno 50 lat.\n"); } if(wiek = 0) { // czy na pewno chodzilo o operator przypisania '='? printf("Warunek spelniony - osoba dopiero sie urodzila.\n"); } return 0; }
Blok instrukcji (inaczej: instrukcja złożona) to przynajmniej dwie instrukcje scalone ze sobą poprzez zawarcie ich w nawiasach klamrowych: { }
Blok instrukcji jest traktowany przez kompilator jak pojedyncza instrukcja.
Porównaj działanie poniższych programów:
#include <stdio.h> int main() { int wiek = 16; // nie ma klamer if(wiek > 18) printf("Osoba jest pelnoletnia.\n"); printf("Osoba moze wyrobic dowod osobisty.\n"); return 0; }
#include <stdio.h> int main() { int wiek = 16; // sa klamry if(wiek > 18) { printf("Osoba jest pelnoletnia.\n"); printf("Osoba moze wyrobic dowod osobisty.\n"); } return 0; }
Instrukcja warunkowa if
w przypadku spełnienia warunku wykonuje tylko jedną instrukcję, znajdującą się bezpośrednio za if
-em.
W przypadku pierwszego programu (mimo wcięć w kodzie) instrukcja if
obejmuje tylko pierwsze wywołanie funkcji printf()
.
W drugim przypadku umieszczenie obu instrukcji printf()
w bloku kodu pozwala na wykonanie ich obu w przypadku spełnienia warunku.
Często chcemy, aby działanie programu zależało od pewnego warunku, na przykład “jeśli dzielnik wynosi 0, to wyświetl komunikat o błędzie, w przeciwnym razie oblicz wartość dzielenia”. Do realizacji takich zadań służy m.in. instrukcja warunkowa if-else
(ang. else – w przeciwnym razie).
Ogólna postać instrukcji if-else
:
if (wyrażenie) instrukcja1 else instrukcja2
Jeśli warunek jest prawdą, wykonywana jest instrukcji następująca po słowie kluczowym if
(czyli instrukcja1
).
W przeciwnym razie wykonywana jest instrukcja po słowie kluczowym else
(czyli instrukcja2
).
Przykład 1
#include <stdio.h> int main() { int wiek = 40; if (wiek > 50) { printf("Warunek spelniony - osoba ma ponad 50 lat.\n"); } else { printf("Warunek nie byl spelniony - zatem osoba nie ma wiecej niz 50 lat.\n"); } return 0; }
Przykład 2 - Zagnieżdżanie instrukcji
#include <stdio.h> int main() { int wiek = 40; if (wiek > 50) { if (wiek > 70) { printf("Osoba ma ponad 70 lat.\n"); } else { printf("Osoba ma ponad 50, lecz mniej niz 70 lat.\n"); } } else { printf("Osoba nie ma wiecej niz 50 lat.\n"); } return 0; }
PS. Za moment poznasz sposoby na zapisanie tego w bardziej czytelny sposób…
Zdarza się, że chcemy niejako wybrać spośród jednej z kilku możliwości – na przykład aby określić ilość miejsc zerowych równania kwadratowego rozpatrujemy trzy przypadki: $\Delta > 0$, $\Delta = 0$ oraz $\Delta < 0$.
Do realizacji takiego zadania służy instrukcja if-else if-else
o ogólnej postaci:
if (wyrażenie1) instrukcja1 else if (wyrażenie2) instrukcja2 ... else if (wyrażenie_n-1) instrukcja_n-1 else instrukcja_n
Jeśli pierwszy warunek jest prawdą, wykonywana jest instrukcja instrukcja1
.
W przeciwnym razie, jeśli prawdziwe jest drugie wyrażenie, wykonaj instrukcję instrukcja2
– i tak dalej.
Jeśli żaden z warunków nie został spełniony, wykonaj instrukcję po else
(czyli instrukcję instrukcja_n
).
Przykład
Aby uczynić program do weryfikacji wieku bardziej czytelnym możemy napisać:
#include <stdio.h> int main() { int wiek = 40; if (wiek > 70) { printf("Osoba ma ponad 70 lat.\n"); } else if (wiek > 50) { printf("Osoba ma ponad 50, lecz mniej niz 70 lat.\n"); } else { printf("Osoba nie ma wiecej niz 50 lat.\n"); } return 0; }
Operatory logiczne języka C pozwalają na łączenie operatorów relacyjnych w bardziej efektywne instrukcje służące do testowania danych. Poniższa tabela przedstawia operatory logiczne:
operator | opis | odpowiednik w algebrze Boole'a | przykład |
---|---|---|---|
&& | i (AND) | $\wedge$ | a && b |
|| | lub (OR) | $\vee$ | a || b |
! | nie (NOT) | $\neg$ | !a |
Wynik relacji prawdziwej wynosi zawsze
1
, a fałszywej – 0
.
Przykład
Poniższy kod sprawdza wartość logiczną wyrażenia $\neg (a < b \wedge b > c)$:
#include <stdio.h> int main() { int a = 1; int b = 12; int c = 100; printf("%d\n", !((a < b) && (b > c))); return 0; }
Przez ostatnie dwa laboratoria używaliśmy wielu pojęć, które są dla Ciebie prawdopodobnie obce. Teraz, gdy już masz pewną intuicję co do działania pewnych konstrukcji języka C, możemy je odrobinę dokładniej zdefiniować.
W języku C pewne operacje (np. działania matematyczne) wyrażane są za pomocą operatorów. Na przykład, operator +
powoduje zsumowanie wartości znajdujących się po jeo obydwu stronach.
Skąd nazwa “operator”? Hm… może po prostu brzmi lepiej niż “ta rzecz”?
Operand to “coś”, czym posługują się operatory. Na przykład dla operatora dzielenia (/
) lewym operandem jest dzielna, a prawym – dzielnik.
Wyrażenie (expression) to kombinacja operatorów i operandów. Każde wyrażenie w języku C ma wartość.
Oto kilka przykładów wyrażeń:
wyrażenie | wartość |
---|---|
4 | 4 |
-6 | -6 |
4 + 21 | 25 |
a * (b + c / d) / 20 | (zależy od wartości a , b i c ) |
q = 5 * 2 | 10 |
7 > 3 | 1 |
Najprościej mówiąc – instrukcja (statement) to wyrażenie, na końcu krórego znajduje się średnik.
Zatem a = 5
jest wyrażeniem, natomiast a = 5;
to już instrukcja.
Program komputerowy składa się głównie właśnie z instrukcji.
Oto przykłady instrukcji:
#include <stdio.h> int main() { int a; a = 1; // instrukcja przypisania if (a > 4) { // instrukcja warunkowa printf("%d\n", a); // instrukcja wywołania funkcji } return 0; }
Być może zastanawiasz się: Jak to if
jest instrukcją? Przecież nie ma na końcu średnika!
Odpowiedź brzmi – blok instrukcji traktowany jest jak jednak instrukcja.
Sam średnik również oznacza instrukcję – instrukcję pustą – zatem poniższy program jest poprawny, choć niekoniecznie robi to, co zapewne miał robić w zamierzeniu jego twórcy:
#include <stdio.h> int main() { int a = 3; // Oblicz wartosc bezwzgledna liczby 'a' if (a < 0); a = -a; printf("%d\n", a); return 0; }
Jeśli program nie działa tak, jak oczekujesz, sprawdź czy na końcu linii z if
albo for
nie znalazł się przypadkiem średnik.
Z drugiej strony tę właściwość można ciekawie wykorzystać - patrz: idiom do czyszczenia bufora wejściowego.
Napisz program, który poda ilość rozwiązań równania kwadratowego dla zadanych przez użytkownika współczynników $a$, $b$ i $c$.
Napisz program, który sprawdzi czy zadana przez użytkownika liczba jest liczbą parzystą i wypisze odpowiedni komunikat.
Wskazówka: Podczas rozwiązywania tego zadania może Ci się przydać operator modulo (%
), który zwraca resztę z dzielenia, np. wyrażenie 5 % 3
ma wartość 2.
Napisz program sprawdzający w naiwny sposób (czyli: najprostszy), czy zadana przez użytkownika liczba jest liczbą pierwszą.
Wykorzystaj pętlę for
i operator modulo (%
).