Język C i C++. Warunki, instrukcje wyboru

Podobne dokumenty
Instrukcje warunkowe i skoku. Spotkanie 2. Wyrażenia i operatory logiczne. Instrukcje warunkowe: if else, switch.

if (warunek) instrukcja1; if (warunek) instrukcja1; else instrukcja2; a > b - a większe od b if (warunek) instrukcja1; a <= b - a mniejsze lub równe b

Warto też w tym miejscu powiedzieć, że w C zero jest rozpoznawane jako fałsz, a wszystkie pozostałe wartości jako prawda.

3. Instrukcje warunkowe

Operacje wykonywane są na operandach (argumentach operatorów). Przy operacji dodawania: argumentami operatora dodawania + są dwa operandy 2 i 5.

Podstawy Programowania Podstawowa składnia języka C++

Instrukcja do ćwiczeń nr 4 typy i rodzaje zmiennych w języku C dla AVR, oraz ich deklarowanie, oraz podstawowe operatory

Podstawy programowania C. dr. Krystyna Łapin

Odczyt danych z klawiatury Operatory w Javie

4. Funkcje. Przykłady

Temat 1: Podstawowe pojęcia: program, kompilacja, kod

Wskaźniki a tablice Wskaźniki i tablice są ze sobą w języku C++ ściśle związane. Aby się o tym przekonać wykonajmy cwiczenie.

1 Podstawy c++ w pigułce.

1 Wielokrotne powtarzanie tych samych operacji

2 Przygotował: mgr inż. Maciej Lasota

Podstawy Informatyki. Inżynieria Ciepła, I rok. Wykład 10 Kurs C++

7. Pętle for. Przykłady

Cw.12 JAVAScript w dokumentach HTML

JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Laboratorium 3. Instrukcje wyboru

Po uruchomieniu programu nasza litera zostanie wyświetlona na ekranie

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

Wstęp do Programowania, laboratorium 02

JAVAScript w dokumentach HTML (1) JavaScript jest to interpretowany, zorientowany obiektowo, skryptowy język programowania.

C++ wprowadzanie zmiennych

znajdowały się różne instrukcje) to tak naprawdę definicja funkcji main.

Języki programowania C i C++ Wykład: Typy zmiennych c.d. Operatory Funkcje. dr Artur Bartoszewski - Języki C i C++, sem.

Programowanie w języku Python. Grażyna Koba

Nazwa implementacji: Nauka języka Python pętla for. Autor: Piotr Fiorek

Podstawy i języki programowania

Podstawy Programowania C++

Celem tego projektu jest stworzenie

Podstawy programowania. Wykład: 4. Instrukcje sterujące, operatory. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD

Tablice (jedno i wielowymiarowe), łańcuchy znaków

Spis treści JĘZYK C - OPERATORY RELACYJNE I LOGICZNE, WYRAŻENIA LOGICZNE, INSTRUKCJA WARUNKOWA IF. Informatyka 1

lekcja 8a Gry komputerowe MasterMind

