Zmienne i struktury dynamiczne

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

ZASADY PROGRAMOWANIA KOMPUTERÓW

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

Część 4 życie programu

Programowanie i struktury danych

Deklaracja struktury w C++

Programowanie obiektowe W3

DYNAMICZNE PRZYDZIELANIE PAMIECI

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

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

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

Podstawy programowania. Wykład 7 Tablice wielowymiarowe, SOA, AOS, itp. Krzysztof Banaś Podstawy programowania 1

Alokacja pamięci dla tablicy dwuwymiarowej

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

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

Wstęp do programowania

Wykład 1: Wskaźniki i zmienne dynamiczne

Proste programy w C++ zadania

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:

// Liczy srednie w wierszach i kolumnach tablicy "dwuwymiarowej" // Elementy tablicy są generowane losowo #include <stdio.h> #include <stdlib.

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

Instrukcje sterujące

I - Microsoft Visual Studio C++

Ćwiczenie 7 z Podstaw programowania. Język C++, programy pisane w nieobiektowym stylu programowania. Zofia Kruczkiewicz

ZASADY PROGRAMOWANIA KOMPUTERÓW ZAP zima 2015

Co to jest sterta? Sterta (ang. heap) to obszar pamięci udostępniany przez system operacyjny wszystkim działającym programom (procesom).

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

tablica: dane_liczbowe

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

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

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

Uniwersytet Zielonogórski Instytut Sterowania i Systemów Informatycznych. Ćwiczenie 3 stos Laboratorium Metod i Języków Programowania

1 Podstawy c++ w pigułce.

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

Programowanie komputerowe. Zajęcia 1

Programowanie w języku C++

Podstawy Programowania C++

INFORMATYKA Z MERMIDONEM. Programowanie. Moduł 5 / Notatki

1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość

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

Programowanie i struktury danych

Dynamiczne struktury danych

MACIERZE. Sobiesiak Łukasz Wilczyńska Małgorzata

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

Zajęcia 6 wskaźniki i tablice dynamiczne

Wstęp do programowania INP001213Wcl rok akademicki 2018/19 semestr zimowy. Wykład 4. Karol Tarnowski A-1 p.

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

Materiał uzupełniający do ćwiczen z przedmiotu: Programowanie w C ++ - ćwiczenia na wskaźnikach

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

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

Lab 9 Podstawy Programowania

Algorytmy i język C++

// Potrzebne do memset oraz memcpy, czyli kopiowania bloków

Wskaźniki w C. Anna Gogolińska

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

Podstawy algorytmiki i programowania - wykład 1 Tablice powtórzenie Tablice znaków Tablice dwuwymiarowe

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

Programowanie - wykład 4

Podstawy programowania w języku C++

lekcja 8a Gry komputerowe MasterMind

int tab[5]; tab[1]; ciągły obszar pamięci, w którym umieszczone są elementy tego samego typu macierz [ ] - dwuargumentowy operator indeksowania

Wstęp do Informatyki

W języku C/C++ pomiędzy wskaźnikami a tablicami istnieje bardzo ścisły związek. Do onumerowania elementów w tablicy służą tzw. INDEKSY.

Programowanie komputerowe. Zajęcia 5

Programowanie Procedurale

1 Podstawy c++ w pigułce.

Pytania sprawdzające wiedzę z programowania C++

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

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

KURS C/C++ WYKŁAD 6. Wskaźniki

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.

int tab_a [ 2 ] [ 3 ];

Powyższe wyrażenie alokuje 200 lub 400 w zależności od rozmiaru int w danym systemie. Wskaźnik wskazuje na adres pierwszego bajtu pamięci.

Programowanie komputerowe. Zajęcia 4

Podstawy programowania w języku C++

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

Podstawy programowania. Wykład PASCAL. Zmienne wskaźnikowe i dynamiczne. dr Artur Bartoszewski - Podstawy prograowania, sem.

Wskaźniki. Informatyka

C++ wprowadzanie zmiennych

Zajęcia 6 wskaźniki i tablice dynamiczne

Spis treści WSKAŹNIKI. DYNAMICZNY PRZYDZIAŁ PAMIĘCI W JĘZYKU C. Informatyka 2. Instrukcja do pracowni specjalistycznej z przedmiotu

Program 22. #include <iostream> using namespace std; struct Osoba { string Imie; string Nazwisko; char Plec; int RokUr; };

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

Język C zajęcia nr 11. Funkcje

