background image

1

W

YKŁAD

4 T

ABLICE I WSKAŹNIKI

DR  INŻ.  

M

AŁGORZATA 

J

ANKOWSKA

2

M

.  

J

ANKOWSKA  –

W

YKŁAD

4 T

ABLICE I WSKAŹNIKI

ARYTMETYKA  WSKAŹNIKÓW

Wskaźniki możemy używać jako operandy z następującymi operatorami:
• dodawania (+) i odejmowania (-) liczb całkowitych (możliwe jest również odjęcie od 

siebie dwóch wskaźników),

• przypisania (=),
• przypisania wraz dodaniem/odjęciem liczby całkowitej (+=, -=),
• porównania (<, >, <=, >=, ==, !=),
• inkrementacji (++) oraz dekrementacji (--).

 W języku C++ istnieje ścisły związek między wskaźnikami a tablicami. Mogą

być one dzięki temu wykorzystywane zamiennie.

 Wskaźniki mogą być wykorzystane do wykonania dowolnej operacji, która działa 

na indeksach elementów tablicy.

 Nazwa tablicy (bez indeksu) jest wskaźnikiem do pierwszego elementu 

tablicy.

UWAGI

 Arytmetyka operacji na wskaźnikach zawsze bierze pod uwagę rozmiar 

wskazywanego typu. Zakłada się, że wskaźnik jest adresem pierwszego 
elementu tablicy składającej się z elementów tego właśnie typu.

background image

3

M

.  

J

ANKOWSKA  –

W

YKŁAD

4 T

ABLICE I WSKAŹNIKI

PRZYKŁAD 

/* ... */
int A[6] = {0,1,2,3,4,5};
int * pA = A;

/* ... */
int A[6] = {0,1,2,3,4,5};
int * pA = &A[0];

lub

Deklaracja wskaźnika pA do wartości typu 
int połączona z inicjacją adresem 
pierwszego elementu tablicy 
może być
wykonana na dwa równoważne sposoby:
• przy wykorzystaniu nazwy tablicy A –
nazwa tablicy jest adresem pierwszego 
elementu tablicy,
• pobierając adres (operator &) pierwszego 
elementu tablicy A, czyli elementu A[0];

A[0] 

0

A[1] 

1

A[2] 

2

A[3] 

3

A[4] 

4

A[5] 

5

2000

2004

2008

2012

2016

2020

4

położenie w pamięci

elementy tablicy

2000

pA

zmienna wskaźnikowa pA
wskazuje na element A[0] 
tablicy znajdujący się
pod adresem 2000

W języku C/C++ tablica zajmuje ciągły obszar pamięci o rozmiarze, który wystarcza 
do przechowania wszystkich jej elementów. 

UWAGA 1

4

M

.  

J

ANKOWSKA  –

W

YKŁAD

4 T

ABLICE I WSKAŹNIKI

Rezultat operacji arytmetycznych wykonywanych na wskaźnikach zależy od 
rozmiaru obiektu na który na wskaźnik wskazuje. 

Dodanie/odjęcie liczby całkowitej do/od wskaźnika powoduje przesunięcie go o n

elementów tablicy do przodu/wstecz (tj. w kierunku rosnących/malejących indeksów 
lub za tablicę).
Wykonanie wspomnianych operacji dodawania/odejmowania powoduje przesuniecie 
wskaźnika o:

* sizeof(typ-wskazywany)

bajtów.

UWAGA  2 – REZULTAT  OPERACJI  ARYTMETYCZNYCH

Zmienne wskaźnikowe mogą być od siebie odejmowane.
W przypadku, gdy odejmujemy od siebie zmienne wskaźnikowe wskazujące na 
różne elementy tej samej tablicy w wyniku dostaniemy liczbę elementów znajdują-
cych się pomiędzy nimi (a nie liczbę bajtów).

Wynikiem może być oczywiście liczba ujemna!

UWAGA  3 – ODEJMOWANIE  ZMIENNYCH  WSKAŹNIKOWYCH

background image

5

M

.  

J

ANKOWSKA  –

W

YKŁAD

4 T

ABLICE I WSKAŹNIKI

PRZYKŁAD – REZULTAT  OPERACJI  ARYTMETYCZNYCH

/* ... */
int A[6] = {0,1,2,3,4,5};

// Krok 1
int * pA1 = &A[0];
int * pA2 = pA1;

// Krok 2
pA1++;
pA2 += 3; 

A[0] 

0

A[1] 

1

A[2] 

2

A[3] 

3

A[4] 

4

A[5] 

5

2000

2004

2008

2012

2016

2020

4

położenie w pamięci

elementy tablicy

zmienne wskaźnikowe
pA1 oraz pA2 
wskazują na element A[0] 
tablicy znajdujący się
pod adresem 2000

2000

pA1

2000

pA2

KROK 1

6

M

.  

J

ANKOWSKA  –

W

YKŁAD

4 T

ABLICE I WSKAŹNIKI

PRZYKŁAD – REZULTAT  OPERACJI  ARYTMETYCZNYCH

/* ... */
int A[6] = {0,1,2,3,4,5};

