O podstawowych operacjach na tablicach. Mateusz Ziółkowski, MBiU II

Podobne dokumenty
r. Tablice podstawowe operacje na tablicach

ZASADY PROGRAMOWANIA KOMPUTERÓW

Zadeklarowanie tablicy przypomina analogiczną operację dla zwykłych (skalarnych) zmiennych. Może zatem wyglądać na przykład tak:

1 Podstawy c++ w pigułce.

Tablice. Monika Wrzosek (IM UG) Podstawy Programowania 96 / 119

typ y y p y z łoż o on o e n - tab a lice c e w iel e owym m ar a o r we, e stru r kt k ury

Wskaźniki i dynamiczna alokacja pamięci. Spotkanie 4. Wskaźniki. Dynamiczna alokacja pamięci. Przykłady

Wstęp do programowania. Wykład 1

MACIERZE. Sobiesiak Łukasz Wilczyńska Małgorzata

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

Część 4 życie programu

Wstęp do programowania

tablica: dane_liczbowe

Niezwykłe tablice Poznane typy danych pozwalają przechowywać pojedyncze liczby. Dzięki tablicom zgromadzimy wiele wartości w jednym miejscu.

Wskaźnik może wskazywać na jakąś zmienną, strukturę, tablicę a nawet funkcję. Oto podstawowe operatory niezbędne do operowania wskaźnikami:

> C++ dynamiczna alokacja/rezerwacja/przydział pamięci. Dane: Iwona Polak. Uniwersytet Śląski Instytut Informatyki

INFORMATYKA Z MERMIDONEM. Programowanie. Moduł 5 / Notatki

Programowanie obiektowe W3

Inicjacja tablicy jednowymiarowej

1 Podstawy c++ w pigułce.

Zmienne i struktury dynamiczne

Materiał Typy zmiennych Instrukcje warunkowe Pętle Tablice statyczne Wskaźniki Tablice dynamiczne Referencje Funkcje

TABLICA (ang. array) pojedyncza zmienna z wieloma komórkami, w których można zapamiętać wiele wartości tego samego typu danych.

DYNAMICZNE PRZYDZIELANIE PAMIECI

Programowanie w C++ Wykład 5. Katarzyna Grzelak. 26 marca kwietnia K.Grzelak (Wykład 1) Programowanie w C++ 1 / 40

Podstawy Programowania C++

Zajęcia nr 2 Programowanie strukturalne. dr inż. Łukasz Graczykowski mgr inż. Leszek Kosarzewski Wydział Fizyki Politechniki Warszawskiej

I - Microsoft Visual Studio C++

Programowanie - wykład 4

Jak napisać program obliczający pola powierzchni różnych figur płaskich?

Wstęp do programowania

Programowanie w C++ Wykład 5. Katarzyna Grzelak. 16 kwietnia K.Grzelak (Wykład 1) Programowanie w C++ 1 / 27

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

Podstawy informatyki. Elektrotechnika I rok. Język C++ Operacje na danych - wskaźniki Instrukcja do ćwiczenia

Wymiar musi być wyrażeniem stałym typu całkowitego, tzn. takim, które może obliczyć kompilator. Przykłady:

Deklaracja struktury w C++

Programowanie komputerowe. Zajęcia 1

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.

Podstawy Programowania

Podstawy informatyki. Informatyka stosowana - studia niestacjonarne. Grzegorz Smyk. Wydział Inżynierii Metali i Informatyki Przemysłowej

Temat: Dynamiczne przydzielanie i zwalnianie pamięci. Struktura listy operacje wstawiania, wyszukiwania oraz usuwania danych.

1 Wskaźniki. 1.1 Główne zastosowania wskaźników

2. Tablice. Tablice jednowymiarowe - wektory. Algorytmy i Struktury Danych

Tablice mgr Tomasz Xięski, Instytut Informatyki, Uniwersytet Śląski Katowice, 2011

