PODSTAWY PROGRAMOWANIA 3-4 WYKŁAD 22-10-2015 ECLIPSE wnioski z dwóch pierwszych laboratoriów Dodanie pliku i konfiguracji startowej (każdy uruchamiany program powinien mieć własna konfigurację startową) Po stworzeniu projektu C++ type Executable- toolchain cygwin lub mingw (pamiętając o zmiennej PATH zawierającej ścieżkę do GCC) dodajemy nowy plik do projektu wybierając opcję File New Other C/C++ Source File. Zmieniamy aktywą konfigurację projektu z debug na release
Kompilujemy i konsolidujemy plik exe (pojawia się plik release/nazwa_projekte.exe) Uruchamiamy PIERWSZY raz projekt poprzez ctrl+f11 z poziomu edytora lub prawy przycisk myszy na projekcie Run As Local C/C++ Application lub wybierając Launch configurations New launch configuration Po pierwszym uruchomieniu konfiguracja uruchumieniowa zostaje zapisana, każde następne wywołanie projektu będzie możliwe również poprzez przycisk (przy aktywnej konfiguracji uruchumieniowej) Lub: Troubleshouting: Nie pojawia się typ projektu MiNGW Może nie być ustawiona ścieżka dostępu do gcc, należy ją dodać z poziomu komputera lub w eclipsie ctl+shift+l ctl+shift+l C/C++ Build Environment
Program nie kompiluje się pisząc no access to... exe Być może jest otwartych zbyt dużo kopi programu, należy pozamykać uruchomione instancje z widoku konsoli Wybrana jest konfiguracja debug zamiast run i program staje po pierwszej instrukcji w funkcji main. Należy wyłączyć opcję stop on startup
Zamiast wyników programu wyświetlana jest konsola błędów CDT Należy wyłączyć dla konsoli CDT automatyczne uzyskiwanie fokusu w przypadku wystąpienia błędu: Tekst zachęty do wprowadzania danych pojawia się dopiero po zakończeniu wprowadzania danych Należy zamiast wprowadzania w konwencji strukturalnego C (printf, scanf) wyświetlać i wprowadzać dane w konwencji obiektowego C++ (cout<<, cin>> ). Nie da się skompilować drugiego programu wewnątrz tego samego projektu Tylko jeden plik źródłowy w projekcie może mieć funkcję main. Jeżeli chcemy uruchomić inny program, to powinniśmy utworzyć inny projekt. Wyjściem prowizorycznym może być zaremowanie (dodanie komentarza znakami // lub /* */ funkcji main w pierwszym pliku). Struktura programu - podstawy W programie w języku C / C++ można wyróżnić w miarę stałe bloki: W przypadku prostych programów nie wykorzystujących funkcji lub klas:
#include <iostream> // Deklaracje dołączanych bibliotek / plików nagłowkowych, dyrektywy kompilatora, przestrzenie nazw using namespace std; int main() { // funkcja main - główna funkcja programu int ile_razy=1; // Deklaracje zmiennych for(int i=0;i<0;i++){ // Właściwe instrukcje cout << "!!!Hello World!!!" << endl; } } return 0; // zakończenie funkcji main W przypadku bardziej złożonych programów, oprócz funkcji main występują jeszcze definicje innych funkcji i/lub klas, plik cpp jest jeszcze często połączony z plikiem nagłówkowym *.h zawierającym ich prototypy. Słowa Kluczowe języka C Słowo asm auto break case char const continue default do double else enum extern float for goto if int long register return short OPIS Kod w asemblerze Modyfikator określający, że zmienne są pamiętane w domyślnym miejscu pamięci Polecenie kończące bezwarunkowo for, while, switch, i do...while W połączeniu ze switch - wybór wielokrotny Najprostszy typ danych, 1 bajt Modyfikator powodujący, że zmienna musi mieć w trakcie wykonywania programu tą samą wartość Polecenie powodujące przejście do następnej iteracji for, while, i do...while Domyślna wartość w instrukcji switch Instrukcja pętli Typ danych - podwójna precyzja, zmiennopozycyjne. Instrukcje do wykonania jeśli warunek po If...jest niespełniony Typ danych pozwalający aby zmienna przyjmowała tylko określone wartości Modyfikator określający, że zmienna jest zdefiniowana na zewnątrz programu/ funkcji Typ danych pojedyncza precyzja, zmiennopozycyjne. Instrukcja pętli Instrukcja skoku Instrukcja wyboru Typ danych przechowujący liczby całkowite Typ danych przechowujący liczby całkowite długie Modyfikator określający, że zmienne są pamiętane w rejestrze ( o ile to możliwe) Powrót z aktualnie wykonywanej funkcji Typ danych przechowujący liczby całkowite krótkie
signed sizeof static struct switch typedef union unsigned void volatile while Modyfikator określające, że zmienne danego typu mogą być ujemne Operator określający rozmiar zmiennej Modyfikator określający, że wartość zmiennej nie zmienia się pomiędzy kolejnymi wywołaniami funkcji Deklaracja struktury Wybór wielokrotny Definicja nowego typu Deklaracja unii Modyfikator określające, że zmienne danego typu nie mogą być ujemne "Pusty" typ danych. Najczęściej służy do określenia, że funkcja nie ma zwracać żadnych wartości. Modyfikator określający, że zmienna może być modyfikowana Instrukcja pętli wykonywana dopóki warunek pętli jest prawdziwy. Słowa kluczowe C++ catch inline template class new this delete operator throw except private try finally Protected virtual friend Public Priorytety operatorów: Operatory Wiązanie 1. () [] -> ::. ++ i -- (przyrostkowe) od lewej do prawej 2.! ~ + - ++ -- & * (typ) sizeof new delete od prawej do lewej 3..* ->* (dostęp do składowych obiektów) od lewej do prawej 4. * / % od lewej do prawej 5. + - (dwuargumentowe) od lewej do prawej 6. << >> od lewej do prawej 7. < <= > >= od lewej do prawej 8. ==!= od lewej do prawej 9. & od lewej do prawej 10. ^ od lewej do prawej 11. od lewej do prawej 12. && od lewej do prawej
13. od lewej do prawej 14.?: od prawej do lewej 15. = *= /= %= += -= &= ^= = <<= >>= od prawej do lewej 16., od lewej do prawej Instrukcje sterujące: Funkcja: printf() biblioteka: <stdio.h> wysyła sformatowane dane do standardowego strumienia wyjściowego (stdout) int printf ( tekst_sterujący, argument_1, argument_2,... ) ; tekst sterujący jest to stała łańcuchowa (w podwójnych cudzysłowach) zawierająca: zwykłe znaki (które są po prostu kopiowane na ekran) kody formatujące kolejnych argumentów: %c pojedynczy znak %s łańcuch znaków %d liczba dziesiętna ze znakiem %f liczba zmiennoprzecinkowa (notacja dziesiętna) %e liczba zmiennoprzecinkowa (notacja wykładnicza) %g liczba zmiennoprzecinkowa (krótszy z formatów %f %e) %u liczba dziesiętna bez znaku %x liczba w kodzie szesnastkowym (bez znaku) %o liczba w kodzie ósemkowym (bez znaku) l przedrostek (long) stosowany przed: d u x o \n nowa linia Instrukcja warunkowa: if ( wyrażenie ) instrukcja_1 ; else instrukcja_2 ;
Przykład Napisz program, który rozwiąze układ równań ax+by=c dx+ey=e badając możliwe sytuacje (jedno rozwiązanie, wiele rozwiązań, brak rozwiązań) Instrukcja while Składnia instrukcji while jest następująca: while ( warunek ) instrukcja; warunek jest wyrażeniem języka C++, zaś instrukcja jest dowolną instrukcją lub blokiem instrukcji C++. Gdy wartością wyrażenia warunek jest true (prawda), wykonywana jest instrukcja, po czym następuje powrót do początku pętli i ponowne sprawdzenie warunku. Czynność ta powtarza się, dopóki warunek zwraca wartość true. Gdy wyrażenie warunek ma wartość false, działanie pętli zostaje zakończone Może się zdarzyć, że przed wykonaniem całego zestawu instrukcji w pętli będziesz chcieć powrócić do jej początku. Służy do tego instrukcja continue (kontynuuj). Może zdarzyć się także, że będziesz chcieć wyjść z pętli jeszcze przed spełnieniem warunku końca. Instrukcja break (przerwij) powoduje natychmiastowe wyjście z pętli i przejście wykonywania do następnych instrukcji programu. Przykład } // zliczanie do 10 int x = 0; while (x < 10) { printf("x: %d", x); x++; Przykład: Napisz program losujący liczbę całkowitą tak długo, aż wylosowana zostanie liczba podzielna przez 666. Instrukcja do...while Składnia instrukcji do...while jest następująca: do instrukcja while (warunek); Wykonywana jest instrukcja, po czym sprawdzany jest warunek. Jeśli warunek jest spełniony, pętla jest powtarzana; w przeciwnym razie jej działanie się kończy. Pod innymi względami instrukcje i warunki są identyczne, jak w pętli while.
Przykład // wypisujemy małe litery alfabetu char ch = 'a'; do { printf("%c",ch); ch++; } while ( ch <= 'z' ); Używaj pętli do...while, gdy chcesz mieć pewność że pętla zostanie wykonana co najmniej raz. Używaj pętli while, gdy chcesz pominąć pętlę (gdy warunek nie jest spełniony). Składnia pętli for Składnia instrukcji for jest następująca: for (inicjalizacja; test; akcja ) instrukcja; Instrukcja inicjalizacja jest używana w celu zainicjalizowania stanu licznika lub innego przygotowania do wykonania pętli. Instrukcja test jest dowolnym wyrażeniem języka C++, które jest obliczane przed każdym wykonaniem zawartości pętli. Jeśli wyrażenie test ma wartość true, wykonywane jest ciało pętli, po czym wykonywana jest instrukcja akcja z nagłówka pętli (zwykle po prostu następuje inkrementacja zmiennej licznikowej). Przykład 1 Przykład 2 // dziesięć razy wpisuje napis "Hello" for (int i = 0; i < 10; i++) printf("hello! "); for (int i = 0; i < 10; i++) { printf("hello!"); printf("wartoscia i jest: %d",i); } Przykład Napisz program obliczający n-tą liczbę Fibbonaciego Instrukcja switch Składnia instrukcji switch jest następująca: switch (wyrażenie) { case wartośćjeden: instrukcja; case wartośćdwa: instrukcja;... case wartośćn: instrukcja;
default: instrukcja; } Instrukcja switch umożliwia rozgałęzienie programu (w zależności od wartości wyrażenia). Na początku wykonywania instrukcji następuje obliczenie wartości wyrażenia, gdy odpowiada ona którejś z wartości przypadku case, wykonanie programu przechodzi do tego właśnie przypadku. Wykonywanie instrukcji jest kontynuowane aż do końca ciała instrukcji switch lub do czasu napotkania instrukcji break. Jeśli wartość wyrażenia nie odpowiada żadnej z wartości przypadków case i występuje przypadek default, wykonanie przechodzi do przypadku default. W przeciwnym razie wykonywanie instrukcji switch się kończy. Przykład: Napisz program podający słownie dzień tygodnia, dla dnia tygodnia podanego w postaci liczby. Tablice : int tablica [ 20 ]; // 10-cio elementowa tablica liczb całkowitych # define ile=15 float tekst [15 ]; // 255-cio elementowa tablica zmiennych zmiennopozycyjnych (liczby rzeczywiste typu float char macierz [ 3 ] [ 5 ]; // dwuwymiarowa tablica: znaków 3 wiersze po 2 kolumny, w języku C tablice są zawsze indeksowane od zera np. pierwszym elementem tablicy «macierz» jest: macierz[ 0 ][ 0 ] a ostatnim elementem jest: macierz[ wymiar_1 1 ][wymiar_2 1] tzn. macierz[ 4 ][ 1 ] w języku C nie jest sprawdzana zgodność indeksu z wymiarami tablicy!!! często jest to przyczyną trudnych do wykrycia błędów. np. odwołanie: macierz[ 1 ][ 2 ] zwróci w rzeczywistości wartość pierwszego elementu z trzeciego wiersza tzn. macierz[ 2 ][ 0 ] Definicję tablicy można połączyć z inicjacją jej zawartości: int tab[ 10 ]; // sama definicja bez inicjacji int tab_inicjowana[ 10 ] = { 20, -3, 12, 1, 0, 7, -5, 100, 2, 5 }; char tab_znakow[ 5 ] = { a, B, \n, 1, \0 }; float macierz_a[ 3 ][ 2 ] = { {1,1}, {3.5,7.0}, {-15,100} }; float macierz_b[ 3 ][ 2 ] = { 1, 1, 3.5, 7.0, -15, 100 };
Kolejne inicjatory zawsze wstawiane są do kolejnych komórek tablicy (w związku z tym można pominąć wewnętrzne nawiasy klamrowe). Jeżeli lista inicjatorów jest krótsza niż ilość elementów tablicy to pozostałe elementy są uzupełniane zerami lub wskaźnikami NULL np. definicja: a definicja: int tab[ 10 ] = { 20, -3, 12, 1 }; jest równoważna: int tab[ 10 ] = { 20, -3, 12, 1, 0, 0, 0, 0, 0, 0 }; float macierz[ 3 ][ 2 ] = { {1}, {3.5,7.0} }; jest równoważna: lub: float macierz[ 3 ][ 2 ] = { {1,0}, {3.5,7.0}, {0,0} }; float macierz[ 3 ][ 2 ] = { 1, 0, 3.5, 7.0, 0, 0 }; PRZYKŁAD : Wprowadź dane do tablicy 10 elementowej Policz ile w tablicy jest elementów większych od trzech Znajdź minimalną i maksymalną wartość w tablicy Posortuj liczby w tablicy metodą sortowania bąbelkowego