typy złożone- tablice wielowymiarowe, struktury Wykład 6
Deklarowanie wskaźników nazwa_typu * nazwa_wskaznika; WSKAŹNIKI: PRZYPOMNIENIE Przypisywanie wskaźnikom wartości double * pn = &zmienna_typu_double; double * pt = new double; int * pi = new int[5]; Dereferencja wskaźników *pn = 3.71; *(pi+3)= 3; pi[2] = -12; Rozróżnienie wskaźnika od wskazywanej wartości Nazwy tablic pn to wskaźnik *pn to nie jest wskaźnik Nazwa każdej tablicy to wskaźnik Arytmetyka wskaźników ++pi; pi = pi+2; pi = pi-1; Dynamiczne i statyczne wiązanie tablic float * cus = new float[5];.. delete [] cus; 2
WSKAŹNIKOWY OPIS TABLICY float cus[4]; //przydzielenie ciągłego obszaru pamięci na przechowanie 4 liczb //zmiennoprzecinkowych cus[0] cus[1] cus[2] cus[3] cus cus to wskaźnik do początku tabeli z danymi typu float. zatem *cus == cus[0] czyli *(cus) oraz cus[1] mają tą samą wartość! cus +1 cus +2 cus+1 to wskaźnik do kolejnego elementu (drugiego) tabeli z danymi typu float. zatem *(cus+1) == cus[1] cus+2 to wskaźnik do kolejnego elementu (trzeciego) tabeli z danymi typu float. zatem *(cus+2) == cus[2] cus +3 Równoważność zapisu tablicowego i zapisu wskaźnikowego tabel cus+3 to wskaźnik do kolejnego elementu (czwartego) tabeli z danymi typu float. zatem *(cus+3) == cus[3] cus[3] = 3.14; *(cus+1) = 4.324; 3
TABLICE STATYCZNA: INICJOWANIE Inicjowanie tablicy: Lista inicjująca int a[]={ 10, 20, 30, 40, 50; int a[40]={0; Można pominąć rozmiar. Rozmiar zostanie obliczony int a[40]={10, 20; Wszystkim 40 elementom tablicy przypisane będzie 0 a[0]=10 i a[1]=20 pozostałym elementom tablicy przypisane będzie 0 4
TABLICE WIELOWYMIAROWE Tablice wielowymiarowe: double A[5], B[5][4], C[5][4][3]; Wektor 5- elementowy o składowych typu double Macierz 2d: 5 wierszy i 4 kolumny = wektor 5- elementowy o składowych wektor 4- elemntowy o składowych typu double Macierz 3d : Wektor 5- elementowy o składowych wektor 4- elemntowy o składowych typu wektor 3- elementowy typu double 5
TABLICA DWUWYMIAROWA Tablica 4x2: [ A 11 A 12 A 21 A 22 ] A 31 A 32 A 41 A 42 float A[4][2]; // A to tablica 4 elementów, z których każdy jest // 2-elementową tablicą o elementach typu float Elementy A[i][j] reprezentują elementy tablicy 2-wymiarowej: Tak A jest ułożona w pamięci systemu: A[0][0] A[1][0] A[2][0] A[3][0] A[0][1] A[1][1] A[2][1] A[3][1] A[0][0], A[0][1], A[1][0], A[1][1], A[2][0], A[2][1], A[3][0], A[3][1] A[0] A[1] A[2] A[3] Tablica 1D wskaźników do kolejnych wierszy tablicy 6 2D
TABLICA DWUWYMIAROWA int main(){ int tab[2][3]; //wektor od wektorów : dwa wektory zbudowane z 3 elementowych wektorów for (int i=0; i <2; ++i ) for (int j=0; j<3; ++j) tab[i][j]= i+j; for (int i=0; i <2; ++i ){ cout << endl; for (int j=0; j<3; ++j) cout <<" tab["<<i<<"]["<<j<<"] = " <<tab[i][j]; Zwyczajne wyświetlenie zawartości tab wyświetlenie zawartości tab przy pomocy wskaźników cout << "\n\n teraz przez wskazniki \n"; for (int i=0; i <2; ++i ){ cout << endl; for (int j=0; j<3; ++j) cout <<" tab["<<i<<"]["<<j<<"] = " << *(*(tab+i)+j); cout << "\n\n teraz tylko wskazniki:"; cout <<"\n tab = " << tab; for (int i=0; i <2; ++i ) cout <<"\n tab["<<i<<"] = " << tab[i]; cout <<endl; // jako jeden DŁUGI wektor for (int i=0; i <6; ++i ){ if (i%3 ==0) cout <<endl; cout <<' '<< *tab+i << '='<<*(*tab+i); return 0; tab tab[0][0] tab[0][1] tab[0][2] tab[1][0] tab[1][1] tab[1][2] tab[0] tab[1] wyświetlenie wektora wskażników do wierszy wyświetlenie zawartości tab 2D jako 1D 7
TABLICA 2D : dynamicznie int ** tab; //podwójny wskaźnik: wskaźnik do wskaźnika (niebieski) tab=new int *[N]; // pamięć na przechowanie N wskaźników do int (różowa) //tab wskazuje na tab[0] for (int i=0; i<n;++i) //kreujemy M obiektów dla każdego z N wskaźników tab[i]=new int [M]; //tab[i] wskazuje na początkowy element tab[i][0] tab tab[0] tab[1] tab[0][0] tab[0][1] tab[0][m] tab[1][0] tab[1][1] tab[1][m] tab[n] tab[n][0] tab[n][1] tab[n][m] for (int i=0; i<n; ++i) delete [] tab[i]; // zwalniamy zieloną pamięć delete [] tab; //zwalniamy różową i niebieską 8
#include <iostream> using namespace std ; void hydraulik_wart(int kran) ; void hydraulik_refer(int *wsk_do_kranu) ; SEMANTYKA WARTOŚCI A SEMANTYKA REFERENCJI int main(){ int kran = -1 ; cout << "Stan techniczny kranu = "<< kran << endl ; semantyka wartości (kopiowania) w C++ działa wobec zmiennych prostych typów wbudowanych oraz obiektów klasy zdefiniowanej przez programistę hydraulik_wart( kran ) ; cout <<"Po wezwaniu hydraulika stan techniczny kranu = << kran << endl ; return 0; hydraulik_ref( &kran ) ; cout <<"Po wezwaniu hydraulika stan techniczny kranu = << kran << endl ; void hydraulik_ref(int *wsk_do_kranu) { *wsk_do_kranu = 100 ; // akcja naprawiania void hydraulik_wart(int kran) { kran = 100 ; // akcja naprawiania semantyka referencji (wskazywania) w C++ działa wobec zmiennych typów złożonych 9
TABLICE JAKO PARAMETRY FUNKCJI Zadanie : Przygotuj funkcję obliczającą iloczyn skalarny dwóch wektorów Dane: tablice A[n] i B[n] Wynik: iloczyn_skalarny= A[1]*B[1] +A[2]*B[2]+.+A[n]*B[n] Zmienna pomocnicza: suma Rozwiązanie: i=1 suma=0 dopóki i <= n wykonuj suma= suma + A[i]*B[i] ++i iloczyn_skalarny=suma oddaj iloczyn_skalarny Pierwsze podejście Drugie podejście float iloczyn_wektorow (float *A, float *B, int rozmiar){ float suma=0; for (int i=0; i< rozmiar;++i) suma += *(A+i)* *(B+i); return suma; void iloczyn_wektorow (float *A, float *B, int rozmiar, float *rezultat){ for (int i=0; i< rozmiar;++i) *rezultat += *(A+i)* *(B+i); return; 10
TABLICE JAKO PARAMETRY FUNKCJI Zadanie : Przygotuj funkcję wyznaczającą sumę dwóch wektorów Dane: tablice A[n] i B[n] Wynik: tablica C[n] taka, że C[i]= A[i]+B[i] dla i=1,2,..,n Rozwiązanie: i=1 dopóki i <= n wykonuj C[i]= A[i] +B[i] ++i Wszystkie wektory : A, B i C są utworzone poza funkcją. Funkcją ma dostęp do pamięci, gdzie A, B i C są ulokowane void suma_wektorow (float *A, float *B, flat *C, int rozmiar){ for (int i=0; i< rozmiar;++i) *(C+i)= *(A+i)+ *(B+i); return ; 11
Zadanie : Przygotuj funkcję wyznaczającą sumę dwóch macierzy TABLICE JAKO PARAMETRY FUNKCJI Dane: tablice A[n][m] i B[n][m] Wynik: tablica C[n][m] taka, że C[i][j]= A[i][j]+B[i][j] dla i=1,2,..,n oraz j =1,2,,m Rozwiązanie: i=1 j=1 dopóki i <= n wykonuj dopóki j<= m wykonuj C[i][j]= A[i][j] +B[i][j] ++j ++i **: wskaźnik do wektora zbudowanego z wartości typu float void suma_wektorow (float *A[], float *B[], float *C[], int n, int m){ for (int i=0; i< rozmiar;++i) *(C+i)= *(A+i)+ *(B+i); return ; Nawias kwadratowy [] ma pierwszeństwo przed operatorem dereferencji * 12
TABLICE STATYCZNA #include <iostream> using namespace std; void drukuj_macierz( int (*A)[2], int,int ); int main(){ const int n=3, m=2; int A[n][m] ={{1,2, {3,4, {5,6; cout <<"\nmacierz A: "; drukuj_macierz(a,n,m); return 0; Ilość kolumn jest zafiksowana void drukuj_macierz( int (*A)[2], int n,int m=2){ for (int i=0; i < n; ++i){ cout << endl; for (int j=0; j<m; ++j) cout << '\t'<< A[i][j]<<" "; cout << endl; 13
Struktura : zespoły, grupy danych, rekordy danych Słowo kluczowe oznaczające typ złożony skonstuowany z elementów różnych typów struct NAZWA_STRUKTURY { pole1; pole2; ta z klaracjami pów uktury List dek typ stru ; STRUKTURA Przykład: struct Skoczek { char nazwisko[16]; char imie[11]; int punkty; ; 14
UŻYCIE STRUKTURY #include <iostream> Czy można użyć string? Dev-cpp nie pozwala struct Skoczek { char nazwisko[20]; char imie[15]; int punkty; ; using namespace std; int main() { const int ilosc_skoczkow=4; struct Skoczek narciarze[ilosc_skoczkow] ={ {"Zyla", "Piotr", 177, {"Stoch", "Kamil", 187, cout<< "TABELA WYNIKOW: \n" ; for (int i=0; i< ilosc_skoczkow; ++i){ cout << narciarze[i].imie << \t ; cout<< narciarze[i].nazwisko << \t ; cout<< narciarze[i].punkty<<endl; return 0; {"Kot", "Maciej", 182, {"Mietus", "Krzysztof", 179; 15
UŻYCIE STRUKTUR #include <iostream> struct Skoczek { char nazwisko[20]; char imie[15]; int punkty; ; using namespace std; void drukuj_skoczka( struct Skoczek ); const int ilosc_skoczkow=4; int main() { system("chcp 1250"); struct Skoczek narciarze[ilosc_skoczkow] ={ {"Żyła", "Piotr", {"Stoch", "Kamil", {"Kot", "Maciej", {"Miętus", "Krzysztof"; cout<< "TABELA WYNIKÓW: \n" ; for (int i=0; i< ilosc_skoczkow; ++i) drukuj_skoczka(narciarze[i]); return 0; /*----------------------------------------------------------------------*/ void drukuj_skoczka(struct Skoczek skoczek ){ cout <<left; cout.width(10); cout << skoczek.imie ; cout.width(7); cout<<skoczek.nazwisko ; cout.width(5); cout<< skoczek.punkty<<endl; 16