1 / 54

Podstawy informatyki 2013/2014

Podstawy informatyki 2013/2014. Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi i Pawła Jerzego Matuszyka. int , int *, int **. int a=1; int * w=&a ; int ** ww=&w ; cout<<&ww<<endl ; cout<<ww<<endl ;

mahlah
Download Presentation

Podstawy informatyki 2013/2014

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Podstawy informatyki2013/2014 Łukasz SztangretKatedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiałyDanuty Szeligi i Pawła Jerzego Matuszyka

  2. int, int*, int** int a=1; int *w=&a; int **ww=&w; cout<<&ww<<endl; cout<<ww<<endl; cout<<*ww<<endl; cout<<**ww<<endl; 0043F8CC 0043F8CF 1 a 0043F8D0 0043F8D3 0043F8CC w 0043F8D4 0043F8D7 0043F8D0 ww 0043F8D4 0043F8D0 0043F8CC 1

  3. void f1(int), void f3(int*), void f5(int**)void f2(int&), void f4(int*&), void f6(int**&) void f1(intfa){} intmain() { int a=1; int *w=&a; int **ww=&w; f1(a); return 0; } 0043F8CC 0043F8CF 1 a Nie możemy zmienić: a, w, ww Możemy zmienić: 0043F8D0 0043F8D3 0043F8CC w 0043F8D4 0043F8D7 0043F8D0 ww 0043F8D8 0043F8DB 1 fa

  4. void f1(int), void f3(int*), void f5(int**)void f2(int&), void f4(int*&), void f6(int**&) void f2(int &fa){} intmain() { int a=1; int *w=&a; int **ww=&w; f2(a); return 0; } 0043F8CC 0043F8CF 1 a fa Nie możemy zmienić: w, ww Możemy zmienić: a 0043F8D0 0043F8D3 0043F8CC w 0043F8D4 0043F8D7 0043F8D0 ww

  5. void f1(int), void f3(int*), void f5(int**)void f2(int&), void f4(int*&), void f6(int**&) void f3(int *fw){} intmain() { int a=1; int *w=&a; int **ww=&w; f3(w); return 0; } 0043F8CC 0043F8CF 1 a Nie możemy zmienić: w, ww Możemy zmienić: a 0043F8D0 0043F8D3 0043F8CC w 0043F8D4 0043F8D7 0043F8D0 ww 0043F8D8 0043F8DB 0043f8CC fw

  6. void f1(int), void f3(int*), void f5(int**)void f2(int&), void f4(int*&), void f6(int**&) void f4(int *&fw){} intmain() { int a=1; int *w=&a; int **ww=&w; f4(w); return 0; } 0043F8CC 0043F8CF 1 a Nie możemy zmienić: ww Możemy zmienić: a, w 0043F8D0 0043F8D3 0043F8CC w fw 0043F8D4 0043F8D7 0043F8D0 ww

  7. void f(int), void f(int*), void f(int**)void f(int&), void f(int*&), void f(int**&) void f5(int **fww){} intmain() { int a=1; int *w=&a; int **ww=&w; f5(ww); return 0; } 0043F8CC 0043F8CF 1 a Nie możemy zmienić: ww Możemy zmienić: a, w 0043F8D0 0043F8D3 0043F8CC w 0043F8D4 0043F8D7 0043F8D0 ww 0043F8D8 0043F8DB 0043F8D0 fww

  8. void f(int), void f(int*), void f(int**)void f(int&), void f(int*&), void f(int**&) void f6(int **&fww){} intmain() { int a=1; int *w=&a; int **ww=&w; f6(ww); return 0; } 0043F8CC 0043F8CF 1 a Nie możemy zmienić: Możemy zmienić: a, w, ww 0043F8D0 0043F8D3 0043F8CC w 0043F8D4 0043F8D7 0043F8D0 ww fww

  9. Możliwe wywołania funkcji int a=1; int *w=&a; int **ww=&w; 0043F8CC 0043F8CF 1 a 0043F8D0 0043F8D3 0043F8CC w 0043F8D4 0043F8D7 0043F8D0 ww int a; int *w; int **ww; void f1(int); f1(a); f1(*w); f1(**ww); void f2(int&); f2(a); f2(*w); f2(**ww); void f3(int*); f3(&a); f3(w); f3(*ww); void f4(int*&); -- f4(w); f4(*ww); void f5(int**); -- f5(&w); f5(ww); void f6(int**&); -- -- f6(ww);

  10. Wskaźnik do funkcji • Funkcję można wywołać lub można pobrać jej adres (miejsce, gdzie jej kod zaczyna się w pamięci). • W wyniku wywołania zaczyna się wykonywać kod tej funkcji: q = fun(x, 7); • W wyniku pobrania adresu funkcji uzyskuje się wskaźnik do tej funkcji: pfun = &fun; • Wskaźnika tego można użyć do wywołania funkcji: q = (*pfun)(x, 7)

  11. Wskaźnik do funkcji • Definicja: • funkcji fun typu T (T1, T2, ...): T fun(T1, T2, ...) { ... } • wskaźnika pf (do tej funkcji) typu T (*)(T1, T2, ...): T (*pf)(T1, T2, ...); int (*pf)(double, char); • Ustawienie (dwa alternatywne sposoby): pf = fun; pf = &fun; • Użycie (wywołanie funkcji przez wskaźnik): intres; double x=0.5; char y=‘a’; res = (*pf)(x, y); res = pf(x, y);

  12. #include<iostream> usingnamespacestd; intpodwoj(int a); intpotroj(int a); intmain() { int a, (*fun)(int a); a=10; fun=podwoj; cout << (*fun)(a) << endl; fun=potroj; cout << (*fun)(a) << endl; cout << a << endl; return 0; } int podwoj(int a) { return (a*2); } int potroj(int a) { return (a*3); } Wskaźnik do funkcji 20 30 10

  13. Wskaźnik do funkcji #include<iostream> usingnamespacestd; int f(int a); voidfun(int (*)(int),int); intmain() { int (*w)(int)=&f; fun(w,5); return 0; } int f(int a) { return 2*a; } void fun(int (*wf)(int), int a) { cout<<wf(a)<<endl; } 10

  14. Czytanie deklaracji • Zaczynamy od nazwy. • Następnie poruszamy się w prawo. • Gdy napotkamy na nawias zamykający poruszamy się w lewo. • Jeżeli odczytaliśmy już wszystko w obrębie danego nawiasu wychodzimy na zewnątrz i znowu poruszamy się w prawo.

  15. Co to jest a??? int *(*(*a)(int))[10]; int *(*(*a)(int))[10 a jest]; int *(*(*a)(int))[10]; wskaźnikiem int *(*(*a)(int))[10]; do funkcji wywoływanej z parametrem typu int int *(*(*a)(int))[10]; zwracającej wskaźnik int *(*(*a)(int))[10]; do 10-cio elementowej tablicy int *(*(*a)(int))[10]; wskaźników do obiektów typu int

  16. Co to jest a??? int (*(*a())[10])(); int (*(*a())[10])(); a jest funkcją wywoływaną bez parametrów int (*(*a())[10])(); zwracającą wskaźnik int (*(*a())[10])(); do 10-cio elementowej tablicy int(*(*a())[10])(); wskaźników int(*(*a())[10])(); do funkcji wywoływanych bez parametrów int(*(*a())[10])(); zwracających obiekty typu int

  17. Co to jest a??? float (*(*a)(int))(); float (*(*a)(int))();a jest float (*(*a)(int))();wskaźnikiem float (*(*a)(int))();do funkcji wywoływanej z parametrem typu int float(*(*a)(int))();zwracającej wskaźnik float(*(*a)(int))(); do funkcji wywoływanej bez parametrów float(*(*a)(int))(); zwracających obiekty typu float

  18. Co to jest a??? int (*(*(*a)())[10])(); int (*(*(*a)())[10])();a jest int (*(*(*a)())[10])();wskaźnikiem int (*(*(*a)())[10])();do funkcji wywoływanej bez parametrów int (*(*(*a)())[10])();zwracającej wskaźnik int (*(*(*a)())[10])();do 10-cio elementowej tablicy int(*(*(*a)())[10])();wskaźników int(*(*(*a)())[10])(); do funkcji wywoływanych bez parametrów int(*(*(*a)())[10])(); zwracających obiekty typu int

  19. Wskaźnik do funkcji jako argument innej funkcji #include<iostream> usingnamespacestd; double dod (double a, double b){return (a+b);} double ode (double a, double b){return (a-b);} double mno (double a, double b){return (a*b);} double dzi (double a, double b){return (a/b);} double wykonaj(double (*)(double, double),double,double); intmain() { intwybor; double a ,b; cout << "Wybierz dzialanie\n"; cout << "1.Dodawanie\n2.Odejmowanie\n"; cout << "3.Mnozenie\n4.Dzielenie\n"; cin >> wybor; cout << "Podaj dwie liczby\n"; cin >> a >> b; double (*wsk[4])(double, double)={dod, ode, mno, dzi}; cout<<wykonaj(*wsk[wybor-1],a,b)<<endl; return 0; } double wykonaj(double (*wsk)(double, double), double a, double b){return (*wsk)(a,b);}

  20. Arytmetyka wskaźników • Rezultat zastosowania do wskaźników operatorów arytmetycznych +, -, +=, -=, ++ i -- zależy od typu wskazywanego obiektu. • Stosując operator arytmetyczny do wskaźnika p typu T* zakładamy, że p wskazuje na element w tablicy obiektów typu T. • Wtedy: • p + 1oznacza adres następnego elementu w tablicy, • p - 1oznacza adres poprzedniego elementu w tablicy, • p + ioznacza adres i-tego następnego elementu, • p - i oznacza adres i-tego poprzedniego elementu

  21. Arytmetyka wskaźników #include<iostream> usingnamespacestd; intmain() { inttab[]={0,1,2,3,4}; int *wsk1,*wsk2; wsk1=&tab[1]; wsk2=&tab[4]; cout << wsk2-wsk1 << endl; return 0; } 3

  22. Arytmetyka wskaźników intmain() { inttab[5]={1,2,3,4,5}; int *wsk; wsk=tab; for (int i=0;i<5;i++) { cout<<*wsk<<"\t"<<wsk<<endl; wsk++; } return 0; }

  23. Porównywanie wskaźników • Dwa wskaźniki tego samego typu są równe (różne) jeżeli pokazują (nie pokazują) na ten sam obiekt: int *wsk1,*wsk2; if (wsk1==wsk2){} //ten sam obiekt if (wsk1!=wsk2){} //różne obiekty • Porównywanie wskaźników operatorami <, >, <= i >= ma sens tylko wtedy, gdy oba wskaźniki wskazują na elementy tej samej tablicy. • Wtedy, jeżeli w1 < w2, to oznacza to, że obiekt wskazywany przez w1 znajduje się w pamięci wcześniej niż drugi (w1 jest bliżej początku tablicy niż w2).

  24. Wskaźniki i const • zwykły wskaźnik: int *wsk; • stały wskaźnik int * constwsk; • wskaźnik do obiektu stałego constint * wsk; • stały wskaźnik do stałego obiektu constint * constwsk;

  25. Stały wskaźnik #include<iostream> usingnamespacestd; intmain() { int a=5,b=10; int * constw=&a; cout << *w << endl; (*w)++; cout << *w << endl; w=&b; return 0; } 5 6 BŁĄD

  26. Wskaźnik do obiektu stałego intmain() { constint a=5,b=10; constint *st_w; int *zm_w; st_w=&a; cout << *st_w << endl; st_w=&b; cout << *st_w << endl; (*st_w)++; zm_w=&a; return 0; } 5 10 BŁĄD BŁĄD

  27. Stały wskaźnik do stałego obiektu intmain() { constint a=5,b=10; const int * const st_w=&a; cout << *st_w << endl; (*st_w)++; st_w=&b; return 0; } 5 BŁĄD BŁĄD

  28. Wskaźnik typu void intmain() { intti[]={1,2,3,4},*wi; double td[]={1.0,2.0,3.0,4.0},*wd; void *wv; wi=ti; wd=td; wv=wi; cout<<*wv<<endl; wv++; wv=wd; return 0; } BŁĄD BŁĄD

  29. Operatory rzutowania intmain() { double d=2.5; int i; i=d; cout << d << endl << i << endl; return 0; } conversion from 'double' to 'int', possible loss of data 2.5 2

  30. Operatory rzutowania intmain() { double d=2.5; int i; i=(int)d; // lub i=int(d) cout << d << endl << i << endl; return 0; } 2.5 2

  31. Operatory rzutowania intmain() { int i=65; char c; c=(char)i; cout << i << endl << c << endl; return 0; } 65 A

  32. Nowe operatory rzutowania • Stare operatory rzutowania: • (nazwa_typu)wyrażenie • nazwa_typu (wyrażenie) • Nowe operatory rzutowania: • static_cast<nazwa_typu>(wyrażenie) • const_cast<nazwa_typu>(wyrażenie) • dynamic_cast<nazwa_typu>(wyrażenie) • reinterpret_cast<nazwa_typu>(wyrażenie)

  33. static_cast • Operator static_cast jest używany do wszystkich konwersji, które są dobrze zdefiniowane i mogą być wykonane przez kompilator (mogą powodować ostrzeżenia), np.: • konwersje roszerzające (np. int -> float, int -> long), • konwersje zawężające (utrata informacji, np. float -> int),

  34. static_cast intmain() { double d=3.14; int i; i=static_cast<int>(d); cout << d << endl << i << endl; return 0; } 3.14 3

  35. const_cast • Używany do konwersji typu: • const -> non-const • volatile -> non-volatile • Używany TYLKO do konwersji tego typu – jeżeli równocześnie konieczna jest inna konwersja, musi być ona wykonana za pomocą oddzielnego operatora. • Nie może być użyty do bezpośredniej konwersji obiektu const na non-const.

  36. const_cast intmain() { constint a=2; constint *st_w=&a; int *zm_w; cout<<a<<endl; zm_w=const_cast<int *>(st_w); *zm_w=-2; cout<<*zm_w<<endl; cout<<a<<endl; return 0; } 2 -2 ???

  37. dynamic_cast dynamic_cast robi rzutowanie tylko pod warunkiem, że w danej konkretnej chwili ma to sens.

  38. dynamic_cast class pojazd { protected: intl_kol, max_sp; public: pojazd(inta,int b):l_kol(a),max_sp(b){} virtualvoid wypisz(); }; classsamochod: public pojazd { double poj_s; public: samochod(inta,intb,double c):pojazd(a,b), poj_s(c){} void wypisz(); }; class rower: public pojazd { intli_prze; public: rower(int a, int b, int c):pojazd(a,b), li_prze(c){} void wypisz(); }; intmain() { pojazd P(2,30),*WP; samochod S(4,180,1.9),*WS; rower R(2,30,21); char a; cout<<"S czy R\n"; cin>>a; if (a=='S') WP=&S; else WP=&R; WS=dynamic_cast<samochod*>(WP); cout<<&S<<endl; cout<<WS<<endl; return 0; } S czy R S 0040F950 0040F950 S czy R R 0040F950 00000000

  39. reinterpret_cast • Jest to najmniej bezpieczny mechanizm rzutowania, mogący powodować błędy. • Traktuje obiekty jak pewien zestaw bitów, nie zwraca uwagi na znaczenie.

  40. reinterpret_cast intmain() { intti[]={1,2,3,4},*wi,*wt; double td[]={1.0,2.0,3.0,4.0},*wd; wi=ti; wd=td; for (int i=0;i<4;i++) cout<<*(wi+i)<<"\t"<<*(wd+i)<<endl; wt=wi; wi=reinterpret_cast<int *>(wd); wd=reinterpret_cast<double *>(wt); cout<<endl; for (int i=0;i<4;i++) cout<<*(wi+i)<<"\t\t"<<*(wd+i)<<endl; return 0; }

  41. reinterpret_cast intmain() { int *wi; cin>>wi; return 0; } intmain() { int *wi,a; a=00203040; wi=reinterpret_cast<int*>(a); cout<<wi<<endl; cout<<oct<<a<<endl; return 0; } 00010620 203040

  42. Dynamiczne tworzenie tablic • 1D int *w=newint[n]; • 2D int **w = new int*[n]; for(int i=0;i<n;i++)     w[i] = newint[m]; • 3D int ***w = new int**[n]; for(int i=0;i<n;i++)     w[i] = newint*[m]; for(int i=0;i<n;i++)     for(int j=0;j<m;j++) w[i][j] = newint[o];

  43. Usuwanie tablic • 1D delete [] w; • 2D for(int i=0;i<n;i++) delete [] w[i]; delete [] w; • 3D for(int i=0;i<n;i++)     for(int j=0;j<m;j++) delete [] w[i][j]; for(int i=0;i<n;i++) delete [] w[i]; delete [] w;

  44. Dynamicznetworzenietablicy 2D 0031FC3C 0031FC3F 00658E58 tab 0031FC40 0031FC43 2 m 0031FC44 0031FC47 3 n int n=3,m=2; int **tab; tab=newint *[n]; for (int i=0; i<n; i++) tab[i]=newint [m]; for (int i=0; i<n; i++) for (int j=0; j<m; j++) tab[i][j]=i*m+j+1; cout<<&tab<<endl; cout<<tab<<endl; cout<<*tab+1<<endl; cout<<*(tab+1)<<endl; cout<<tab[1]<<endl; cout<<&tab[1]<<endl; cout<<tab[1][0]<<endl; cout<<*(*(tab+1)+1)<<endl; cout<<&tab[1][0]<<endl; 00658E58 00658E5B 00651F10 int* 00658E5C 00658E5F 00651F20 int* 00658E60 00658E63 00651F30 int* 0031FC3C 00658E58 00651F10 00651F13 1 int 00651F14 00651F14 00651F17 2 int 00651F20 00651F20 00651F20 00651F23 3 int 00658E5C 00651F24 00651F27 4 int 3 4 00651F30 00651F33 5 int 00651F20 00651F34 00651F37 6 int

  45. Dynamicznetworzenietablicy 2D int n=3,m=2; int **tab; tab=newint *[n]; for (int i=0; i<n; i++) tab[i]=newint [m]; for (int i=0; i<n; i++) for (int j=0; j<m; j++) tab[i][j]=i*m+j+1; cout<<typeid(&tab).name()<<endl; cout<<typeid(tab).name()<<endl; cout<<typeid(*tab+1).name()<<endl; cout<<typeid(*(tab+1) ).name()<<endl; cout<<typeid(tab[1] ).name()<<endl; cout<<typeid(&tab[1] ).name()<<endl; cout<<typeid(tab[1][0] ).name()<<endl; cout<<typeid(*(*(tab+1)+1) ).name()<<endl; cout<<typeid(&tab[1][0] ).name()<<endl; int * * * int * * int * int * int * int * * int int int *

  46. Dynamiczne tworzenie tablic #include<iostream> usingnamespacestd; intmain() { int n; cout << "Podaj rozmiar tablicy\n"; cin >> n; int *w=newint[n]; for (int i=0; i<n; i++){ cout << "Podaj wartosc\n"; cin >> w[i];} for (int i=0; i<n; i++) cout << *(w+i) << endl; delete [] w; return 0; }

  47. Dynamiczne tworzenie tablic 2-D #include<iostream> using namespace std; int main() { int n; cout << "Podaj rozmiar\n"; cin >> n; int **wsk=new int*[n]; for (int i=0; i<n; i++) wsk[i]=new int[n]; for (int i=0; i<n; i++) for (int j=0; j<n; j++) wsk[i][j]=i*n+j; for (int i=0; i<n; i++){ for (int j=0; j<n; j++) cout<<*(*(wsk+i)+j)<<"\t"; cout << endl;} for(int i=0;i<n;i++) delete [] wsk[i]; delete [] wsk; return 0; }

  48. Wskaźnik do tablicy wielowymiarowej intmain() { inttab[][3]={1,2,3,4,5,6,7,8,9}; int **w=newint*[3]; for (int i=0; i<3; i++) *(w+i)=&tab[i][0]; for (int i=0; i<3; i++){ for (int j=0; j<3; j++){ cout<<w[i][j]<<"\t";} cout << endl;} return 0; }

  49. Funkcja zwracająca tablicę int *fun() { inttab[5]; for (int i=0; i<5; i++) tab[i]=i; return tab; } intmain() { int *w; w=fun(); for (int i=0; i<5; i++) cout << w[i] << endl; return 0; }

  50. Funkcja zwracająca tablicę int *fun() { int *wsk=newint[5]; for (int i=0; i<5; i++) wsk[i]=i; return wsk; } intmain() { int *w; w=fun(); for (int i=0; i<5; i++) cout << w[i] << endl; return 0; }

More Related