Alokacja pamięci dla tablicy dwuwymiarowej

Podobne dokumenty
Część 4 życie programu

I - Microsoft Visual Studio C++

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:

Zmienne i struktury dynamiczne

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

Wskaźniki. Informatyka

Lab 9 Podstawy Programowania

Techniki Programowania wskaźniki 2

Programowanie Procedurale

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

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

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

Rozwiązanie. #include <cstdlib> #include <iostream> using namespace std;

Lab 10. Funkcje w argumentach funkcji metoda Newtona. Synonimy nazw typów danych. Struktury. Tablice struktur.

Programowanie - wykład 4

DYNAMICZNE PRZYDZIELANIE PAMIECI

Przekazywanie argumentów wskaźniki

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

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

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

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

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

tablica: dane_liczbowe

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

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

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

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

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

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

Projektowanie klas c.d. Projektowanie klas przykład

ZASADY PROGRAMOWANIA KOMPUTERÓW

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

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

Język C++ zajęcia nr 2

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

Programowanie i struktury danych

MACIERZE. Sobiesiak Łukasz Wilczyńska Małgorzata

Wstęp do programowania

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

Wstęp do programowania obiektowego, wykład 7

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

Wykład 1: Wskaźniki i zmienne dynamiczne

wykład II uzupełnienie notatek: dr Jerzy Białkowski Programowanie C/C++ Język C - funkcje, tablice i wskaźniki wykład II dr Jarosław Mederski Spis

Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016

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

Wstęp do programowania

Stałe, tablice dynamiczne i wielowymiarowe

Programowanie w języku C++

Zajęcia 6 wskaźniki i tablice dynamiczne

Wstęp do wskaźników w języku ANSI C

1 Podstawy c++ w pigułce.

Wstęp do Programowania, laboratorium 02

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

Programowanie obiektowe W3

Uzupełnienie dot. przekazywania argumentów

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

Podstawy Programowania Obiektowego

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

1 Podstawy c++ w pigułce.

Podstawy programowania w języku C++

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

Podstawy programowania w języku C++

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

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

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

KURS C/C++ WYKŁAD 8. Deklaracja funkcji informuje komplilator jaką wartość funkcja będzie zwracała i jakiego typu są jej argumenty.

Techniki Programowania wskaźniki

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

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

Wykład :37 PP2_W9

Pytania sprawdzające wiedzę z programowania C++

Argumenty wywołania programu, operacje na plikach

Język C zajęcia nr 11. Funkcje

Wprowadzenie do programowania i programowanie obiektowe

Szablony klas, zastosowanie szablonów w programach

Wstęp do Informatyki

ZASADY PROGRAMOWANIA KOMPUTERÓW ZAP zima 2015

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

Zadanie 04 Ktory z ponizszych typow danych w jezyku ANSI C jest typem zmiennoprzecinkowym pojedynczej precyzji?

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

Programowanie w C++ Wykład 3. Katarzyna Grzelak. 12 marca K.Grzelak (Wykład 1) Programowanie w C++ 1 / 35

Wstęp do programowania, część II

Globalne / Lokalne. Wykład 15. Podstawy programowania (język C) Zmienne globalne / lokalne (1) Zmienne globalne / lokalne (2)

Wskaznik. Przekazywanie wyniku funkcji przez return. Typy i zmienne wskaznikowe. Zmienna wskazywana. typ * nazwa_wkaznika

Programowanie komputerowe. Zajęcia 4

Podstawy programowania w języku C i C++

Programowanie komputerowe. Zajęcia 3

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

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

int f(); //f - funkcja zwracająca wartość typu int int (*f)(); //f - wskaźnik do funkcji zwracającej wartość typu int

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

IX. Wskaźniki.(3 godz.)

Wykład 1. Program przedmiotu. Programowanie Obiektowe (język C++) Literatura. Program przedmiotu c.d.:

Programowanie i struktury danych

Proste programy w C++ zadania

Który ciąg instrukcji nada zmiennej n wartość równą ilości liczb w pliku binarnym skojarzonym ze strumieniem fp? Wymierz odpowiedź

#include "stdafx.h" #include <iostream> #include "windows.h" using namespace std;

Katedra Elektrotechniki Teoretycznej i Informatyki. wykład 3 - sem.iii. Dr inż. M. Czyżak

Wstęp do programowania

wykład IV uzupełnienie notatek: dr Jerzy Białkowski Programowanie C/C++ Język C, a C++. wykład IV dr Jarosław Mederski Spis Język C++ - wstęp

Transkrypt:

Alokacja pamięci dla tablicy dwuwymiarowej struktura tablicy float a[3][4]; /* rezerwacja 3*4 elementów typu float */ a - adres początku dwuwymiarowej tablicy a[0] - adres początku pierwszej tablicy składowej a[1] - adres początku drugiej tablicy składowej a[2] - adres początku trzeciej tablicy składowej stała stała zmienna zmienna zmienna adres adres typ float typ float typ float a a[0] a[0][0] a[0][1] a[0][2] a[1] a[1][0] a[1][1] a[1][2] a[2] a[2][0] a[2][1] a[2][2] aby poprawnie obsłużyć tablicę musimy znać adresy: początku całej tablicy oraz początków wektorów składowych dla normalnej (statycznej) tablicy jest to określone przez nazwy tablic składowych a[ ][N] (np. w definicji funkcji zależnej od tablicy: void ff(float a[][n]);) dla tablicy określonej dynamicznie te adresy musimy podać dodatkowo zwykle stosowany sposób organizacji: o wskaźnik do tablicy jako całości wskazuje tablicę z adresami początków wszystkich tablic składowych o tablica wskaźnikowi wskaźnik do tablicy adresów wskaźnik do wskaźnika do typu składowego tablicy sposób dynamicznej alokacji tablicy dwuwymiarowej (np. typu float o potrzebna znajomość adresów początków wierszy zapisane w tablicy adresów pokazuje na nią wskaźnik do adresów (wskaźników) do float: float **a;

o potrzebna alokacja miejsca do przechowania adresów początków wierszy danych tablicy różne metody alokacji o metoda pierwsza: robimy dynamiczną alokację tablicy o rozmiarze w (ilości wierszy tablicy docelowej); adres początku tej tablicy zapisujemy w a alokujemy oddzielnie każdy wiersz tablicy; adres początku i-tego wiersza wpisujemy jako a[i] o metoda druga: alokujemy jednorazowo pamięć dla całej tablicy (adres początku obszaru zapisujemy w pomocniczym wskaźniku b) alokujemy pamięć dla adresów początku wierszy (wskazuje ją a), wpisujemy adresy początków wierszy jako pozycje tablicy którą wskazuje a o gdy chcemy zlikwidować tablicę a musimy dokonać odpowiednich zwolnień pamięci we właściwym porządku Przykład: dynamiczna alokacja tablicy float o rozmiarach N x K, przykład użycia, zwolnienie pamięci Metoda 1: #include <iostream> int main() cout << "Podaj ilosc wierszy i kolumn tablicy: "; int N, K; cin >> N >> K; float **a; // wskaźnik do tablicy jako całości a= new float* [N]; // alokacja wektora adresów wierszy for (int k=0; k<n; k++) a[k]=new float[k]; //alokacja tablic - wierszy a // użycie tablicy for(int i=0; i<n; i++) for(int j=0; j<k; j++) a[i][j]=0.0; // zwykła obsługa tablicy

int mniej; mniej=(n<k?n:k); for(int k=0; k<mniej; k++) *(*(a+k)+k)=1.0; // wersja wskaźnikowa for(int k=0; k<n; k++) for(int j=0; j<k; j++) cout << *(*(a+k)+j) << " "; cout << endl; // zwolnienie pamięci for (int k=0; k<n; k++) delete [ ] a[k]; delete [ ] a; system("pause"); Metoda 2: #include <iostream> #include <iomanip> int main() cout << "Podaj rozmiary (N x K) : "; int N,K; cin >> N >> K; int ** a; int *b; b=new int[n*k]; a = new int* [N]; for(int i=0; i<n; i++) a[i]=&b[i*k]; for(int i=0; i<n; i++) for(int j=0; j<k; j++) // *(*(a+i)+j)=(100*(i+1)+j+1); a[i][j]=100*(i+1)+j+1;

for(int i=0; i<n; i++) for(int j=0; j<k; j++) cout << setw(5) << a[i][j] << " "; cout << "\n"; //zwolnienie pamieci delete [] a[0]; delete [] a; system("pause"); return EXIT_SUCCESS; Typy wskaźników rzutowanie wskaźnik niesie wiedzę o typie na który wskazuje może wskazywać tylko na obiekty określonego typu int *wi1, *wi2, o1; double *wd; wi1=&o1; //O.K. wi2=wi1; //O.K. wd=wi1; //niedozwolone!!! możemy wymusić podobne podstawienia poprzez rzutowanie: wd=(double *) w1; wd=reinterpret_cast<double *> (w2) za sensowność tego rzutowania odpowiada programista typowe zastosowanie zamiana adresu na liczbę całkowitą i odwrotnie int adres_num=0x22ff6c; wi2=reinterpret_cast<int*>(adres_num); sygnal=*wi2; //ustawienie //odczyt o2=reinterpret_cast<int>(wi2); //adres liczba

wskaźniki void nie zawierają wiedzy o typie wskazywanym (tylko inormacje o położeniu) każdy wskaźnik dowolnego (nie-stałego) typu można przypisać wskaźnikowi typu void odwrotnie konieczne rzutowanie Stałe wskaźniki, wskaźniki do stałych wskaźnik stały ustawiony raz nie może ulec zmianie: int a, b; int * const wa=&a; wa=b; //błąd!!! wskaźnik do stałej uznaje pokazywany obiekt za stały: const a=10, b=20; const int *w; w=&o1; //O.K. w=&o2; //O.K. *w++; //blad!!! #include <cstdlib> #include <iostream> int main(int argc, char *argv[]) //******************************************************* // konwersje const_cast const int a=100; int *wa; wa=const_cast<int*>(&a); cout << "Wartosc stalej - przez wskaznik: *wa=" << *wa << endl; cout << "Wartosc stalej - przez nazwe: a=" << a << endl; *wa=*wa+1; cout << "\npo zmianie: (zwiekszenie wartosci o 1) \n\n";

cout << "Adresy: przez nazwe - " <<&a << " przez wskaznik " << wa << endl; cout << "Wartosci: przez nazwe " <<a << " przez wskaznik " << *wa << endl; cout << "Roznica adresow: " << &a - wa << "\n\n"; system("pause"); Wartosc stalej - przez wskaznik: *wa=100 Wartosc stalej - przez nazwe: a=100 Po zmianie: (zwiekszenie wartosci o 1) Adresy: przez nazwe - 0x22ff74 przez wskaznik 0x22ff74 Wartosci: przez nazwe 100 przez wskaznik 101 Aby kontynuowa, naci nij dowolny klawisz... Roznica adresow: 0

Wskaźniki do funkcji wskaźnik może pokazywać na różne obiekty w tym na funkcje wskaźnik ma zawierać adres może to być adres tego miejsca w pamięci, gdzie zaczyna się kod instrukcji danej funkcji wskaźnik musi zawierać informację typu co jaki jest charakter obiektu jaki wskazuje nazwa funkcji jest inaczej jej adresem w pamięci int ff(int); /* ff jest funkcją zależną od zmiennej typu int zwracającej wartość typu int */ int (*fp)(int); /* fp jest wskaźnikiem do funkcji zależnej od zmiennej int zwracającej wartość typu int */ fp = ff; /* wskaźnik fp wskazuje na funkcję ff */ k=ff(j); k=(*fp)(j); /* równoważne wywołanie funkcji ff */ po co nam wskaźniki do funkcji? o procedury zależne od funkcji (np. całkowanie, rozwiązywanie równań, sortowanie) o kształt tych procedur nie zależy od funkcji o wskaźniki do funkcji pozwalają na napisanie tych procedur w sposób ogólny (niezależny od konkretnej funkcji) Przykład 1: Program w którym użytkownik wskazuje w czasie wykonania, której funkcji użyć

#include <iostream> // przykład użycia wskaźników do funkcji int pierwsza(); int druga(); int main() int i; int (*w_f)(); cout << Podaj numer funkcji na która ma pokazywac wskaznik:\n ; cout << dopuszczalne wartosci : 1 lub 2: ; cin >> I; switch (i) case 1 : w_f=pierwsza; break; case 2 : w_f=druga; break; default: w_f=null; break; cout << Wedle rozkazu! \n ); if (w_f) for (i=0; i<3; i++) (*w_f)(); int pierwsza() cout << funkcja pierwsza!\n ; return 5; int druga() cout << funkcja druga!\n ; return 8;

ważniejsze momenty programu: o definicja wskaźnika do funkcji tak, by ilość i typ argumentów oraz typ zwracanego wyniku były takie same, jak w funkcjach, które ma wskazywać o ustawienie wskaźnika przyrównanie wskaźnika do nazwy funkcji (bez listy argumentów); nazwa funkcji reprezentuje jej adres o wykonanie funkcji określonej przez wskaźnik w_f użycie operatora odwołania pośredniego (*w_f)() o w tak napisanym programie wskaźnik w_f może pokazywać na dowolną funkcję niezależną od żadnych argumentów i zwracającej wartości typu int (o dowolnej nazwie). Przykład 2: rozwiązywanie równania f(x)=0 metodą bisekcji: start: podanie dwóch wartości xm, xp: f(xm)<0, f(xp)>0 dla xs=(xm+xp)/2 wyliczamy f(xs) o gdy f(xs)<0 za xm wstawiamy xs o gdy f(xs)>0 za xp wstawiamy xs powtarzamy, dopóki xm xp > eps (zakładana dokładność) dla ustalonej funkcji (np. f(x)=sin(x)*sin(x)-0.5) #include <iostream> #include <cmath> double ss(double x) return sin(x)*sin(x)-0.5; double bisec(double xm, double xp, double eps) double xh; double delta; delta = fabs(xm-xp); while (delta>eps) xh=(xm+xp)/2; if(ss(xh)<0.0) xm=xh; else xp=xh; delta=fabs(xm-xp); return (xm+xp)/2;

void start(double *xm, double *xp) int ok=1; do cout << "Podaj: xm xp "; cin << *xm, *xp; if (ss(*xp)<0.0 ss(*xm)>0.0) cout << "Zle wartosci poczatkowe:\n"; cout << xm= << *xm << ym= << ss(*xm) << endl; cout << xp= << *xp << ym= << ss(*xp) << endl; cout << "Sprobuj jeszcze raz\n\n"; else ok=0; while (ok); main() double xx,xm,xp; start(&xm,&xp); xx=bisec(xm,xp,1.0e-10); cout << "Rozwiazanie: << x << daje wartość funkcji << ss(xx) << endl; momenty zależne od funkcji: o ustalenie danych startowych funkcja start o funkcja bisec wersja ogólna użycie wskaźników #include <stdio.h> #include <math.h> double bisec(double (*f)(double), double xm, double xp, double eps) /* rozwiązanie równania g(x) = 0 dla dowolnej funkcji g(x) reprezentowanej przez wskaźnik do funkcji f */ double xh, delta; delta = fabs(xm-xp);

while (delta>eps) xh=(xm+xp)/2; if((*f)(xh)<0.0) xm=xh; else xp=xh; delta=fabs(xm-xp); return (xm+xp)/2; void start(double (*f)(double), double *xm, double *xp) /* zadanie warunków początkowych */ int ok=1; do printf("podaj: xm xp "); scanf("%lf %lf",xm,xp); if ((*f)(*xm)*(*f)(*xp)>0.0 (*f)(*xm)>0.0) printf("zle wartosci poczatkowe:\n"); printf("xm=%f ym=%f\n",*xm,(*f)(*xm)); printf("xp=%f yp=%f\n",*xp,(*f)(*xp)); printf("sprobuj jeszcze raz\n\n"); else ok=0; while (ok); double ss(double x) return sin(x)*sin(x)-0.5; main() double xx,xm,xp; double (*f)(double); start(ss,&xm,&xp); xx=bisec(ss,xm,xp,1.0e-10); f=ss; printf("rozwiazanie: %15.10lf %15.5e\n",xx,(*f)(xx)); system("pause");

funkcja jako argument innej funkcji: wywołanie (parametr aktualny) nazwa funkcji; odebranie (parametr formalny) wskaźnik do funkcji wykonanie funkcji określonej przez wskaźnik f użycie operatora odwołania pośredniego (*f)(x) tak napisany program możemy zastosować dla dowolnej funkcji zależnej od jednej zmiennej typu double zwracającej wartości typu double (o dowolnej nazwie). Złożone deklaracje deklaracja wskaźnika do funkcji przykład deklaracji złożonej zasady interpretacji deklaracji złożonych: o zaczynamy od nazwy obiektu o staramy się iść w prawo (tam mogą być operatory o najwyższym priorytecie ( ) [ ] ) o jeżeli to nie jest możliwe (np. gdy są nawiasy) idziemy w lewo o powtarzamy ten proces aż do osiągnięcia lewego skrajnego brzegu deklaracji Przykłady: int f[10]; int *f[10]; int f( ); int *f( ); int (*f)(); int *(*f)(); int (* (f[10] ) ) ( ); tablica 10 elementów typu int tablica 10 elemntów typu wskaźnik do int funkcja zwracająca wartości typu int funkcja zwracająca wskaźnik do int wskaźnik do funkcji zwracającej wartości typu int wskaźnik do funkcji zwracającej wskaźnik do zmiennej typu int f jest tablicą 10 elementów będących wskaźnikami do funkcji zwracających wartości typu int

Argumenty funkcji main w C/C++ możliwe przekazanie z wiersza polecenia wywołującego program dodatkowych parametrów (argumentów) do uruchamianego programu odbywa się to za pomocą argumentów funkcji main: main(int argc, char *argv[]) argc liczba całkowita >=1 określająca liczbę argumentów w linii komend argv wskaźnik do tablicy zawierającej argumenty argv[0] nazwa programu argv[1] pierwszy argument dodatkowy... argv[argc] NULL Przykład: echo, mnożenie #include <iostream> int main(int argc, char *argv[]) for(int i=1; i< argc; i++) cout << argv[i] << ; cout << endl; return 0; #include <iostream> #include <cstdlib> int main(int argc, char *argv[]) int s1,s2; s1=atoi(argv[1]); s2=atoi(argv[2]); cout << s1 << x << s2 << = << s1*s2 << endl;