Temat: Wskaźniki - definicja, arytmetyka wskaźników, dostęp

Transkrypt

Temat: Wskaźniki - definicja, arytmetyka wskaźników, dostęp
Temat: Wska niki - definicja, arytmetyka wska ników,
dost p wska nikowy do elementów tablicy
jednowymiarowej.
1. Deklaracja zmiennych typu wska nikowego
Wska nik to zmienna, która zawiera adres pocz tku (pierwszego baju)
dowolnego obszaru w pami ci operacyjnej komputera. Pod takim adresem
(wska nikiem )mog si znajdowa dane programu b d kod programu. Na
razie b dziemy si zajmowali tylko tak sytuacj , kiedy pod wska nikiem
zapami tany jest obszar danych.
Deklaracja wska nika
typ_danych ∗ nazwa_wska nika;
Przykład 1
∗ wskaznik;
int
double ∗ wsk_liczby;
char
∗ wsk_znaku;
// wska nik na warto
// wska nik na warto
// wska nik na znak
całkowit
rzeczywist
Deklaracja wska nika anonimowego
void ∗ nazwa_wska nika;
Wska nik anonimowy to wska nik na „dowolny” ci g bajtów danych.
Niezale nie od tego, jakiego typu dane znajduje si aktualnie we
wskazywanym obszarze pami ci, wka nik anonimowy mo e pokazywa na
ten obszar.
1
2. Operatory zwi zane z typem wska nikowym
&-
operator referencji, zwraca adres zmiennej podanej po prawej stronie
tego operatora
*-
operator dereferencji, zwracaj cy dane wskazywane przez wska nik
podany po prawej stronie tego operatora
Przykład 2
int liczba=2;
int ∗wsk ; // deklaracja zmiennej typu wska nikowego, która mo e
// pokazywa na obszar, w którym znajduje si liczba
// całkowita
???
2
wsk
liczba
stos zmiennych
wsk = &liczba; // przypisanie zmiennej wsk adresu zmiennej liczba
wsk
2
liczba
stos zmiennych
2
∗wsk = 10;
// przypisanie warto ci 10 do obszaru
// pami ci pokazywanego przez wska nik
// wsk, a tym samym do zmiennej liczba
wsk
10
liczba
stos zmiennych
3
3. Arytmetyka wska ników
Operatory, które mog by u yte dla typu wska nikowego:
a) operatory przypisania: =, +=, -=
wsk2 = wsk1;
// przypisanie adresowi wks2 wska nika wsk1
wsk+=n; //wsk=wsk+n; // wsk „przesuwa si ” w prawo o n*sizeof(typ_wskazywany)
bajtów
wsk-=n;wsk=wsk-n
// wsk „przesuwa si ” w lewo o n*sizeof(typ_wskazywany)
bajtów
Uwaga !!! Operatory: +=, -= nie mog by u yte dla wska ników anonimowych
Przykład 3
Zakładamy, e jedna zmienna typu int zajmuje dwa bajty.
int *wsk1, *wsk2, *wsk3, x=2;
wsk1=&x; wsk2=wsk1; wsk2+=3; wsk3=wsk2; wsk3-=2;
wsk1
wsk3
wsk2
↓
↓
↓
kolejne bajty pami ci
↑
pierwszy bajt zmiennej x
b) operatory porównania: ==, !=, <, >, >=, <=
wsk1 == wsk2
wsk1 < wsk2
// sprawdzenie czy zmienne zawieraj te same adresy
// sprawdzenie czy zmienna wsk1 zawiera adres mniejszy
// (wcze niejszy) od adresu zawartego w zmiennej wsk2
wsk1 <= wsk2
// równowa ne: !(wsk1>wsk2)
wsk1 > wsk2
// sprawdzenie czy zmienna wsk1 zawiera adres wi kszy
// (pó niejszy) od adresu zawartego w zmiennej wsk2
wsk1 >= wsk2
// równowa ne: !(wsk1<wsk2)
wsk1 != wsk2
// sprawdzenie czy zmienne zawieraj ró ne adresy
4
Przykład 4
Dla ko cowych ustawie adresów wsk1, wsk2 , wsk3 z Przykład 3 prawdziwe s
nast puj ce warunki: wsk1<wsk2, wsk1!=wsk2, wsk1<=wsk3, !(wsk1==wsk3)
c) operatory dekrementacji oraz inkrementacji: ++, ---// przesuni cie adresu o jedn porcj typu_wskazywanego w prawo
wsk++;
wsk--;
// przesuni cie adresu o jedn porcj typu_wskazywanego w lewo
Operatory ++ i – mog by u yte w wersji postfiksowej i prefiksowej i działaj w tych
wersjach analogicznie jak operatory arytmetyczne.
d) operator odejmowania i dodawania liczby całkowitej do zmiennej
wska nikowej: +, wsk+n;
// wsk+n ma warto
adresu, który jest „przesuni ty” w prawo o
// n*sizeof(typ_wskazywany) bajtów w stosunku do adresu wsk
wsk-n;
// wsk-n ma warto
adresu, który jest „przesuni ty” w lewo o
// n*sizeof(typ_wskazywany) bajtów w stosunku do adresu wsk
Uwaga !!! Operatory: +, - nie mog by u yte dla wska ników anonimowych
Przykład 5
Zakładamy, e jedna zmienna typu int zajmuje dwa bajty.
int *wsk1, *wsk2, *wsk3, x=2;
wsk1=&x; wsk2=wsk1+3; wsk3=wsk2-2;
wsk1
wsk3
wsk2
↓
↓
↓
kolejne bajty pami ci
↑
pierwszy bajt zmiennej x
5
e) odejmowania wska ników tego samego typu
wsk1-wsk2
//wyznaczenie „odległo ci” pomi dzy dwoma adresami w pami ci,
//odległo ci w jednostach sizeof ( typ_wskazywany )
Przykład 6
Zakładamy, e jedna zmienna typu int zajmuje dwa bajty.
int *wsk1, *wsk2, *wsk3, x=2;
wsk1=&x; wsk2=wsk1+3; wsk3=wsk2-2;
wsk1
wsk3
wsk2
↓
↓
↓
kolejne bajty pami ci
↑
pierwszy bajt zmiennej x
Prawdziwe warunki:
wsk2-wsk1==3 , wsk3-wsk1==1
Przykład 7
Zakłamy, e jedna warto typu int zajmuje dwa bajty, jedna warto
bajty, a jedna zmienna wska nikowa dwa bajty.
typu float cztery
Int a, b, c;
float x ;
int *wsk;
Zmienne
a
Bajty pami ci
b
C
x
wsk
90
wsk
printf(" \n Adres zmiennej a = %u " , (unsigned) &a ) ;
wsk=&a;
printf(" \n Warto adresu wsk = %u " , (unsigned) &wsk) ;
b=10;
wsk = &b;
∗wsk = 20;
wsk = &a;
∗(wsk+1) = 30;
∗(&a + 1) = 40;
∗(&c − 1) = 50;
∗( (int∗)&x − 2) = 60;
∗(int∗)( &x − 1) = 70;
∗((int∗)&wsk − 4) = 80;
6
∗(int∗) (&wsk − 4) = 90;
4. Dost p wska nikowy do elementów tablicy jednowymiarowej
Nazwa tablicy jest jednocze nie adresem jej pierwszego elementu.
Przykład 8
int T[100];
int *wsk=T;
int *wsk1=&T[0];
wsk1
T+4
T+8
↓
↓
wsk
↓
T:
indeksy
0
1
2
3
4
5
6
7
8
9
...
...
...
jedna kratka, to jedna komórka tablicy T
7
Przykład 9
Dost p wska nikowy do elementów tablicy
// dost p indeksowy
int tab[ 20],i;
for( i = 0; i < 20; i++ )
{
scanf( ”%d”, &tab[ i ] );
tab[ i ] = 2 ∗ tab[ i ];
printf( ”Tab[ %d ] = %d \n”, i+1 , tab[ i ] );
}
// dost p wska nikowy – wersja I
int ∗wsk,tab[20];
for( wsk=tab; wsk < tab + 20; wsk++ )
{
scanf( ”%d”, wsk );
∗wsk ∗= 2;
printf( ”Tab[ %d ] = %d \n”, wsk−tab+1 , ∗wsk );
}
// dost p wska nikowy – wersja II
int ∗wsk,tab[20],i;
for( i= 0; i < 20; i++ )
{
scanf( ”%d”, tab + i );
∗(tab+i) = 2 ∗ ∗(tab+i);
printf( ”Tab[ %d ] = %d \n”, i+1 , ∗(tab+i) );
}
// dost p wska nikowy – wersja III
int ∗wsk,T[20],i;
for( i=0, wsk=tab; i < 20; i++, wsk++ )
{
scanf( ”%d”, wsk );
∗wsk = 2∗∗wsk;
printf( ”Tab[ %d ] = %d \n”, i+1 , ∗wsk );
}
8