Prof. Danuta Makowiec Instytut Fizyki Teoretycznej i Astrofizyki pok. 353, tel danuta.makowiec at gmail.com

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

Wskaźniki. Przemysław Gawroński D-10, p marca Wykład 2. (Wykład 2) Wskaźniki 8 marca / 17

W2 Wprowadzenie do klas C++ Klasa najważniejsze pojęcie C++. To jest mechanizm do tworzenia obiektów. Deklaracje klasy :

Wykład 4: Klasy i Metody

Tablice są typem pochodnym. Poniżej mamy przykłady deklaracji różnych tablic:

Tablice cz. I Tablice jednowymiarowe, proste operacje na tablicach

Zasady programowania Dokumentacja

Wstęp do programowania

r. Tablice podstawowe operacje na tablicach

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

Stałe, tablice dynamiczne i wielowymiarowe

Podstawy programowania w języku C++

Program 6. Program wykorzystujący strukturę osoba o polach: imię, nazwisko, wiek. W programie wykorzystane są dwie funkcje:

Pętla for. Wynik działania programu:

*W uproszczeniu: jest dziewięciu sędziów przyznających po dwie noty: za wartość techniczną i artystyczną (skala od 0.0 do 6.0)

Transkrypt:

Zmienne i struktury dynamiczne Zmienne dynamiczne są to zmienne, które tworzymy w trakcie działania programu za pomocą operatora new. Usuwa się je operatorem delete. Czas ich występowania w programie jest uzależniony od potrzeb programu, zajmują więc miejsce w pamięci tylko wówczas, gdy są wykorzystywane (zmienne statyczne istnieją od początku do końca trwania programu). Zmienna dynamiczna nie ma własnej nazwy, dlatego dostęp do niej jest możliwy wyłącznie przez adres obszaru pamięci, który ona zajmuje. Adres ten jest przechowywany we wskaźniku do tej zmiennej. Przy deklaracji wskaźnika, dobrym zwyczajem jest nadanie mu wartości początkowej NULL (adres zerowy). Tablica dynamiczna jednowymiarowa Def. Tablica dynamiczna to taka tablica, która zostaje utworzona w trakcie działania programu i może być usunięta przed jego zakończeniem. Tablice dynamiczne mogą przechowywać elementy jednego typu (podobnie statyczne). Aby móc zadeklarować tablicę, musimy najpierw zadeklarować wskaźnik zdolny wskazywać element tablicy, a następnie za jego pomocą dynamicznie alokować pamięć przeznaczoną na przechowywanie tego elementu. Na żądanie napisanego przez nas programu system operacyjny przyznaje nam obszar pamięci, w którym będą przechowywane dane, w takiej ilości, w jakiej jest nam aktualnie potrzebne. Uzyskane w ten sposób dynamicznie alokowane obszary pamięci należy zwolnić przed zakończeniem działania programu. Deklaracja dynamicznej tablicy przykład: float *tab = NULL; //na razie wskaźnik na nic nie wskazuje tab = new float[k]; //k rozmiar tablicy (może być wpisany z klawiatury) Powyższe instrukcje można połączyć: float *tab = new float[k]; Program pyta użytkownika, ile liczb chce wprowadzić do tablicy, następnie wypełnia tablicę podanymi liczbami i wyświetla je. #include <iomanip> float *tab = NULL; cout << "Ile liczb wpiszesz do tablicy? "; int ile; float liczba; cin >> ile; // dołączamy bibliotekę w której zdefiniowany // jest sposób postępowania w razie braku // miejsca na utworzenie tablicy // deklaracja wskaźnika i ustawienie jego // wartosci na adres zerowy czyli NULL // za pomocą operatora new tab = new float [ile]; // próbujemy powołać do życia nową tablicę // jesli nie udało sie utworzyć // tablicy z powodu braku wolnej pamieci cout << "Brak miejsca na utworzenie tablicy"; for (int i=0; i<ile; i++) // jeśli utworzenie powiodło się

