380 likes | 523 Vues
Informatyka II MPZI2 sem.letni. Wykład 1. Tablice. Tablice deklarujemy array [ lista typów indeksów ] of typ bazowy (składowych). np. var t1,t2:array [1..5, 1..6] of real;. Nadanie wartości początkowych zmiennym tablicowym. dla tablic konstrukcja typu:
E N D
Informatyka II MPZI2 sem.letni Wykład 1
Tablice Tablice deklarujemy array [ lista typów indeksów ]of typ bazowy (składowych) np. var t1,t2:array [1..5, 1..6] of real;
Nadanie wartości początkowych zmiennym tablicowym • dla tablic konstrukcja typu: ( (st11, st21,..., stn1 ), (st12, st22,..., stn2 ), . . . (st1m, st2m,..., stnm) ) const osoby: array[ 1..3] of string[20] = ( 'Nowak', 'Kowalski', 'Nycz' ); albo zmienna (zmiennym można w programie zmienić wartości a stałym NIE): var wyniki: array[ 1..3, 1..4] of real = ( ( 3, 4, 4.5, 5), ( 2, 3.5, 5.0, 4.5), (5.0, 4, 3.5, 2) );
Przykład: program p2; uses SysUtils; var wyniki: array[ 1..3, 1..4] of real = (( 3, 4, 4.5, 5), ( 2, 3.5, 5.0, 4.5), (5.0, 4, 3.5, 2)); begin writeln (wyniki[1,1]:10:2); //wypisze wartość 3.00 readln; end.
Przykłady operacji tablicowych type tab = array [1..2, 1..5] of real; var t1, t2 : tab; wie,kol: integer; begin write ('Podaj element 1,1:'); readln(t1[1,1]); //itp. // najczęściej operacje w pętli zagnieżdżanej jeśli tablica 2-wymiarowa for wie:=1 to 2 do for kol:= 1 to 5 do t1[wie, kol] :=1; //wyświetlenie na ekranie też w pętli zagnieżdżanej for wie:=1 to 2 do begin for kol:= 1 to 5 do write(t1[wie, kol]); writeln; end; readln; end.
Zadanie: w wektorze zsumować co drugi element (nieparzyste indeksy) const N=12; type zakres = 1..N; var k: zakres; suma: real; x: array [ 1 .. N ] of real= ( 3, 4, 4.5, 5, 2, 3.5, 5.0, 4.5, 5.0, 4, 3.5, 2); begin suma := 0; for k := 1 to N do if (k mod 2) = 1 then suma := suma + x [k]; writeln ( suma :10:3) ; readln end. albo można tak: for k := 1 to ( N+1 ) div 2 do suma := suma + x [ 2*k - 1 ]; zastanowić się!
Pamiętajmy: Nie ma gotowych operacji macierzowych (mnożenie, obliczanie wyznacznika, znajdowanie macierzy odwrotnej itp.), trzeba samemu stworzyć algorytm lub posiadać odpowiednie biblioteki z gotowymi podprogramami Przykładowo mnożenie tablic: program mn24; var t1:array[1..2, 1..4] of real = ((1,2,4,-1),(0, -1, 8, 1)); t2 :array[1..4,1..2] of real = ((1,1.1),(4,-2.0),(0, -1),(-3,-2.5)); wyn: array[1..2,1..2] of real; i:1..4; begin // obliczanie elementu 1,1 wyn[1,1]:=0; for i:=1 to 4 do wyn[1,1]:= wyn[1,1]+ t1[1,i]*t2[i,1]; writeln(wyn[1, 1]:10:2); readln; end.
Całość: program mn24; const N=2; M=4; var t1:array[1..N, 1..M] of real = ((1,2,4,-1),(0, -1, 8, 1)); t2 :array[1..M,1..N] of real= ((1,1.1),(4,-2.0),(0, -1),(-3,-2.5)); wyn: array[1..N,1..N] of real; wie,kol, i:1..4; begin //potrójna pętla! for wie:=1 to N do for kol:=1 to N do for i:=1 to M do wyn[wie,kol]:= wyn[wie,kol]+ t1[wie,i]*t2[i,kol]; //wyswietlenie wyniku for wie:=1 to N do begin for kol:= 1 to N do write(wyn[wie, kol]:10:2); //wypisanie wiersza writeln; //zmiana wiersza end; readln; end.
Można wyświetlać wyniki od razu po utworzeniu elementu ... begin //potrójna pętla! for wie:=1 to N do begin for kol:=1 to N do begin //utworzenie elementu for i:=1 to M do wyn[wie,kol]:= wyn[wie,kol]+ t1[wie,i]*t2[i,kol]; // i od razu wyświetlenie write(wyn[wie, kol]:10:2); end; writeln; end; readln; end.
Sortowanie Sortowanie bąbelkowe Algorytm polega porównywaniu kolejnych par elementów sąsiadujących i zamianie miejscami w przypadku niewłaściwej kolejności 1 2 3 4 ..... N N-1 porównań Wykonujemy N przebiegów
1 przebieg 12 5 11 4 7 2 zamiana 1 5 12 11 4 7 2 zamiana 2 5 11 12 4 7 2 zamiana 3 5 11 4 12 7 2 zamiana 4 5 11 4 7 12 2 zamiana 5 5 11 4 7 2 12efekt ostatniej zamiany – największy na końcu 2 przebieg 5 11 4 7 2 12 5 11 4 7 2 12 zmiana 6 5 4 11 7 2 12 zmiana 7 5 4 7 11 2 12 zmiana 8 5 4 7 2 11 12 5 4 7 2 11 12 3 przebieg 5 4 7 2 11 12 zamiana 9 4 5 7 2 11 12 4 5 7 2 11 12 zamiana 10 4 5 2 7 11 12 4 5 2 7 11 12 4 5 2 7 11 12 4 przebieg 4 5 2 7 11 12 4 5 2 7 11 12 zamiana 11 4 2 5 7 11 12 4 2 5 7 11 12 4 2 5 7 11 12 4 2 5 7 11 12 N=6 zauważamy nadmiarowe porównania
5 przebieg 4 2 5 7 11 12 zmiana 12 2 4 5 7 11 12 2 4 57 11 12 2 4 5 711 12 2 4 5 7 11 12 2 4 5 7 11 12 6 przebieg 2 4 5 7 11 12 2 4 5 7 11 12 2 4 5 7 11 12 2 4 5 7 11 12 2 4 5 7 11 12 30 operacji= (N-1)*N=6*5
Sortowanie bąbelkowe skrócone Algorytm polega na porównywaniu kolejnych par elementów sąsiadujących, z tym, że w każdym kolejnym przebiegu liczba analizowanych par jest zmniejszana o 1 Przebiegów wykonujemy N-1
1 przebieg 12 5 11 4 7 2 zamiana 1 5 12 11 4 7 2 zamiana 2 5 11 12 4 7 2 zamiana 3 5 11 4 12 7 2 zamiana 4 5 11 4 7 12 2 zamiana 5 5 11 4 7 2 12 efekt 2 przebieg 5 11 4 7 2 12 5 11 4 7 2 12 zamiana 6 5 4 11 7 2 12 zamiana 7 5 4 7 11 2 12 zamiana 8 5 4 7 2 11 12 efekt 3 przebieg 5 4 7 2 11 12 zamiana 9 4 5 7 2 11 12 4 5 7 2 11 12 zamiana 10 4 5 2 7 11 12 efekt 4 przebieg 4 5 2 7 11 12 4 5 2 7 11 12 zamiana 11 4 2 5 7 11 12 efekt 5 przebieg 4 2 5 7 11 12 zamiana 12 2 4 5 7 11 12 efekt 5 4 15 operacji 3 2 1
Można też tak (rodzaj sortowania bąbelkowego): • Algorytm polega na porównywaniu: • pierwszego elementu z kolejnymi i dokonanie zamiany jeśli trzeba, • drugiego elementu z kolejnymi itd., • aż do porównania dwóch ostatnich elementów. N (N-1) operacji 2
1 przebieg 125 11 4 7 2 zamiana 1 5 12 11 4 7 2 5 12 11 4 7 2 zamiana 2 4 12 11 5 7 2 4 12 11 5 7 2 zamiana 3 2 12 11 5 7 4 najmniejszy na początku 2 przebieg 2 1211 5 7 4 zamiana 4 .. więc zaczynamy od 2-go 2 11 12 5 7 4 zamiana 5 2 5 12 11 7 4 2 5 12 11 7 4 zamiana 6 2 4 12 11 7 5 3 przebieg 2 4 1211 7 5 zamiana 7 2 4 11 12 7 5 zamiana 8 2 4 7 12 11 5 zamiana 9 2 4 5 12 11 7 4 przebieg 2 4 5 1211 7 zamiana 10 2 4 5 11 12 7 zamiana 11 2 4 5 7 12 11 5 przebieg 2 4 5 7 1211 zamiana 12 2 4 5 7 11 12 15 operacji
const N=10; var tab:array [1..N] of integer; var k,m:1..N; pom,lop:integer; begin //wypełnienie losowe tablicy 1-wymiarowej Randomize; for k:=1 to N do tab[k]:=random(100); //sortowanie for k:=1 to N do for m:=1 to N-1 do begin lop:=lop+1; if tab[m]>tab[m+1] then begin pom:=tab[m]; tab[m]:=tab[m+1]; tab[m+1]:=pom; end; end; //wypisanie wyniku for k:= 1 to N do write(tab[k]:6); writeln;writeln(lop); readln; end. Bąbelkowe lop=90
const N=10; var tab:array [1..N] of integer; var k,m:1..N; pom,lop:integer; begin //wypełnienie losowe tablicy 1-wymiarowej Randomize; for k:=1 to N do tab[k]:=random(100); //sortowanie for k:=1 to N-1 do for m:=1 to N-k do begin lop:=lop+1; if tab[m]>tab[m+1] then begin pom:=tab[m]; tab[m]:=tab[m+1]; tab[m+1]:=pom; end; end; //wypisanie wyniku for k:= 1 to N do write(tab[k]:6); writeln;writeln(lop); readln; end. Bąbelkowe skrócone różnice! lop=45 szybsze
Typ rekordowy (record) Pojęcie i opis • pojęcie: - skończony zbiór elementów dowolnego typu składowego tak zwane pola - ułożone jednowymiarowo - o położeniu (selekcji) określanym przez nazwęskładowej (pola) - tzw. dostęp kwalifikowany wektor nazwanych pól dowolnego typu (różnego rozmiaru) typ dowolny: prosty lub strukturalny (bez plików) pole może być tablicą, napisem, innym rekordem • opis: record lista_nazw_pól: typ; . . . end deklaracja_pól_tego_samego_typu;
fizycznie: w PaO kolejne wartości pól określonego typu • przykłady: type data = record rok: 1900 .. 2100; mies: 1..12; dzien: 1..31 end; var student: record nazw: string[ 20 ]; imie: array[1..2] of string[ 15 ]; data_ur: data; stypend: real end;
Porównanie: • jednakowe składowe • selektor typu indeks • dostęp bezpośredni • statyczny rozmiar • różne składowe • selektorem jest nazwa pola • dostęp bezpośredni • statyczny rozmiar Uwaga: Rekord to jeden zestaw danych (np. dane jednego studenta), jeśli potrzebujemy analizy większej liczby to tworzymy tablicę rekordów
Zmienne rekordowe całościowe desygnator pola (składowa) • zmienne całościowe - tylko przypisanie - typów tożsamych! brak: + - * / porównania wejścia/wyjścia – można tylko składową (pole) np: var r1, r2: record ..definicja... end ; begin r1 := r2;
desygnator pola (składowa) - dostęp do pola Z . p Ztypu składowego nazwa zmiennej rekordowej nazwa pola • użycie - w wyrażeniach lub instrukcjach, jak zmienne typu składowego Przykład: student.nazw (nazwisko) student.stypend student.imie (tablica) student.data_ur.dzien student.data_ur.rok student.imie[1] (1-sze imię) student.imie[2][1] (1-sza litera 2-go imienia) type data= record dzien, miesiac, rok:integer; var student: record nazw: string[ 20 ]; imie: array[1..2] of string[ 15 ]; data_ur: data;//zdef. typrekordowy stypend: real end;
TABLICE REKORDÓW type data = record rok: 1900 .. 2100; mies: 1..12; dzien: 1..31 end; type osoba = record nazw: string[ 20 ]; imie: array[1..2] of string[ 15 ]; data_ur: data; end; var grupa: array[1..100] of osoba; //tablica rekordów !!!! os1:osoba; // zmienna rekordowa pomocnicza grupa – zmienna typu tablicowego grupa[k] – typu rekordowego grupa[1].nazw - typu string grupa[2].imie – typu tablicowego grupa[k].imie[1] - typu string grupa[k].data_ur - typu rekordowego grupa[k].data_ur.rok – typu integer grupa[2].imie[2][5] – typu char Użycie zależne od typu: writeln( grupa[3].nazw); os1.nazw := 'Nowak'; grupa[50]:=os1; os1:= grupa[51]; writeln (grupa[k]. imie[1]); writeln(length(grupa[30].nazw)) if grupa[k].data_ur.rok>1970 then…
różne składowe • selektorem jest nazwapola • jednakowe składowe • selektor typu indeks
Deklaracje (opis) zmiennych Zmienna tablicowa var t1:array [1..5, 1..6] of real; Zmienna rekordowa varstudent: record nazw: string[ 20 ]; imie: array[1..2] of string[ 15 ]; data_ur: data; stypend: real end;
Użycie w części wykonawczej programu tablica t1[5, 6] indeks (-y) rekord student.nazwisko student.imie[1] student.data_ur.rok w zależności od typu nazwa pola
TABLICE REKORDÓW typedata = record rok: 1900 .. 2100; mies: 1..12; dzien: 1..31 end; osoba = record nazw: string[ 20 ]; imie: array[1..2] of string[ 15 ]; data_ur: data; end; var grupa: array[1..100] of osoba; //tablica rekordów !!!!
Instrukcja wiążąca - with • dotyczy tylko zmiennych rekordowych (obiektowych) • upraszcza zapis !! Opis: withlista_zmiennych_rekordowych doinstrukcja; najczęściej begin . . . end można tu używać nazw pól bez specyfikowania zmiennej rekordowej przykład: with student do begin nazw :=’Kowalski’; imie[1] := ’Jan’; data_ur.rok := 1988; stypendium := 420,00; end; student.nazw :=’Kowalski’; student.imie[1] := ’Jan’; student.data_ur.rok := 1988; student.stypendium := 420.00;
Podprogramy Pojęcie i istota stosowania • dzielenie programu na części (logicznie spójne) • nazwane • niezależne od pozostałych części • z określonym sposobem wymiany informacji z innymi częściami (przekazywanie danych) • korzyści: • krótszy zapis źródłowy • efektywniejsze wykorzystanie PaO (mniej) • czytelność • łatwiejsze uruchamianie i testowanie • tworzenie bibliotek i korzystanie z nich
Definiowanie funkcje procedury • różnice - sposób definiowania - funkcja przyjmuje wartość a procedura nie - sposób wywołania nagłówek: procedure nazwa_proc (deklaracje_parametrów_formalnych ); function nazwa_fun ( deklaracje_param._formal. ): typ_wartości; lista_nazw_parametrów_formalnych: nazwa_typu var lista_nazw_parametrów_ formalnych : nazwa_typu mechanizm przekazywania danych elementy listy oddzielane ;
Czyli... - musimy zdefiniować sposób otrzymywania przez podprogram danych i ewentualny zwrot wyników oraz operacje wykonawcze podprogramu podprogram dane wyniki
dane wynik Definicje funkcji i procedury functionnazwa (parametry formalne): typ funkcji ; definicje, deklaracje lokalne begin .... nazwa:=wyrażenie; //albo result:=wyrażenie end ; dane i ewentualne wyniki procedurenazwa (parametry formalne) ; definicje, deklaracje begin .... instrukcje .... end ;
Wywołanie (wykonanie) procedura – osobna instrukcja wykonania: nazwa_procedury( lista_parametrów_aktualnych ); funkcja – najczęściej w wyrażeniu (jako składniku instrukcji): nazwa_funkcji( lista_parametrów_aktualnych ); ale może być też osobną instrukcją, gdy nie zależy nam na zwracanej wartości • Uwagi: • parametryaktualne zgodne z parametramiformalnymi: • -co do liczby • - co do typu • - co do kolejności parametry oddzielane przecinkami ,
Przykład funkcji obliczającej średnią arytmetyczną Definicja lokalna funkcji program p1; parametry formalne typ wyniku functionsrednia (x1, x2 : real): real ; begin result:= (x1 + x2)/2; //albo srednia:=(x1 + x2)/2; end ; {koniec definicji funkcji} var a, b, c:real; begin a:=2; writeln(srednia (6.7, 2*a)) ; readln; end. parametry aktualne
Przekazywanie danych z/do podprogramu • przez wartość - parametr formalny bez var - jest zmienną lokalną - wartość początkowa w momencie wywołania - argument aktualny - wyrażenie typu zgodnego - przekazywanie danych tylko na wejściu do podprogramu • przez zmienną (adres)- określonego typu (referencyjnie) - parametr formalny z var - faktycznie nie dane lecz adres argumentu aktualnego - argument aktualny - zmienna tego samego typu - przekazywanie danych na wyjściu (czyli w większości przypadków zwrot wyniku lub wyników) - ale może być także na wejściu
Przykład • program x; • procedurealfa(x1,x2:real; var wynik:real); • begin • wynik:=x1-x2; • end; • var w:real; //dodatkowa zmienna • begin • alfa(5,2,w); • writeln(w) ; • alfa(4,2,w); • writeln(w) ; • readln; • end; definicja procedury
Przykład procedury obliczającej średnią arytmetyczną parametry formalne var !! Program proc; proceduresrednia (liczba1, liczba2 : real ; var wynik : real) ; begin wynik := (liczba1 + liczba2)/2; end ; {koniec definicji procedury} var a, b, c:real; begin a:=2; b:=3; srednia (6.7, 2*a, c) ; {trzeci parametr aktualny musi być zmienną} writeln(c)) ; {c jest równe (6.7+2*2)/2=5.35} srednia (a, b, c) ; writeln(c) ; {c jest równe (2+3)/2=2.5} srednia (a, c, c) ; writeln(c) ; {c jest równe (2+2.5)/2=2.25} srednia (c, b, a) ; writeln(a) ; {a jest równe (2.25+3)/2=2.67.. end. parametry aktualne