Wskaźniki
Wskaźniki
repetytorium
repetytorium
Wskaźniki
Wskaźniki
int Y = 1, X = 2;
X = 5;
int *p = &X;
1
2
5
Y
X
p
4
4
p = &Y;
*p = 4;
5
Niezainicjowane
Niezainicjowane
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 vs
Wskaź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;
1
7
2
4
8
11
7
2
p++;
Arytmetyka wskaźników w
Arytmetyka wskaźników w
C++
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
Dynamiczna alokacja
pamięci
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
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
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
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
Stałe wskaźniki i
wskaźniki do stałych
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
2
Przekazywanie parametru
Przekazywanie parametru
void fun(int y) {
}
int X = 2;
fun(X);
Fun
X
y
y = 5;
5
2
Przekazywanie wskaźnika
Przekazywanie wskaźnika
void fun(int * pInt) {
// partametr -
wskaźnik
}
void fun(int ArrayInt[]) {
// partametr –
tablica
}
int A[10] = {2};
fun(A);
Fun
A
pInt
*pInt = 5;
2
5
pInt++;
Przekazywanie wskaźnika
Przekazywanie wskaźnika
do wskaźnika
do wskaźnika
void fun(int ** ppInt) { // mozliwosc zmiany wskaznika
}
int A[10] = {2};
Fun
A
**ppInt = 5;
2
5
(*ppInt)++;
*(ppInt++);
pInt
int *pInt =
A;
ppInt
fun(&pInt);
Przekazywanie referencji
Przekazywanie referencji
do wskaźnika
do wskaźnika
void fun(int * &refPInt) { // mozliwosc zmiany wskaznika
}
int A[10] = {2};
Fun
A
* refPInt = 5;
2
5
refPInt ++;
pInt
int *pInt =
A;
refPInt
fun(pInt);
Zwrot wskaźnika
Zwrot wskaźnika
int*fun(int * pIntL) { // wskaznik zwracany jako wynik
}
int A[10] = {7,2};
Fun
A
*pIntL = 5;
2
5
pIntL++;
pInt
int *pInt =
A+1;
pIntL
pInt = fun(pInt); // pInt = fun(A+1);
7
return pIntL;
Zestawienie metod
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
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 nie wyni-
// ka, że f. moze zmienic argument
Typowe błędy
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
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?
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
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
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
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
Przykład zastosowania
wskaźników do funkcji
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);