cout << "Podaj liczbe: "; cin >> liczba; *(tab+i) = liczba; // wypełniamy komórkę tablicy cout << endl << "Wypisuje zawartosc tablicy:" << endl; for (int i=0; i<ile; i++) cout << setw(6) << *(tab+i); delete [] tab; // usuwamy tablicę z pamięci // za pomocą operatora delete Jeśli w programie, korzystając z zapasu pamięci, zamierzamy utworzyć bardzo dużą tablicę, wówczas możemy nie znaleźć wystarczająco dużego, spójnego obszaru na jej przechowanie. W takim wypadku wskaźnik tab zamiast wskazywać na początek tablicy, wskazywał będzie na adres NULL. W bloku umieszczamy funkcje, które chcemy śledzić pod kątem wystąpienia błędów. W naszym programie jest to błąd związany z nieudaną alokacją pamięci za pomocą operatora new. Instrukcja catch przechwytuje przypadki, kiedy funkcja wewnątrz bloku się nie powiodła. W programie nie przesuwamy wskaźnika tab, a jedynie wpisujemy (lub wypisujemy) liczby do komórek odpowiednio przesuniętych względem komórki, na którą wskazuje wskaźnik tab. Jeśli przypadkową instrukcją przypisania zmienisz wartość wskaźnika wskazującego na tablicę dynamiczną, możesz stracić możliwość korzystania z tej tablicy. Po instrukcji zwolnienia pamięci zajętej przez tablicę wskaźnik tab nadal istnieje, ponieważ jest on zmienną statyczną, którą nie da się usunąć z programu. Tablica dynamiczna dwuwymiarowa Dwuwymiarowa tablica dynamiczna będzie jednowymiarową tablicą dynamiczną, przechowującą wskaźniki do tablic dynamicznych jednowymiarowych, w których umieszczone zostaną dane. Deklaracja dwuwymiarowej tablicy dynamicznej [w][k] przykład: int **tab; //tab jest wskaźnikiem do wskaźnika na zmienne typu int tab = new int *[w]; //w liczba wierszy; tablica jednowymiarowa wskaźników //do zmiennych typu int for (i=0; i<w; i++) //dla każdego wskaźnika z poprzedniej tablicy tab[i] = new int [k]; //tworzymy tablicę liczb całkowitych; k liczba kolumn Napiszemy program, który utworzy dwuwymiarową tablicę dynamiczną o żądanych wymiarach (podanych z klawiatury) i wypełni ją losowymi liczbami z przedziału <0, 100>. #include <iomanip> #include <cstdlib> int wie, kol, i, j; cout << "Podaj liczbe wierszy i kolumn tablicy:\n"; cin >> wie >> kol; srand(time(null)); // inicjacja generatora liczb int **tab; // deklaracja wskaźnika do wskaźnika na zmienne typu int // próba tworzenia tablicy wskaźników tab = new int *[wie];

cout << "Brak miejsca na utworzenie tablicy. Koncze program"; for (i=0; i<wie; i++) // próba tworzenia dynamicznych tablic liczb tab[i] = new int [kol]; cout << "Brak miejsca na utworzenie tablicy. Koncze program"; for (i=0; i<wie; i++) for (j=0; j<kol; j++) tab[i][j] = rand()%101; // wypełnianie tablic liczbami cout << setw(4) << tab[i][j]; // wyświetlanie elementów cout << endl; // teraz usuniemy tablicę z obszaru zajmowanej pamieci for (i=0; i<wie; i++) delete [] tab[i]; // usuwamy kolejne tablice z liczbami delete [] tab; // usuwamy tablicę wskaźników Poszczególne tablice z danymi nie muszą mieć takiego samego rozmiaru. Jak to jest w tym przykładzie? Napiszemy program, który utworzy tabelę odległości pomiędzy miastami. Nazwy miast oraz odległości pomiędzy nimi podaje użytkownik. #include <iomanip> int liczba, i, j; // liczba zmienna przechowująca liczbę miast cout << "Podaj liczbe miast: "; cin >> liczba; char **miasta; // deklarujemy tablicę dwuwymiarową o nazwie miasta miasta = new char *[liczba]; // w której poszczególne wiersze zawierają // nazwy miast (będące tablicami znaków) miasta[i] = new char[20]; cout << "Podaj nazwe miasta: "; cin >> miasta[i]; int **tab; // deklarujemy tablicę odległości między miastami tab = new int *[liczba];

// próba utworzenia tablicy tab[i] = new int[i+1]; // jeśli brak miejsca na tablicę // to zakończ działanie programu for (j=0; j<i+1; j++) if (i==j) tab[i][j]=0; else cout << "Podaj odleglosc z miasta " << miasta[i]; cout << " do miasta " << miasta[j] << ": "; cin >> tab[i][j]; cout << " "; cout << setw(10) << miasta[i]; cout << endl; for (j=0; j<i+1; j++) if (j==0) cout << setw(10) << miasta[i]; cout << setw(10) << tab[i][j]; cout << endl; delete [] tab[i]; delete [] tab; delete [] miasta;

