250 likes | 352 Views
Wskaźniki repetytorium. Wskaźniki. 4. Y. 4. 1. X. 5. 5. 2. p. p = &Y;. *p = 4;. int Y = 1, X = 2; X = 5; int *p = &X;. Niezainicjowane wskaźniki. Y. 1. X. 2. p. p1. int *p1=NULL; // b łą d czasu wykonania. int Y = 1, X = 2; int *p = &X;. int *p1;. *p1 = 3; .
E N D
Wskaźniki 4 Y 4 1 X 5 5 2 p • p = &Y; • *p = 4; int Y = 1, X = 2; X = 5; int *p = &X;
Niezainicjowane wskaźniki Y 1 X 2 p p1 • int *p1=NULL;// błąd czasu wykonania int Y = 1, X = 2; int *p = &X; • int *p1; • *p1 = 3;
Wskaźnik vs. wskazanie Y 1 2 X p1 2 p2 int Y = 1, X = 2; int *p1 = &Y, *p2 = &X ; • *p1 = *p2; • p1 = p2;
Tablice i wskaźniki w C++ 1 7 2 4 8 11 7 2 const int MAX = 12; int Array[MAX] = {1,7,2,4,8,11,7,2}; int *p = Array; • p++;
Arytmetyka wskaźników w C++ int Array[100]; int *Ptr; Array[10] = 3; Ptr = Array + 10; // wskazanie na 10 (11)- //element tablicy Ptr = & Array[10]; // j.w. *Ptr = 3; *(Ptr-3) = 5; // to samo co Ptr[-3] = 5; // UWAGA Ptr[-3] musi byc w obrebie tablicy Ptr-Array = = 10 // Odejmowanie ma sens dla jednej tablicy
Dynamiczna alokacja pamięci int *Ptr = new int[100]; // wymagane delete Ptr; Ptr[1] = 10; Ptr[100] = 10; // blad naruszenie zakresu ++Ptr; // potencjalny problem przy zwalnianiu int *Ptr1 = Ptr; Ptr1++; delete Ptr; // zwolnienie pamieci Ptr = NULL; // zaznaczenie wskaznika jako pusty
Troche przykładów const int MAX=100; int Array[MAX], *Ptr; for (i=0; i<MAX; i++) Array[i] = i; for (i=0, Ptr=Array; i<MAX; i++, Ptr++) *Ptr = i; for (Ptr=Array; Ptr<Array+MAX; Ptr++) *Ptr = 0; for (Ptr=Array+MAX-1; Ptr>=Array; Ptr--) *Ptr = 0;
Typy wskaźników int I, *pInt= &I; long L, *pLong = &L; I = L; // OK *pInt = *pLong; // OK pInt = pLong; // blad rozne typy pInt = I; // bez sensu long ** ppLong; // czasem tak trzeba … ppLong = &pLong; // Ok **ppLong = 10; // L = 10; pLong = pInt; // blad rozne typy
Wskaźniki i referencje int y=0, x=0, *ptr = &x, &ref = x; *ptr = 3; // x = 3; ref = 3; // x = 3; ++ptr; // przesuniecie wskaznika (tutaj bez sensu) ++ref; // ++x; ptr = &x; // ref = x oznaczaloby x = x; *ptr = y; // x = y; ptr = &y; // od tej pory wskazujemy na y ref = y; // x = y; const int & ref = x;// umozliwia tylko odczyt int & ref; // blad, niezainicjowana referencja nie ma sensu
Stałe wskaźniki i wskaźniki do stałych int Array[100]; int *Ptr = Array; int *const cPtr = Array; // takie same wlasciwosci jak Array const int*PtrToC = Array; const int*const cPtrToC Array; *(Ptr ++) = 1; // mozna wszystko cPtr++; // blad *cPtr = 1; // ok, nie mozna tylko zmieniac wskaznika *(cPtr+3) = 1; // ok, nie mozna tylko zmieniac wskaznika cPtr[3] = 1; // ok, nie mozna tylko zmieniac wskaznika *PtrToC = 1; // blad x = *(PtrToC++); // ok, przez wskaznik mozna tylko czytac x = = PtrToC[3]; // ok, przez wskaznik mozna tylko czytac x = *(cPtrToC+5); // ok, czytamy i nie zmieniamy wskaznika
Przekazywanie parametru void fun(int y) { } int X = 2; fun(X); 2 X Fun y 2 5 y = 5;
Przekazywanie wskaźnika void fun(int * pInt) { // partametr - wskaźnik } void fun(int ArrayInt[]) {// partametr – tablica } int A[10] = {2}; fun(A); 2 5 A Fun pInt *pInt = 5; pInt++;
Przekazywanie wskaźnika do wskaźnika • int *pInt = A; • fun(&pInt); pInt ppInt void fun(int ** ppInt) { // mozliwosc zmiany wskaznika } int A[10] = {2}; 2 A 5 Fun **ppInt = 5; (*ppInt)++; *(ppInt++);
Przekazywanie referencji do wskaźnika • int *pInt = A; • fun(pInt); pInt refPInt void fun(int * &refPInt) { // mozliwosc zmiany wskaznika } int A[10] = {2}; 2 A 5 Fun * refPInt = 5; refPInt ++;
Zwrot wskaźnika • int *pInt = A+1; pInt int*fun(int * pIntL) { // wskaznik zwracany jako wynik } int A[10] = {7,2}; 7 2 A 5 • pInt = fun(pInt); // pInt = fun(A+1); Fun *pIntL = 5; pIntL pIntL++; return pIntL;
Zestawienie metod void fun(int x); // zwykły parametr void fun(int * x); // partametr - wskaźnik void fun(int array[]); // partametr - tablica int * fun(int * x); // wskaznik zwracany jako wynik void fun(int ** x); // mozliwosc zmiany wskaznika int fun(int *&x); // mozliwosc zmiany wskaznika typedef int *intPtr; // to samo z oddzielnym typem int fun(intPtr &x);
Podsumowanie void fun(int x); // nie można zmienić x void fun(int * x); // nie można zmienić wskaźnika void fun(int Array[]); // partametr - tablica int * fun(int * x); // funkcja zwraca zmieniony // wskaznik long fun(int ** x); // nieco niewygodne int fun(int *&x); // F. moze zmienic argument fun(pInt); // Problem:z wywołania niewyni- // ka, że f. moze zmienic argument
Typowe błędy //niezainicjowany wskaznik int *ptr; *ptr = 1; // potencjalny upadek systemu //niewazny wskaznik (podwojne zwolnienie); int *ptr1,*ptr2; ptr1 = ptr2 = new int[100]; delete ptr1[]; ptr1=NULL; *ptr2 = 5; // potencjalny upadek systemu delete ptr2; // przerwanie programu //wyciek pamieci ptr1 = new int[10]; ptr2 = new int[100]; ptr1 = ptr2; // stracona tablica int[10]
Wskaźniki do funkcji void fun(int x); void (*wskfun)(int x); // formy rownoważne wskfun = &fun; wskfun = fun; // formy rownoważne fun(5); (*wskfun)(5); wskfun(5); gdzie zysk ?
Co to za wskaznik? int (*wskfun)(int x); double (*wskfun)(int x, float y); int * (*wskfun)(int *); int * (*wskFunTab[10])(int * t[]); wskFunTab[3] = myFun1; int *tab[5]; int * wyn = wskfun[3](tab);
typedef do pomocy int * (*wskfun[10])(int * t[]); typedef int * (*WSKFUNCTYPE)(int * t[]); WSKFUNCTYPE wskfuntab[10]; int *tab[5]; int * wyn = wskfuntab[3](tab);
Tradycyjny sort void sort (int a[], int cnt) { ... for(...) if (a[i]>=a[j]) ... } lub void sort (Samochod a[], int cnt); { ... for(...) if (wiekszy(a[i], a[j]) ) ... } Problem: chcemy uzyskać rózne porządki sortowania BEZ POWIELANIA algorytmu sort
Sort z różnymi porządkami enum TypSortow { rosnaco, malejaco }; void sort (int a[], int cnt, TypSortow jak); { ... for(...){ ... bool zamien = false; switch(jak){ case rosnaco : if (a[i]>=a[j]) zamien = true; break; case rosnaco : if (a[i]<a[j]) zamien = true; break; } ... } } // NB. zamiast if (a[i]>=a[j]) zamien = true; // można zamien = a[i]>=a[j]; // czy jest róznica?
Przykład zastosowania wskaźników do funkcji typedef bool(*CMP_INT_FUN)(int , int); void sort (int a[], int cnt, CMP_INT_FUN cmp); { ... for(...){ ... if (cmp(a[i], a[j]) ) ... } } bool wiekszy(int e1, int e2) { return e1>=e2; }) bool mniejszy(int e1, int e2) { return e1<e2; }) sort(A, MAX, wiekszy);