// Krok 1
int * pA1 = &A[0];
int * pA2 = pA1;

// Krok 2
pA1++;
pA2 += 3; 

A[0] 

0

A[1] 

1

A[2] 

2

A[3] 

3

A[4] 

4

A[5] 

5

2000

2004

2008

2012

2016

2020

4

położenie w pamięci

elementy tablicy

zmienna wskaźnikowa pA1 
wskazuje na element A[1] tablicy 
znajdujący się pod adresem 2004

zmienna wskaźnikowa pA2
wskazuje na element A[3] tablicy 
znajdujący się pod adresem 2012

2004

pA1

Wynikiem działania jest wartość 2000 + 4 = 2004;
liczba 2000 zostaje powiększona o rozmiar wskaźnika
(w przypadku liczb typu int rozmiar zazwyczaj wynosi 4).

Wynikiem działania jest wartość 2000 + 3*4 = 2012.

KROK 2

2012

pA2

background image

7

M

.  

J

ANKOWSKA  –

W

YKŁAD

4 T

ABLICE I WSKAŹNIKI

PRZYKŁAD – ODEJMOWANIE  ZMIENNYCH  WSKAŹNIKOWYCH

/* ... */
int A[6] = {0,1,2,3,4,5};

int * pA1 = &A[1];
int * pA2 = &A[5];

int x = pA2 – pA1;

A[0] 

0

A[1] 

1

A[2] 

2

A[3] 

3

A[4] 

4

A[5] 

5

2000

2004

2008

2012

2016

2020

4

2020

pA2

2004

pA1

położenie w pamięci

elementy tablicy

zmienna wskaźnikowa pA1
wskazuje na element A[1] tablicy 
znajdujący się pod adresem 2004

zmienna wskaźnikowa pA2 
wskazuje na element A[5] tablicy 
znajdujący się pod adresem 2020

Wynikiem działania nie jest liczba bajtów, 
tj. wartość 2020 – 2004 = 16.

Wykonując odejmowanie wskaźników wskazujących na 
elementy tej samej tablicy, np. pA2 - pA1 dostaniemy 
liczbę elementów znajdujących się pomiędzy nimi; 
w danym przypadku x = 4.

8

M

.  

J

ANKOWSKA  –

W

YKŁAD

4 T

ABLICE I WSKAŹNIKI

ZWIĄZEK MIĘDZY WSKAŹNIKAMI A TABLICAMI

Wiemy już, że istnieje ścisły związek między wskaźnikami i tablicami, gdyż:
• w języku C/C++ tablica zajmuje ciągły obszar pamięci o rozmiarze, który wystarcza 

do przechowania wszystkich jej elementów,

• nazwa tablicy (bez indeksu) może być traktowana jako wskaźnik do jej pierwszego 

elementu.

Tak więc wskaźniki mogą być wykorzystane do wykonania dowolnej operacji, 
działającej na indeksach elementów tablicy.

PRZYKŁAD  1 – DZIAŁANIA  NA  TABLICY  
Z  WYKORZYSTANIEM  
NOTACJI  INDEKSOWEJ

/* ... */
int A[6];

for (int i=0; i<=5; i++)

A[i] = i;

PRZYKŁAD  2 – DZIAŁANIA  NA  TABLICY  
Z  WYKORZYSTANIEM  
NOTACJI  INDEKSOWANIA WSKA
ŹNIKA

/* ... */
int A[6];
int * pA = A;

for (int i=0; i<=5; i++)

pA[i] = i;

Wskaźnik do pierwszego elementu tablicy (tak samo jak nazwa tablicy) może być
wykorzystany z indeksami poszczególnych elementów. Na przykład wyrażenie pA[3] określa 
element o indeksie 3, podobnie jak A[3].

background image

9

M

.  

J

ANKOWSKA  –

W

YKŁAD

4 T

ABLICE I WSKAŹNIKI

PRZYKŁAD  3 – DZIAŁANIA  NA  TABLICY  
Z  WYKORZYSTANIEM  
NOTACJI  WSKA
ŹNIK/PRZESUNIĘCIE

(JAKO WSKAŹNIK WYKORZYSTYWANA 
JEST NAZWA TABLICY)

/* ... */
int A[6];

for (int i=0; i<=5; i++)

*(A + i) = i;

PRZYKŁAD  4 – DZIAŁANIA  NA  TABLICY  
Z  WYKORZYSTANIEM  
NOTACJI  WSKA
ŹNIK/PRZESUNIĘCIE

/* ... */
int A[6];
int * pA = A;

for (int i=0; i<=5; i++)

*(pA + i) = i;

Nazwa tablicy jest wskaźnikiem do 
jej pierwszego elementu.
Dodając liczbę całkowitą (tzw. 
przesunięcie (ang. offset) względem 
wskaźnika) do wskaźnika ustalamy, 
który element tablicy ma być
referowany (a dokładnie wartość
adresu elementu tablicy, który ma 
być referowany) 
przy pomocy operatora *.

Zapamiętując adres pierwszego 
elementu tablicy w zmiennej 
wskaźnikowej pA możemy postępować
podobnie jak w Przykładzie 3.