Lista jednokierunkowa tworzenie listy i wprowadzanie do niej elementów Dynamiczna struktura danych jest ciągiem powiązanych ze sobą zmiennych dynamicznych, których liczba nie jest znana w czasie kompilacji, a nawet podczas uruchamiania programu. Lista jest złożoną dynamiczną strukturą danych, która przechowuje dane wraz z zapamiętaniem ich kolejności. W przeciwieństwie do tablicy elementy listy nie muszą być położone w sąsiednich komórkach pamięci. Lista jest dobrym rozwiązaniem, gdy chcemy np. zapamiętać dużą liczbę elementów, a nie dysonujemy wystarczająco dużym spójnym obszarem na utworzenie tablicy dynamicznej. Jednak główną i najważniejszą cechą listy jest możliwość dołączania elementów bez zdefiniowania uprzednio ich liczby. Nawet w przypadku tablicy dynamicznej po podaniu rozmiaru nie możemy już jej powiększyć. Tworzenie listy zaczynamy od zdefiniowania jej pierwszego elementu, czyli głowy. Głowa jest jednocześnie identyfikatorem listy. Do głowy dołączamy następne elementy. Dla każdego kolejnego elementu listy będzie znajdowany wolny obszar pamięci, do którego zostaną wpisane dane z nim związane. W wypadku listy jednokierunkowej każdy element zna adres elementu następnego, natomiast nie zna adresu elementu poprzedniego. Elementami listy są struktury. Każda ze struktur musi mieć, oprócz pól z danymi, dodatkowe pole, w którym jest przechowywany wskaźnik do następnego elementu listy. Ostatni element listy wskazuje na adres zerowy, niezwiązany z żadnym obiektem (NULL) informacja, że w liście nie ma już więcej elementów. Lista jest strukturą o dostępie sekwencyjnym, co oznacza, że aby dostać się np. do czwartego elementu, należy przejść wszystkie wcześniejsze elementy, począwszy od głowy. Natomiast w tablicy mamy do czynienia z dostępem swobodnym, czyli wystarczy podać indeks elementu, aby uzyskać do niego dostęp. W listach mamy dwa zasadnicze sposoby dołączania kolejnych elementów: dołączanie do początku listy i dołączanie do końca listy. /Który ze sposobów jest użyty w poniższym przykładzie?/ Napiszemy program, który zadaje pytanie, czy chcemy dodać element do listy. Dopóki otrzymuje pozytywną odpowiedź, pobiera wpisaną na klawiaturze liczbę całkowitą i dołącza ją do listy. Na koniec wyświetla na ekranie monitora całą zawartość listy. struct element_listy int liczba; element_listy *nastepny; ; element_listy *glowa = NULL; // tworzymy listę pustą element_listy *nowy; char odp; int d; cout << "Czy chcesz podac element listy? t/n: "; while (odp!='n') // dołaczamy kolejne elementy

cout << "Podaj dane : "; cin >> d; // próba dołaczenia nowego elementu nowy = new element_listy; // jeśli nie ma miejsca na nowy element cout << "Nie ma juz miejsca na nastepny element"; break; nowy->nastepny = glowa; // jest miejsce na nowy element nowy->liczba = d; glowa = nowy; cout << endl << "Chcesz podac kolejny element listy? t/n: "; element_listy *temp = glowa; // początek wypisywania elementów listy cout << endl << "Oto utworzona przez ciebie lista:" << endl; while (temp!=null) cout << temp->liczba << " "; temp = temp->nastepny; Pobieranie liczb jak wyżej i dołączanie kolejnych elementów do końca listy. #include <cstdlib> struct element_listy int liczba; element_listy *nastepny; ; element_listy *glowa = NULL; element_listy *ogon = NULL; element_listy *nowy; char odp; int d; cout << "Czy chcesz podac element listy? t/n: "; while (odp!='n')

cout << "Podaj dane: "; cin >> d; nowy = new element_listy; cout << endl << "Brak pamieci na ostatni element"; break; nowy->nastepny = NULL; nowy->liczba = d; if (glowa==null) glowa = nowy; ogon = glowa; else ogon->nastepny = nowy; ogon = nowy; cout << endl << "Czy chcesz podac kolejny element listy? t/n: "; element_listy *temp=glowa; // początek wypisywania elementów listy cout << endl << "Oto utworzona przez ciebie lista:" << endl; while (temp!=null) cout << temp->liczba << " "; temp = temp->nastepny;