> C++ wskaźniki. Dane: Iwona Polak. Uniwersytet Śląski Instytut Informatyki 26 kwietnia 2017

Pytania sprawdzające wiedzę z programowania C++

Podstawy programowania. Wykład: 6. Tablice statyczne. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD

Wskaźniki. nie są konieczne, ale dają językowi siłę i elastyczność są języki w których nie używa się wskaźników typ wskaźnikowy typ pochodny:

Lab 9 Podstawy Programowania

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

TABLICE W JĘZYKU C/C++ typ_elementu nazwa_tablicy [wymiar_1][wymiar_2]... [wymiar_n] ;

Podstawy języka C++ Maciej Trzebiński. Praktyki studenckie na LHC IFJ PAN. Instytut Fizyki Jądrowej Polskiej Akademii Nauk. M. Trzebiński C++ 1/16

Programowanie w języku Python. Grażyna Koba

8. Wektory. Przykłady Napisz program, który pobierze od użytkownika 10 liczb, a następnie wypisze je w kolejności odwrotnej niż podana.

Dla każdej operacji łącznie tworzenia danych i zapisu ich do pliku przeprowadzić pomiar czasu wykonania polecenia. Wyniki przedstawić w tabelce.

Programowanie komputerowe. Zajęcia 5

Programowanie komputerowe. Zajęcia 4

Wstęp do programowania

Transponowanie macierzy Mnożenie macierzy Potęgowanie macierzy Wyznacznik macierzy

Zajęcia nr 5 Algorytmy i wskaźniki. dr inż. Łukasz Graczykowski mgr inż. Leszek Kosarzewski Wydział Fizyki Politechniki Warszawskiej

lekcja 8a Gry komputerowe MasterMind

Algorytmika i programowanie. Wykład 2 inż. Barbara Fryc Wyższa Szkoła Informatyki i Zarządzania w Rzeszowie

STL: Lekcja 1&2. Filozofia STL

Tablice. Jones Stygar na tropie zmiennych

Programowanie strukturalne i obiektowe. Funkcje

C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów

Programowanie w C++ Wykład 2. Katarzyna Grzelak. 4 marca K.Grzelak (Wykład 1) Programowanie w C++ 1 / 44

1 P roste e t ypy p d a d n a ych c - c ąg ą g d a d l a szy 2 T y T py p z ł z o ł żo ż ne e d a d n a ych c : T BLICE

Stałe, tablice dynamiczne i wielowymiarowe

Programowanie komputerowe. Zajęcia 3

C++ wprowadzanie zmiennych

Liczby całkowite i rzeczywiste

ZASADY PROGRAMOWANIA KOMPUTERÓW ZAP zima 2015

Programowanie w języku C++

1. Pierwszy program. Kompilator ignoruje komentarze; zadaniem komentarza jest bowiem wyjaśnienie programu człowiekowi.

Informacje wstępne #include <nazwa> - derektywa procesora umożliwiająca włączenie do programu pliku o podanej nazwie. Typy danych: char, signed char

Wykład II. Programowanie II - semestr II Kierunek Informatyka. dr inż. Janusz Słupik. Wydział Matematyki Stosowanej Politechniki Śląskiej

do instrukcja while (wyrażenie);

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

Programowanie proceduralne w języku C++ Pętle, tablice

JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Wykład 5

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

Wieczorowe Studia Licencjackie Wrocław, Wykład nr 6 (w oparciu o notatki K. Lorysia, z modyfikacjami) Sito Eratostenesa

Programowanie i struktury danych

Laboratorium nr 9. Temat: Wskaźniki, referencje, dynamiczny przydział pamięci, tablice dynamiczne. Zakres laboratorium:

Pętle i tablice. Spotkanie 3. Pętle: for, while, do while. Tablice. Przykłady

Podstawy algorytmiki i programowania - wykład 2 Tablice dwuwymiarowe cd Funkcje rekurencyjne