/*W tym miejscu funkcja system wywołuje systemową komendę PAUSE tj.czeka tak długo, aż zostanie wciśnięty dowolny znak z

Strona główna. Strona tytułowa. Programowanie. Spis treści. Sobera Jolanta Strona 1 z 26. Powrót. Full Screen. Zamknij.

Programowanie w C/C++ Instrukcje - konstrukcje powtórka. LABORKA Piotr Ciskowski

Pętle. Dodał Administrator niedziela, 14 marzec :27

Pętla for. Wynik działania programu:

Spis treści JĘZYK C - INSTRUKCJA WARUNKOWA IF, OPERATORY RELACYJNE I LOGICZNE, WYRAŻENIA LOGICZNE. Informatyka 1

Podstawy Informatyki. Kompilacja. Historia. Metalurgia, I rok. Kompilatory C++ Pierwszy program. Dyrektywy preprocesora. Darmowe:

Programowanie. programowania. Klasa 3 Lekcja 9 PASCAL & C++

Elżbieta Kula - wprowadzenie do Turbo Pascala i algorytmiki

Operatory. Operatory bitowe i uzupełnienie informacji o pozostałych operatorach. Programowanie Proceduralne 1

Programowanie strukturalne i obiektowe

1 Podstawy c++ w pigułce.

Podstawy Informatyki. Metalurgia, I rok. Wykład 6 Krótki kurs C++

Zmienne, stałe i operatory

Laboratorium Podstaw Informatyki. Kierunek Elektrotechnika. Ćwiczenie 1. Podstawy. Wprowadzenie do programowania w języku C. Katedra Metrologii AGH

Laboratorium Wstawianie skryptu na stroną: 2. Komentarze: 3. Deklaracja zmiennych

dr inż. Jarosław Forenc

W przeciwnym wypadku wykonaj instrukcję z bloku drugiego. Ćwiczenie 1 utworzyć program dzielący przez siebie dwie liczby

PODSTAWY INFORMATYKI 1 PRACOWNIA NR 6

Struktura pliku projektu Console Application

Języki i metodyka programowania. Typy, operatory, wyrażenia. Wejście i wyjście.

Wskaźniki w C. Anna Gogolińska

Spis treści JĘZYK C - INSTRUKCJA WARUNKOWA IF, OPERATORY RELACYJNE I LOGICZNE, WYRAŻENIA LOGICZNE. Metodyki i techniki programowania

/* dołączenie pliku nagłówkowego zawierającego deklaracje symboli dla wykorzystywanego mikrokontrolera */ #include <aduc834.h>

Część 4 życie programu

Przedrostkowa i przyrostkowa inkrementacja i dekrementacja

I - Microsoft Visual Studio C++

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

Podstawy programowania skrót z wykładów:

WYKŁAD 8. Funkcje i algorytmy rekurencyjne Proste przykłady. Programy: c3_1.c..., c3_6.c. Tomasz Zieliński

Język C++ zajęcia nr 2

Instrukcje sterujące. wer. 11 z drobnymi modyfikacjami! Wojciech Myszka :53:

Język C zajęcia nr 11. Funkcje

Programowanie I C / C++ laboratorium 03 arytmetyka, operatory

Instytut Mechaniki i Inżynierii Obliczeniowej Wydział Mechaniczny Technologiczny Politechnika Śląska

Instrukcja wyboru, pętle. 2 wykład. Podstawy programowania - Paskal

Wstęp do programowania INP003203L rok akademicki 2018/19 semestr zimowy. Laboratorium 2. Karol Tarnowski A-1 p.

1 Wskaźniki i zmienne dynamiczne, instrukcja przed zajęciami

Warunek wielokrotnego wyboru switch... case

Powtórka algorytmów. Wprowadzenie do języka Java.

Programowanie komputerowe. Zajęcia 1

Zmienne powłoki. Wywołanie wartości następuje poprzez umieszczenie przed nazwą zmiennej znaku dolara ($ZMIENNA), np. ZMIENNA=wartosc.

1. Napisz program, który wyświetli Twoje dane jako napis Witaj, Imię Nazwisko. 2. Napisz program, który wyświetli wizytówkę postaci:

Operatory w C++ Operatory arytmetyczne. Operatory relacyjne (porównania) Operatory logiczne. + dodawanie - odejmowanie * mnożenie / dzielenie % modulo

Język C zajęcia nr 5

Informatyka I: Instrukcja 4.2

Informacja o języku. Osadzanie skryptów. Instrukcje, komentarze, zmienne, typy, stałe. Operatory. Struktury kontrolne. Tablice.

Programowanie - instrukcje sterujące

Struktury, unie, formatowanie, wskaźniki

Konwersje napis <-> liczba Struktury, unie Scanf / printf Wskaźniki

Widoczność zmiennych Czy wartości każdej zmiennej można zmieniać w dowolnym miejscu kodu? Czy można zadeklarować dwie zmienne o takich samych nazwach?

Stuck in the loop. Sterowanie. Marcin Makowski. 29 października Zak lad Chemii Teoretycznej UJ

Podstawy programowania w języku C i C++

Programowanie w Baltie klasa VII

