Wskaźniki repetytorium
description
Transcript of Wskaźniki repetytorium
Wskaźniki repetytoriumWskaźniki repetytorium
WskaźnikiWskaźniki
int Y = 1, X = 2;
X = 5;
int *p = &X;
1
2 5
Y
X
p
44
p = &Y;
*p = 4;
5
NiezainicjowaneNiezainicjowane wskaźniki wskaźniki
int Y = 1, X = 2;
int *p = &X;
1
2
Y
X
p
int *p1;p1
*p1 = 3;
int *p1=NULL;
// błąd czasu wykonania
Wskaźnik vsWskaźnik vs.. wskazanie wskazanie
int Y = 1, X = 2;
int *p1 = &Y, *p2 = &X ;
*p1 = *p2;
1
2
Y
X
p2
p1
2
p1 = p2;
Tablice i wskaźniki w C++Tablice i wskaźniki w C++
const int MAX = 12;
int Array[MAX] = {1,7,2,4,8,11,7,2};
int *p = Array;
17248
1172
p++;
Arytmetyka wskaźników w C++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ęciDynamiczna alokacja pamięciint *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ówTroche przykładówconst 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ówTypy wskaźnikówint 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 referencjeWskaźniki i referencjeint 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 yref = y; // x = y;
const int & ref = x; // umozliwia tylko odczytint & ref; // blad, niezainicjowana referencja nie ma sensu
Stałe wskaźniki i Stałe wskaźniki i wskaźniki do stałychwskaź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
2
Przekazywanie parametruPrzekazywanie parametruvoid fun(int y) {
}
int X = 2;
fun(X);
Fun
X
y
y = 5;
5
2
Przekazywanie wskaźnikaPrzekazywanie wskaźnikavoid fun(int * pInt) { // partametr - wskaźnik
}
void fun(int ArrayInt[]) { // partametr – tablica
}
int A[10] = {2};
fun(A);
Fun
A
pInt
*pInt = 5;
25
pInt++;
Przekazywanie wskaźnika Przekazywanie wskaźnika do wskaźnikado wskaźnika
void fun(int ** ppInt) { // mozliwosc zmiany wskaznika}
int A[10] = {2};
Fun
A
**ppInt = 5;
25
(*ppInt)++; *(ppInt++);
pIntint *pInt = A;
ppInt
fun(&pInt);
Przekazywanie referencji Przekazywanie referencji do wskaźnikado wskaźnika
void fun(int * &refPInt) { // mozliwosc zmiany wskaznika}
int A[10] = {2};
Fun
A
* refPInt = 5;
25
refPInt ++;
pIntint *pInt = A;
refPInt
fun(pInt);
Zwrot wskaźnikaZwrot wskaźnikaint*fun(int * pIntL) { // wskaznik zwracany jako wynik}
int A[10] = {7,2};
Fun
A
*pIntL = 5;
25
pIntL++;
pIntint *pInt = A+1;
pIntL
pInt = fun(pInt); // pInt = fun(A+1);
7
return pIntL;
Zestawienie metodZestawienie metodvoid 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);
PodsumowaniePodsumowanievoid 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 nie wyni-
// ka, że f. moze zmienic argument
Typowe błędyTypowe błędy//niezainicjowany wskaznikint *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 systemudelete ptr2; // przerwanie programu
//wyciek pamieciptr1 = new int[10];ptr2 = new int[100];ptr1 = ptr2; // stracona tablica int[10]
Wskaźniki do funkcjiWskaźniki do funkcjivoid fun(int x);
void (*wskfun)(int x);
// formy rownoważnewskfun = &fun;wskfun = fun;
// formy rownoważnefun(5);(*wskfun)(5);wskfun(5);
gdzie zysk ?
Co to za wskaznik?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 pomocytypedef do pomocyint * (*wskfun[10])(int * t[]);
typedef int * (*WSKFUNCTYPE)(int * t[]);
WSKFUNCTYPE wskfuntab[10];
int *tab[5];int * wyn = wskfuntab[3](tab);
Tradycyjny sortTradycyjny sortvoid 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ądkamiSort z różnymi porządkamienum 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 Przykład zastosowania wskaźników do funkcjiwskaźników do funkcjitypedef 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);