Programowanie w C++ Wykład 2. Katarzyna Grzelak. 5 marca K.Grzelak (Wykład 1) Programowanie w C++ 1 / 41

Dariusz Brzeziński. Politechnika Poznańska, Instytut Informatyki

Utworzenie pliku. Dowiesz się:

Język C zajęcia nr 11. Funkcje

Algorytmy i złożoności. Wykład 3. Listy jednokierunkowe

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

Materiał. Typy zmiennych Instrukcje warunkowe Pętle Tablice statyczne Funkcje Wskaźniki Referencje Tablice dynamiczne Typ string Przeładowania funkcji

Wykład 4 Delegat (delegate), właściwości indeksowane, zdarzenie (event) Zofia Kruczkiewicz

Opis zagadnieo 1-3. Iteracja, rekurencja i ich realizacja

7. Pętle for. Przykłady

(3 kwiecień 2014) Marika Pankowska Kamila Pietrzak

Wskaźniki w C. Anna Gogolińska

Transkrypt:

Wykład Ⅴ O podstawowych operacjach na tablicach Mateusz Ziółkowski, MBiU II

Czym są tablice? Tablica (ang. array) to zespół równorzędnych zmiennych, posiadających wspólną nazwę. Jego poszczególne elementy są rozróżnianie poprzez przypisane im liczby - tak zwane indeksy. Każdy element tablicy jest więc zmienną należącą do tego samego typu. Nie ma tutaj żadnych ograniczeń: może to być liczba (w matematyce takie tablice nazywamy wektorami), łańcuch znaków (np. lista uczniów lub pracowników), pojedynczy znak, wartość logiczna czy inny typ danych z wyjątkiem typu referencyjnego lub void. W szczególności, elementem tablicy może być także inna tablica!

Uwaga: W tablicy o n elementach NIE istnieje element n-ty!!! Spowodowane jest to tym, że indeksowanie elementów w tablicy zaczyna się od zera i ostatni element wtedy jest n-1 elementem.

Spis zagadnień Deklaracja tablic Inicjalizacja tablic Tablice statyczne i dynamiczne Tablice dynamiczne o dynamicznym rozmiarze Wprowadzanie i wyprowadzanie danych Wypełnianie tablic

Deklaracja tablic Przed pierwszym użyciem każda tablica musi być zadeklarowana tak jak wszystkie zmienne używane w programie tablica jest zmienną złożoną. Deklaracja w języku C++ wygląda następująco: typ_danych nazwa_tablicy[liczba_elementów], gdzie: Typ danych określa rodzaj informacji przechowywanych w tablicy np. int, nazwa aby odnieść się później do tablicy w programie oraz w nawiasach kwadratowych liczba elementów należąca do liczb naturalnych.

Deklaracja tablic Tablice mogą być wielowymiarowe w zależności od tego jak je zadeklarujemy na przykład: int a[2] tablica jednowymiarowa o dwóch elementach. Jej odpowiednikiem w matematyce jest ciąg. int b[5][3] tablica dwuwymiarowa o pięciu elementach w 3. Odpowiednikiem dwuwymiarowych tablic w matematyce jest macierz.

Inicjalizacja tablic Tablicę możemy zainicjalizować w bardzo prosty sposób, unikając przy tym wielokrotnych przypisań (po jednym dla każdego elementu): int a[2][3] = { {1, 2, 3}, {4, 5, 6} }; lub int b[2][3] = { 1, 2, 3, 4, 5, 6 }; Możemy użyć także takiego zapisu (pominąć jej rozmiar): int fib[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 34}; Kompilator wtedy domyśli się rozmiaru tablicy.

Tablice statyczne i dynamiczne Statyczną tabelę nazywamy wtedy kiedy programista definiuje jej rozmiar w programie. Zdarza się, iż w trakcie pisania programu nie wiemy, ile dokładnie elementów będzie zawierała używana w tym programie tablica. W takim przypadku problem tworzenia dynamicznej tablicy możemy rozwiązać na dwa sposoby:

1. Sposób Utworzyć tablicę o maksymalnej, przewidywanej liczbie elementów. Rozwiązanie nieefektywne ze względu na wykorzystanie pamięci. Jeśli w typowych przypadkach wykorzystujemy małą liczbę elementów tablicy, to i tak musimy rezerwować założoną ilość komórek dla przypadku pesymistycznego, który pojawia się bardzo rzadko, ale jest prawdopodobny.

2. Sposób Utworzyć tablicę dynamicznie o tylu komórkach, ile w danej chwili jest nam potrzebne. Po wykorzystaniu, tablicę dynamiczną usuwamy, zwalniając w ten sposób zajmowany przez nią obszar pamięci, który teraz można wykorzystać do innych celów np. dla nowej tablicy dynamicznej.

W celu utworzenia w języku C++ tablicy dynamicznej, tworzymy zmienną wskaźnikową na typ danych, które mają być przechowywane w tablicy: typ_elementów * nazwa_tablicy_dynamicznej; Zmienna wskaźnikowa (ang. pointer variable) nie przechowuje danych tylko adres obszaru pamięci komputera, w którym te dane się znajdują. Deklarację zmiennej wskaźnikowej zawsze poprzedzamy znakiem gwiazdki.

W poniższym przykładzie tworzymy trzy wskaźniki a, b i c do danych typu double (czyli do obszaru pamięci, w którym będą przechowywane liczby zmiennoprzecinkowe o podwójnej precyzji): double * a, * b, * c; Pamięć rezerwujemy operatorem new i adres zarezerwowanego obszaru umieszczamy w zmiennej wskaźnikowej: nazwa_tablicy_dynamicznej = new typ_elementów[liczba_elementów];

Poniższy przykład tworzy trzy tablice dynamiczne, w których będzie można przechowywać odpowiednio 10, 100 i 1000 elementów typu double: a = new double[10]; // elementy od a[0] do a[9] b = new double[100]; // elementy od b[0] do b[99] c = new double[1000]; // elementy od c[0] do c[999] Po tej operacji do elementów tablic a, b i c odwołujemy się w zwykły sposób za pomocą indeksów. Istnieje również alternatywna metoda, wykorzystująca fakt, iż zmienne a, b i c są wskaźnikami. W języku C++ dodanie do wskaźnika liczby całkowitej powoduje obliczenie adresu elementu o indeksie równym dodawanej liczbie.

Zatem wynik takiej operacji jest również wskaźnikiem: Tablica a[2] = 10.54; cout << a[2] << endl; Wskaźnik * (a + 2) = 10.54; cout<< * (a + 2) <<endl; W rzeczywistości zapis a[i] kompilator i tak przekształca sobie na zapis * (a + i). Forma tablicowa jest tylko uproszczeniem zapisu wskaźnikowego.

Tablice dynamiczne nie są automatycznie usuwane z pamięci, jeśli utworzono je w funkcji. Dlatego po zakończeniu korzystania z tablicy program powinien zwolnić zajmowaną przez tablicę pamięć. Dokonujemy tego poleceniem delete w sposób następujący: delete [] nazwa_tablicy_dynamicznej; W poniższym przykładzie zwalniamy pamięć zarezerwowaną wcześniej na elementy tablic b i c. delete [] b; // usuwamy obszar wskazywany przez b delete [] c; // usuwamy obszar wskazywany przez c

C++ pozwala również na tworzenie statycznych tablic o liczbie elementów podanej w zmiennej. Na przykład: int n; cin >> n; double a[n]; Jednakże nie jest to zbyt standardowe rozwiązanie i może nie być przenośne na inne kompilatory C++, dlatego odradza się używania go lepiej zastosować tablicę dynamiczną.

