User Tools

Site Tools


dydaktyka:cprog:2016:loops

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
dydaktyka:cprog:2016:loops [2016/10/02 20:14]
pkleczek
— (current)
Line 1: Line 1:
-====== ​ Pętla "​while",​ debuggowanie ====== 
- 
-===== Cel laboratorium ===== 
- 
-  * Omówienie priorytetów operatorów. 
-  * Zapoznanie z pętlą ''​while''​ i ''​do-while''​. 
-  * Umiejętność posługiwania się //​debuggerem//​. 
- 
-===== Priorytet operatorów ===== 
- 
-Priorytet operatorów oznacza to samo, co kolejność działań w matematyce -- operator o wyższym priorytecie zostanie wykonany najpierw, a gdy obok siebie stoją, to operacje są wykonywane od lewej do prawej (chyba, że sam operator działa inaczej, o czym za chwilę). 
- 
-Przykładowo -- w matematyce -- wyrażenie $(2+2 \cdot 2) \cdot 2$ zostanie obliczone w następujących krokach: 
-  - Obliczenie wartości w nawiasie: 
-    - Obliczenie $2 \cdot 2 = 4$ 
-    - Obliczenie $2 + 4 = 6$ 
-  - Obliczenie $6 \cdot 2 = 12$ 
- 
-Dlaczego tak? Ponieważ -- mówiąc językiem programisty -- nawiasy mają najwyższy priorytet, a mnożenie ma wyższy priorytet od dodawania. 
- 
-Zapoznaj się z [[http://​en.cppreference.com/​w/​c/​language/​operator_precedence|tabelą priorytetów operatorów]] w języku C (**uwaga:** wielu z zawartych w niej operatorów jeszcze nie znasz, lecz część z nich wprowadzimy sukcesywnie na kolejnych zajęciach). \\ 
-Zwróć uwagę na kolumnę //​Associativity//,​ czyli "​kierunek wiązania"​. Oznacza to, która strona operatora zostanie obliczona w pierwszej kolejności (np. //​Left-to-right//​ oznacza, że najpierw obliczona zostanie lewa strona operatora) i niejako "w którą stronę działa operator"​ -- przykładowo operator przypisania ''​=''​ przypisuje wartość stojącą po jego **prawej** stronie zmiennej stojącej po **lewej** stronie, zatem jego kierunek wiązania to **Right-to-Left**. 
- 
-Tak więc, można stwierdzić,​ że //każde wyrażenie w języku C ma pewną wartość, obliczoną zgodnie z priorytetami i kierunkami wiązania operatorów//​. 
- 
-:!: Nie musisz pamiętać całej tej terminologii,​ lecz **musisz kojarzyć** o co w tym wszystkim chodzi. 
- 
----- 
- 
-**Zadanie 1** \\ 
-Napisz program sprawdzający,​ czy dla zadanej przez użytkownika liczby $x$ zachodzi $4 < x < 6$. \\ 
-Przetestuj swój program dla $x = 5$ oraz dla $x = 7$. 
-===== Pętla "​while"​ ===== 
- 
-Pętla ''​while''​ wykonuje instrukcję dopóty, dopóki spełniony jest warunek testowy (tzn. wyrażenie podane jako warunek ma wartość niezerową). 
- 
-Ogólna postać: 
-<​code>​ 
-while (wyrażenie_testowe) 
-    instrukcja 
-</​code>​ 
- 
-Pętla ''​while''​ to //pętla z warunkiem wejścia//, co oznacza że warunek sprawdzany jest **przed** każdym jej obiegiem (także pierwszym). 
- 
-Zazwyczaj zechcesz gdzieś wewnątrz pętli zmieniać wartości zmiennych tak, aby warunek wejścia stał się fałszywy :) 
- 
----- 
- 
-**Przykład** \\ 
-Obliczanie silni za pomocą pętli ''​while''​ -- porównaj z [[http://​home.agh.edu.pl/​~pkleczek/​dokuwiki/​doku.php?​id=dydaktyka:​cprog:​2015:​conditionals#​petla_for|programem]] wykonującym to samo zadanie z użyciem pętli ''​for''​. 
-<code c> 
-#include <​stdio.h>​ 
- 
-int main() 
-{ 
-    int s, n, i; 
- 
-    printf("​Podaj liczbe naturalna n: "); 
-    scanf("​%d",​ &n); 
- 
-    s = 1; 
-    i = 1; 
- 
-    while (i <= n) { 
-        s = s * i; 
-        i = i + 1; 
-    } 
- 
-    printf("​%d! = %d\n", n, s); 
- 
-    return 0; 
-} 
-</​code>​ 
- 
-Która pętla Twoim zdaniem lepiej nadaje się do tego zadania? 
- 
-Dobra praktyka programistyczna mówi: \\ 
-//Stosuj pętlę ''​for''​ tylko wtedy, gdy dokonujesz zarówno inicjalizacji,​ jak i aktualizacji. We wszystkich innych przypadkach lepiej (czytelniej) użyć pętli ''​while''​.//​ 
- 
----- 
- 
-**Zadanie 1** \\ 
-Napisz program obliczający wynik $n \cdot k$ dla zadanych liczb całkowitych $n$ i $k$ bez korzystania z mnożenia. Użyj pętli ''​while''​. \\ 
-//​Wskazówka:​ $n \cdot k = \underbrace{n + n + \ldots + n}_{k \text{ razy}}$// 
- 
-===== Pętla "​do-while"​ ===== 
- 
-Pętla ''​do-while'',​ podobnie jak pętla ''​while''​ wykonuje instrukcję dopóki spełniony jest warunek testowy. 
- 
-Ogólna postać: 
-<​code>​ 
-do 
-    instrukcja 
-while (wyrażenie_testowe);​ 
-</​code>​ 
-:!: Zwróć uwagę na średnik występujący po ''​%%while (...)%%''​! 
- 
-Różnica między dwoma typami pętli ''​while''​ polega na tym, że ''​do-while''​ to //pętla z warunkiem wyjścia// -- oznacza to, że warunek sprawdzany jest **po** każdym obiegu pętli (a więc petla wykona się **co najmniej raz**). 
- 
----- 
- 
-**Przykład** 
-<code c> 
-#include <​stdio.h>​ 
- 
-int main(void) 
-{ 
-    int i = 0; 
- 
-    printf("​Poczatek petli \n\n"​);​ 
- 
-    do { 
-        printf("​Wartosc zmiennej '​i'​ wynosi %d \n", i); 
-        i = i + 1; 
-    } while (i < 5); 
- 
-    printf("​\nKoniec petli"​);​ 
- 
-    return 0; 
-} 
-</​code>​ 
- 
----- 
- 
-W praktyce programiści starają się unikać stosowania ''​do-while'',​ gdyż: 
-  * umieszczanie warunku na końcu pętli zmniejsza czytelność kodu, natomiast 
-  * bez trudu można tak zmienić kod, aby zastąpić pętlę ''​do-while''​ pętlą ''​while''​. 
- 
-Uogólnienie powyższej zasady brzmi: \\ 
-//Lepiej stosować pętle z warunkiem wejścia (''​while'',​ ''​for''​),​ a nie wyjścia (''​do-while''​).//​ (nbsp) [size=10](z tych samych powodów, co podane powyżej)[/​size] 
- 
----- 
- 
-**Zadanie 1** \\ 
-Napisz program, który prosi użytkownika o podanie liczby całkowitej większej od $0$. Program powinien zakończyć działanie dopiero wtedy, gdy użytkownik podał poprawną wartość. 
- 
-**Zadanie 2** \\ 
-Napisz program losujący liczbę z przedziału $\langle 0, 100 \rangle$ tak długo aż wylosuje liczbę z przedziału $\langle 10, 15 \rangle$. \\ 
-Do losowania liczb służy funkcja [[http://​www.cplusplus.com/​reference/​cstdlib/​rand/?​kw=rand|rand()]] z biblioteki //​stdlib.h//​. 
- 
-===== Debugging ===== 
- 
-Zapoznaj się z materiałem dostępnym tu: [[dydaktyka:​cprog:​learning_resources:​debugging|Debugging]] 
- 
-===== Zadania podsumowujące ===== 
- 
-==== Zadanie DIGSUM ==== 
- 
-([size=10]poziom trudności:​[/​size] {{stars>​2/​4}}) 
- 
-Napisz program, który dla zadanej liczby całkowitej obliczy sumę jej cyfr. \\ 
-Przykład: dla $196$ poprawnym wynikiem jest $1 + 9 + 6 = 16$ 
- 
-//​Wskazówka:​ Wykorzystaj własność [[dydaktyka:​cprog:​2015:​data_types#​arytmetyka_liczb_w_c_-_pulapki|dzielenia i obcięcia w języku C]].// 
- 
-==== Zadanie BABSQRT ==== 
- 
-([size=10]poziom trudności:​[/​size] {{stars>​3/​4}}) 
- 
-Napisz program obliczający pierwiastek kwadratowy zadanej liczby [[https://​pl.wikipedia.org/​wiki/​Metody_obliczania_pierwiastka_kwadratowego#​Metoda_babilo.C5.84ska|metodą babilońską]] (kroki 1-3). Przerwij obliczenia, gdy różnica między kolejnymi przybliżeniami jest mniejsza niż $10^{-4}$. 
- 
-//​Wskazówka:​ Jako pierwsze oszacowanie możesz przyjąć $\sqrt{S} \approx S$ ;-) // 
- 
-[size=10]Być może zastanawiasz się: //Po co ręcznie obliczać pierwiastek?​ Przecież można skorzystać z wbudowanej funkcji [[http://​www.cplusplus.com/​reference/​cmath/​sqrt/​|sqrt()]]! // \\ 
-Owszem, lecz jeśli nie potrzebujesz mega-dużej dokładności,​ to metodą babilońską uzyskasz wystarczająco dobry wynik o wiele, wiele szybciej.[/​size] 
  
dydaktyka/cprog/2016/loops.1475432049.txt.gz · Last modified: 2020/03/25 11:46 (external edit)