Podstawy programowania. Wykład Pętle. Tablice. Krzysztof Banaś Podstawy programowania 1

JAVAScript w dokumentach HTML (1)

Obsługa plików. Laboratorium Podstaw Informatyki. Kierunek Elektrotechnika. Laboratorium Podstaw Informatyki Strona 1. Kraków 2013

Podstawy języka C++ Maciej Trzebiński. Instytut Fizyki Jądrowej Polskiej Akademii Nauk. Praktyki studenckie na LHC IVedycja,2016r.

Programowanie obiektowe - zadania

Laboratorium 1: Podstawy języka c. dr inż. Arkadiusz Chrobot dr inż. Grzegorz Łukawski

Lekcja 3: Pierwsze kroki z Pythonem. Pętle

METODY KOMPUTEROWE W OBLICZENIACH INŻYNIERSKICH

Operatory cd. Relacyjne: ==!= < > <= >= bool b; int i =10, j =20; dzielenie całkowitych wynik jest całkowity! Łączenie tekstu: + string s = "Ala ma ";

Wprowadzenie do programowania w języku C

Transkrypt:

Język C i C++. Warunki, instrukcje wyboru Język C nie narzuca stosowania specjalnego typu danych do warunków logicznych. Warunkiem w C może być dowolna liczba całkowita lub wskaźnik, przy czym wartość 0 (NULL) oznacza fałsz, a wartość różna od zera prawdę. Z prostych warunków logicznych można składać bardziej złożone zdania logiczne, używając operatorów logicznych. && AND Iloczyn logiczny. Przykład: if (a==0 && b==7) printf("komunikat"); OR Suma logiczna. Przykład: if (a==999 f() ) printf("komunikat");! NOT Negacja, czyli zaprzeczenie warunku logicznego. Np. if(!a ) printf("komunikat"); Negacja prawdy daje w wyniku 0 (fałsz), negacja fałszu daje w wyniku 1 (prawdę). Końcowy wynik (wartość zdania logicznego złożonego z wielu prostszych warunków) jest wyliczana od lewej do prawej (w takiej kolejności, w jakie czytamy zapisane wyrażenie). Jeśli w pewnym momencie jednoznacznie udaje się ustalić, jaka będzie końcowa wartość całego wyrażenia, to kolejne warunki nie są sprawdzane. Co to oznacza w praktyce? To, że w pewnych przypadkach dalsze instrukcje, z jakich składa się zdanie logiczne będą wykonywane, w innych zaś nie. Funkcja rand(), której za chwilę użyjemy, wymaga dołączenia nagłówka #include <stdlib.h>. Ponadto, aby wartości były chociaż trochę losowe, należy wystartować generator liczb losowych z losową wartością początkową. Najłatwiej można to osiągnąć wykonując jako pierwszą instrukcję w programu srand(time(null));. Weźmy następujący przykład: #include <stdio.h> #include <stdlib.h> int f() printf("błysk!\n"); //wyzwolenie_lampy_błyskowej(); return rand() % 2; //zwróć losowo 0 albo 1, czyli fałsz albo prawdę int main() srand(time(null)); //co sekundę jest to inna wartość if ( 1 f() f() f() f() f() ) printf("warunek prawdziwy\n"); printf("warunek fałszywy\n"); Krzysztof Urbański 2011 1