Tablice dynamiczne o dynamicznym rozmiarze Gdy operujemy na dynamicznych strukturach danych, to często okazuje się, że taką strukturę należy zwiększyć lub zmniejszyć w czasie działania programu. Np. utworzyliśmy na początku algorytmu dynamiczną tablicę 100 elementową, lecz dalej okazało się, że w tablicy tej należy dodatkowo umieścić jeszcze 50 kolejnych elementów. Co możemy zrobić? Odpowiedź jest prosta dynamicznie zmienić rozmiar naszej struktury. Zasada jest następująca

Oprócz wskazania do tablicy tworzymy dodatkową zmienną, która przechowuje jej maksymalny rozmiar. Oznaczmy tę zmienną przez nn. Każdą tablicę tworzymy z pewnym zapasem komórek, oznaczmy go przez z. Zmienna n przechowuje informację o ilości zajętych komórek. Gdy dodajemy element do tablicy, to najpierw zwiększamy n o 1 i sprawdzamy, czy warunek n nn jest spełniony. Jeśli tak, to tablica zawiera za mało komórek, i należy zwiększyć jej rozmiar. Operację tę przeprowadzamy następująco

Postępowanie wstawiania elementów do tablicy 1. Rezerwujemy nowy obszar pamięci o rozmiarze nn + z i zapamiętujemy jego adres w tymczasowej zmiennej. 2. Przepisujemy zawartość starego obszaru tablicy do nowego. 3. Usuwamy stary obszar w ten sposób system odzyska pamięć. 4. Do wskaźnika tablicy przepisujemy adres ze zmiennej tymczasowej. 5. Zmienną nn zwiększamy o z

Zwróćmy uwagę, że cała tablica zmieniła swoje położenie w pamięci. Jeśli zatem posiadaliśmy jakieś zmienne, które przechowywały adresy jej elementów (wskaźniki), to teraz przestaną one być aktualne, ponieważ wskazują stary obszar, który już do tej tablicy nie należy (chociaż przez pewien czas może zachowywać swoją zawartość aż system zapisze go innymi danymi). Należy to wziąć pod uwagę, gdy planujemy wykorzystywanie dynamicznych tablic o dynamicznym rozmiarze.

Kod postępowania if(++n >= nn) { typ_danych * T = new typ_danych[nn+z]; for(int i = 0; i < nn; i++) T[i] = A[i]; delete [] A; A = T; nn += z; }

Postępowanie usuwania elementów do tablicy Przy usuwaniu elementów z tablicy postępujemy podobnie. Gdy usuniemy element, to rozmiar tablicy n zostanie zmniejszony o 1. Sprawdzamy, czy jest spełniony warunek n nn - 2z. Jeśli tak, to tablica zajmuje zbyt duży obszar i powinniśmy zmniejszyć jej rozmiar.

Dlaczego w nierówności użyliśmy 2z a nie po prostu z? Chodzi o to, aby po zmniejszeniu rozmiaru tablica wciąż posiadała zapas z komórek, co zmniejszy ryzyko częstych przeładowań pamięci, które są przecież kosztowne czasowo. Zmianę rozmiaru tablicy wykonujemy podobnie jak przy zwiększaniu liczby elementów:

Kod postępowania if(--n <= nn) { typ_danych * T = new typ_danych[nn-z]; for(int i = 0; i < nn; i++) T[i] = A[i]; delete [] A; A = T; nn -= z; }

Wprowadzanie/wyprowadzanie danych Dane dla programu zwykle muszą być odczytywane ze zewnętrznego źródła konsoli lub pliku. W takim przypadku nie wiemy z góry (tzn. w trakcie pisania programu) ile ich będzie. Narzucającym się rozwiązaniem jest zastosowanie tablic dynamicznych. Ze źródła danych odczytujemy rozmiar tablicy, tworzymy tablicę dynamiczną o odpowiednim rozmiarze, a następnie wczytujemy do jej komórek poszczególne dane.

Sposoby odczytu zawartości tablicy z konsoli 1. Dane podajemy bezpośrednio z klawiatury. Sposób skuteczny i prosty dla niedużego zbioru danych. Jednakże przy większej ich liczbie staje się bardzo uciążliwy;

Sposoby odczytu zawartości tablicy z konsoli 2. Skopiowanie danych poprzez schowek. Procedura postępowania jest następująca: Tworzymy w notatniku Windows (aplikacja zawsze pod ręką) odpowiedni zbiór danych Zbiór kopiujemy do schowka (zaznaczamy całość Ctrl+A i naciskamy Ctrl+C) Uruchamiamy program Klikamy PPM w pasek tytułowy okna konsoli Z menu kontekstowego wybieramy polecenie Edytuj Wklej Gotowe (^.^)

Sposoby odczytu zawartości tablicy z konsoli 3. Przekierowanie standardowego wejścia z konsoli na plik na dysku. W tym przypadku program będzie pobierał dane z pliku, a nie z klawiatury.

Aby to uzyskać uruchamiamy program w oknie konsoli następująco: nazwa_programu < nazwa_pliku_wejściowego Program nazywa się szukaj.exe, a plik nosi nazwę dane.txt. Odpowiednie polecenie odczytu danych z pliku przez nasz program wygląda następująco: szukaj < dane.txt

To rozwiązanie umożliwia również zapis danych wynikowych nie na ekran konsoli, lecz do pliku na dysku. W tym celu wystarczy wydać polecenie: nazwa_programu > nazwa_pliku_wynikowego Niech plik wyniku będzie wyniki.txt. Obydwa polecenia można skupić w jedno następujące: szukaj < dane.txt > wyniki.txt

Jeśli często używamy takiego typu rozwiązania, możemy stworzyć plik wsadowy (ang. batch file) i umieścimy go w katalogu projektu. Oto jego zawartość: @echo off cls echo DANE WEJSCIOWE: echo. type dane.txt echo. prg < dane.txt > wyniki.txt echo WYNIKI: echo. type wyniki.txt echo.

Kod programu PRG #include <iostream> using namespace std; int main() { int * T,n,i; cin >> n; T = new int[n]; for(i = 0; i < n; i++) cin >> T[i]; cout << endl; for(i = 0; i < n; i++) cout << T[i] << " "; cout << endl << endl; delete [] T; return 0; } Program z pierwszego wiersza odczytuje liczbę n określającą ilość danych. Z następnych n wierszy odczytywane są dane i umieszczane w tablicy dynamicznej. Odczytane dane zostają następnie wyświetlone jedna obok drugiej. Można wypróbować z tym programem podane wcześniej trzy opcje dostarczania danych i wyprowadzania wyników.

Wypełnianie tablicy Czasami algorytm musi wstępnie wypełnić tablicę określoną zawartością. Operację taką przeprowadza się w pętli iteracyjnej, której zmienna licznikowa przebiega przez wszystkie kolejne indeksy elementów. Następnie wykorzystuje się zmienną licznikową jako indeks elementu tablicy, w którym umieszczamy określoną zawartość. W poniższych przykładach zakładamy, iż w programie zadeklarowano tablicę T o 20 elementach typu integer. Indeksy elementów tablicy T są w zakresie od 0 do 19.

Wypełnianie liczbami parzystymi począwszy od 2 for(i = 0; i < 20; i++) T[i] = (i + 1) << 1; Wypełnianie liczbami nieparzystymi począwszy od 1 for(i = 0; i < 20; i++) { T[i] = (i + 1) << 1; }

Wypełnianie stałą zawartością x for(i = 0; i < 20; i++) T[i] = x; Wypełnianie liczbami pseudolosowymi z przedziału <a,b> #include <cstdlib> #include <time.h> srand((unsigned)time(null)); for(i = 0; i < 20; i++) T[i] = a + rand() % (b - a + 1);

Dziękuję za uwagę (*^O^*)