Ten kod zadziała zupełnie inaczej, niż gdybyśmy zapisali: if ( 0 f() f() f() f() f() ). Ile razy błyśnie lampa w obu przypadkach? Czy da się to w ogóle jednoznacznie określić? Przetestuj ten kod uruchamiając go wielokrotnie i obserwuj wyniki. Wniosek: unikaj używania w warunkach takich instrukcji, które modyfikują wartości zmiennych lub mają na celu wywołanie innych działań w programie. W różnych scenariuszach wykonania programu może to doprowadzić do całkowicie losowego działania aplikacji! Zadanie do realizacji: popraw powyższy kod w taki sposób, aby lampa błyskała zawsze 5 razy niezależnie od szczęścia i innych czynników zewnętrznych. Skoro każda wartość różna od zera jest traktowana jak prawda, to prawdziwe są warunki: 1, 1234, zmienna_calkowita (przy założeniu, że zmienna ta ma wartość różną od zera). Konsekwentnie, wszystkie wskaźniki, które nie są puste (nie są NULL) też odpowiadają wartości prawda. Tylko 0 i NULL są fałszem. Przykład: FILE *f = fopen("nazwa.txt", "r"); if (f!= NULL) fscanf(f, "%d", &zmienna); fclose(f); Możemy uprościć powyższy warunek do postaci: if (f) fscanf(f, "%d", &zmienna); fclose(f); Warunek (f) będzie prawdziwy wtedy i tylko wtedy, gdy f będzie różne od NULL (nie będzie wskaźnikiem pustym. Zdradliwe = i == Operator podstawienia (=) w języku C działa w szczególny sposób. Powoduje przypisanie pod zmienną po prawej stronie wartości wyliczonej z wyrażenia stojącego po lewej. Dodatkowo, całe wyrażenie podstawienia ma wartość równą temu, co zostało podstawione. Możliwe jest zatem użycie tej wartości do podstawienia pod kolejną zmienną. Przykład: int a = 7, b = 7, c = 7; printf("%d\n", c=113); printf("%d\n", c); Skoro wyrażenie (c=113) ma wartość 113, to czemu by nie podstawić jego wartości pod zmienną b? Mamy wtedy: b = (c=113); przy czym można pominąć nawiasy i ostatecznie otrzymamy b = c = 113; Krzysztof Urbański 2011 2

Skoro pod b coś podstawiamy (konkretnie będzie to 113), to ta instrukcja też zwraca wartość 113. Podstawmy ją pod a: a = b = c = 113; Jest to wygodny sposób nadawania tej samej wartości wielu zmiennym, zwłaszcza wtedy, gdy często zmieniamy zdanie i chcemy szybko zastąpić 113 czymś innym, na przykład 999: a = b = c = 999; Jest to wygodniejsze niż zamiana a = 113; b = 113; c = 113; na a = 999; b = 999; c = 999;. Mniej przyjemne konsekwencje wystąpią wtedy, gdy popełnisz pomyłkę i w warunku użyjesz instrukcji podstawienia zamiast porównania: int a = 0; if (a==1) printf("prawda"); printf("fałsz"); printf("\nzmienna a ma wartość %d\n", a); Porównaj wyniki powyżej z następującymi: if (a=1) printf("prawda"); printf("fałsz"); printf("\nzmienna a ma wartość %d\n", a); Współczesne kompilatory ostrzegają przed takim potencjalnym błędem, warto więc czytać komunikaty ostrzeżeń ( warning ) w oknie kompilatora. Celowe użycie takich karkołomnych instrukcji (tzn. użycie instrukcji podstawienia = w warunku) jest możliwe i poprawne pod względem składniowym, ale zwykle przynosi więcej szkody niż pożytku. Przykład (nie należy go naśladować): int a = 1, b = 2; if (a (a=b)) printf("prawda"); printf("fałsz"); printf("\na==%d, b==%d\n", a, b); Zmień kod, uruchom i ponownie obejrzyj wyniki, tym razem niech a będzie miało początkową wartość 0: int a = 0, b = 2; Pytanie Dlaczego tak jest? Krzysztof Urbański 2011 3

Instrukcja wielokrotnego wyboru?: warunek? wartość_gdy_prawda : wartość_gdy_fałsz; Jeśli warunek jest prawdziwy, to wartością całego wyrażenia jest to, co stoi przed dwukropkiem, w przeciwnym razie tą wartością jest to, co stoi za dwukropkiem. Jest to chętnie stosowana instrukcja, zwiększa zwięzłość kodu. Działa podobnie jak if.. tylko dodatkowo zwraca wynik jako wartość całego wyrażenia. Tę wartość można np. podstawić pod zmienną lub użyć jako argumentu return w funkcji. Przykład: funkcja abs(x), czyli wartość bezwzględna z x. int abs(int x) if (x < 0) return -x; return x; albo int abs(int x) int wynik; if (x < 0) wynik = -x; wynik = x; return wynik; Wersja bardziej zwięzła: int abs(int x) return x < 0? -x : x; Instrukcje?: można zagnieżdżać, co bardzo ładnie widać na przykładzie funkcji sgn(x): + 1 sgn( x ) = 0 1 dla x > 0 dla x = 0 dla x < 0 int sgn(int x) if (x > 0) return +1; if (x == 0) return 0; if(x < 0) return -1; Wiedząc, że po return funkcja kończy działanie i nie są wykonywane dalsze instrukcje, można ten kod uprościć: Krzysztof Urbański 2011 4

int sgn(int x) if (x > 0) return +1; if (x < 0) return -1; return 0; //kiedy x>0 oraz x<0 były fałszem, to nie potrzeba //sprawdzać że x==0, bo to jest oczywiste. Można też jeszcze krócej zapisać: int sgn(int x) return x>0? +1 : (x<0? -1 : 0); Niektóre mikroprocesory mają wbudowane rozkazy przyspieszające wykonanie?:, zaś niezależnie od tego zwykle ta instrukcja daje po kompilacji szybszy kod maszynowy. Mniej oczywiste użycie?: Wskaźniki mogą być używane w wyrażeniach arytmetycznych (są przecież szczególnej postaci adresami, czyli liczbami, a na liczbach można wykonywać pewne obliczenia). Najczęściej używanym wskaźnikiem w C jest wskaźnik znakowy (char*), zatem użyjemy go w poniższym przykładzie. Chcemy wyświetlić komunikat o tym, czy x jest parzyste czy nieparzyste. Można to zapisać klasycznie w taki sposób: if (x % 2!= 0) //jeżeli reszta z dzielenia x przez 2 nie wynosi 0 printf("liczba %d jest nieparzysta.", x); printf("liczba %d jest parzysta.", x); Zauważ, że printf() to funkcja, która też zwraca wynik (jaki?). W zależności od tego, czy x jest parzyste czy nie, wywołujemy inną wersję printf( ). Moglibyśmy zapisać to krócej: x%2!=0? printf("liczba %d jest nieparzysta.", x) : printf("liczba %d jest parzysta.", x); Wyniku całego wyrażenia nie musimy pod nic podstawiać, język C nie zmusza nas do tego. Wyrażenia po lewej i prawej stronie dwukropka są bardzo podobne. W obu przypadkach jest to printf, pewien napis oraz zmienna x. Czym jest napis w języku C? to wskaźnik. A wskaźniki można dodawać, porównywać, zwracać jako wynik działania funkcji oraz używać w wyrażeniach?:. printf(x%2? "Liczba %d jest nieparzysta.":"liczba %d jest parzysta.", x); Pierwszym argumentem printf musi być wskaźnik znakowy (char*). Takim wskaźnikiem jest napis w języku C, np. "abc" czy "Liczba %d jest nieparzysta.". W zależności od wyniku (x%2) posługujemy się wskaźnikiem z lewej lub prawej strony wyrażenia, a zyskujemy o jedno wywołanie funkcji printf() mniej. Krzysztof Urbański 2011 5

Czy można jeszcze bardziej się streścić? Zauważmy podobieństwo lewego i prawego napisu. Czasem posługujemy się słowem parzysta, czasem zaś nieparzysta. Słowa te można przedstawić jako napisy języka C. Można też, używając formatowanego stdout i funkcji printf, posłużyć się ciągiem %s aby wstawić w odpowiednie miejsce głównego napisu właściwe słowo. Szablon napisu wygląda wtedy tak: "Liczba %d jest %s." przy czym zamiast %d zostanie wyświetlona wartość x, a zamiast %s pojawi się słowo parzysta bądź nieparzysta. printf("liczba %d jest %s.", x, x%2? "nieparzysta" : "parzysta"); Różnica między komunikatami to zaledwie 3 litery (partykuła nie). W napisie "Liczba %d jest nieparzysta." czerwone nie czasem występuje, czasem zaś go nie ma. Kiedy go nie ma, to w tym miejscu można wstawić pusty napis (""), który w C zapisujemy jako dwa znaki cudzysłów, między którymi nic się nie znajduje. printf("liczba %d jest %sparzysta.", x, x%2? "nie" : ""); Zadanie treningowe Posługując się instrukcją?:, w jednej funkcji printf( ) zapisz wynik pomiaru napięcia double U w następujący sposób: Jeśli U>=1.000, to wyświetl Napięcie wynosi +x.xxx V. Jeśli U<1.000 i U>-1.000, to wyświetl Napięcie wynosi xxx mv. Jeśli U <= -1.000, to wyświetl Napięcie wynosi -x.xxx V. Wskazówka: użyj gotowej funkcji fabs( ), która zwróci wartość bezwzględną liczby zmiennoprzecinkowej, lub sam napisz taką funkcję modyfikując kod funkcji int abs(int x) z wcześniejszych stron tego dokumentu. Krzysztof Urbański 2011 6

Instrukcja wielokrotnego wyboru switch..case..default if(znak=='k' znak=='k') koniec_swiata(); if(znak==13) odpal_jakas_duza_rakiete(); if(znak=='?') wezwij_na_pomoc_arnolda(); Taki kod z czasem traci na czytelności, ale przede wszystkim ułatwia powstawanie błędów wynikających z powszechnego używania copy-paste. Chcemy, aby K lub k powodowały koniec świata, zaś U lub u pozwalały uratować świat. Jako scenariusz aplikacji nie jest to może zbyt ambitnyc przykład, ale na scenariusz filmu znakomicie się nadaje, oczywiście pod warunkiem, że zagra w nim Bruce Willis. if(znak=='k' znak=='k') koniec_swiata(); if(znak=='k' znak=='k') uratuj_swiat(); nudne_dialogi(); Gdyby Bruce zagrał według powyższego scenariusza, świat mógłby długo czekać na ratunek, a bardziej prawdopodobne jest, że wcześniej nastąpiłby jego koniec. Dlaczego? Wystąpiła literówka w scenariuszu, który w założeniu miał wyglądać następująco: if(znak=='k' znak=='k') koniec_swiata(); if(znak=='u' znak=='u') uratuj_swiat(); nudne_dialogi(); Moglibyśmy pominąć, ale wtedy kod wykonywałby się dłużej oraz stałby się jeszcze mniej czytelny. Literówki mogłyby być jeszcze bardziej zaskakująco nieprzewidywalne w skutkach. if(znak=='k' znak=='k') koniec_swiata(); if(znak=='u' znak=='u') uratuj_swiat(); if(znak!='k' && znak!='k' && znak!='u' && znak!='u') nudne_dialogi(); Autorom scenariuszy nic już nie pomoże, ale programistom przyda się niezastąpiona w takich sytuacjach pomoc, jaką daje język C w postaci instrukcji switch z dodatkami. Krzysztof Urbański 2011 7

Zadanie switch (znak) case 'K': case 'k': koniec_swiata(); break; case 'U': case 'u': uratuj_swiat(); break; default: nudne_dialogi(); Poeksperymentuj z kodem: spróbuj wstawić K i/lub k zamiast U ; spróbuj wyrzucić jedną lub obie instrukcje break. 1. Co będzie, kiedy spróbujesz na samym początku instrukcji switch zdefiniować zmienną lokalną? A jak zachowa się kod, gdy taka zmienna zostanie zadeklarowana miedzy case a break? 2. Czy instrukcje pomiędzy break a case (np. za pierwszym break, ale przed drugim case) kiedykolwiek się wykonają? 3. Czy sekcja default może być umieszczona w innym miejscu (np. przed case K )? Jak to wpłynie na działanie kodu? W języku C switch..case ma ogromne możliwości, ale jest bardzo wrażliwy na zgubienie słowa break. Tak się pechowo składa, ze pominięcie break nie jest błędem składniowym i kompilator nie zgłosi nam tego problemu. Pomijanie break bardzo rzadko się wykorzystuje w praktyce i zwykle jest to błąd a nie celowe działanie programisty. Nowsze języki (np. C#) traktują już takie przypadki jako błąd. Krzysztof Urbański 2011 8