c++ wykłady, Wyc 5

background image

Wskaźniki

Wskaźniki

background image

Definiowanie wskaźników

Wskaźnik

może wskazywać na obiekt

dowolnego

typu.

int

* w;

char

* Wsk_Znak;

float

* Wskaz_Real;

Przykłady:

Wskaźnik

przechowuje

adres

obiektu

wskazanego typu.

Wskaźnik

służący do pokazywania obiektów

jednego typu nie nadaje się do pokazywania
obiektów innego typu.

background image

Praca ze wskaźnikiem

Do

nadania

wskaźnikowi

wartości

początkowej służy jednoargumentowy
operator

&

.

Oblicza on adres obiektu, który stoi po

prawej stronie operatora przypisania.

Przykład:

int

* w;

// definicja wskaźnika do obiektów
//typu

int

int

k = 10;

// definicja i inicjalizacja

zwykłego

//obiektu

typu

int

w =

&

k;

// ustawienie wskaźnika na

obiekt

k

cout

<<

* w;

// wypisanie zawartości

obiektu

* w

background image

Praca ze wskaźnikiem

#include <iostream.h>
#include <conio.h>

void main

()

{
int

zmienna = 8, druga = 4;

int

*wskaznik;

clrscr ();
wskaznik = &zmienna;

// ustawienie

//

wskaźnika na

zmienna

cout

<<

"

zmienna =

"

<<

zmienna

<<

"

\n a odczytana przez wskaźnik =

"

<<

* wskaznik

<<

endl

;

cdn

.

background image

zmienna = 10;
cout

<<

"

zmienna =

"

<<

zmienna

<<

"

\n a odczytana przez wskaźnik =

"

<<

* wskaznik

<<

endl

;

* wskaznik = 200;
cout

<<

"

zmienna =

"

<<

zmienna

<<

"

\n a odczytana przez wskaźnik =

"

<<

* wskaznik

<<

endl

;

wskaznik = &druga;
cout

<<

"

zmienna =

"

<<

zmienna

<<

"

\n a odczytana przez wskaźnik =

"

<<

* wskaznik

<<

endl

;

}

background image

Uwagi:

Do danego obiektu

można odnosić się na dwa

sposoby

:

Operacja odniesienia się

*

do danego obiektu

może być zarówno po prawej, jak i po lewej
stronie operatora przypisania, np.:

przez jego

nazwę

przez

zorganizowanie wskaźnika

, który

będzie na ten obiekt pokazywał.

a =

* Wskaznik

;

* Wskaznik

= 100 +

a;

background image

Wskaźnik typu

void:

Wskaźnik

jest to adres miejsca w pamięci plus

informacja o tym, jakiego typu obiekt się
pokazuje.

Można jednak zdefiniować wskaźnik bez tej
wiedzy:

void

* Wsk;

gdzie

* Wsk

jest wskaźnikiem dowolnego

typu

void

.

background image

Przykład

:

int

* wi1, * wi2;

float

* wf;

wi1 = wi2;
wf = wi1;

//

błąd

wf = (

float

*) wi1;

void

* wv;

char

* wch;

int

* wi;

float

* wf;

wv = wf;
wv = wch;
wv = wi;

background image

Uwagi:

Wskaźnik każdego niestałego typu można

przypisać wskaźnikowi typu

void

;

Wskaźnika typu

void

nie można przypisać

wskaźnikowi “prawdziwemu”.

Trzeba w takich przypadkach posłużyć się

operatorem rzutowania:

wf = (

float

*) wv;

wi = (

int

*) wv;

wch = (

char

*) wv;

background image

Podstawowe zastosowanie

wskaźników:

wskaźniki do tablic

umożliwiające ulepszenie

pracy z tablicami;

funkcje

zmieniające wartości przesyłanych do

nich argumentów;

rezerwacja obszarów pamięci

.

background image

Wskaźniki do tablic

Nazwa tablicy jest równoważna
(prawie...) wskaźnikowi do jej
pierwszego elementu

const int MAX = 20;
int

*Wsk;//

definicja wskaźnika na

obiekty typu

int

int

Tab[MAX];

Wsk = Tab;

lub

Wsk = &Tab[0];

background image

Wskaźniki do tablic

int

*Wsk;

// definicja wskaźnika na

obiekty typu

int

int

Tab[20];

// definicja tablicy typu

int

Wsk =

&

Tab [i];

// ustawienie wskaźnika na

i

-ty

element

//tablicy

Tab

Wsk =

&

Tab [0];

// inaczej:

Wsk = Tab;

Wsk = Wsk + 1;

// inaczej:

Wsk ++;

Wsk += n;

// inaczej:

Wsk =

Wsk + n;

background image

Dwie poniższe instrukcje są

równoważne:

Wsk = &Tab[0];

Wsk = Tab;

Dwa poniższe zapisy są także

równoważne:

Tab + 4

&Tab [4];

Jeśli

Wsk = Tab

, to:

Wsk++;

Tab++; // BŁĄD

Nazwa tablicy

jest

stałym wskaźnikiem

do niej

samej!

Tab[5]

*(Tab + 5) //zapisy

równoważne

background image

Wskaźniki

tablic

można

od

siebie

odejmować

.

Odjęcie od siebie dwóch wskaźników

pokazujących na różne elementy tej samej
tablicy daje w wyniku liczbę dzielących je
elementów tablicy.

Liczba ta może być dodatnia lub ujemna.

Wskaźniki można też ze sobą porównywać za
pomocą operatorów relacji.

background image

Przesyłanie tablic do funkcji:

Do funkcji przesyłamy adres tablicy, np.:

void

fun (

int

tab [ ] );

Odbieramy tablicę z funkcji na dwa
sposoby:

jako tablicę

jako wskaźnik

background image

Wskaźnik do obiektu

const

Jeśli funkcja otrzymuje adres tablicy, to pracuje
w tym przypadku na oryginale tablicy i może
dowolnie zmieniać wartości jej elementów.

Jeśli nie chcemy, aby funkcja te wartości

zmieniała, to należy posłużyć się

wskaźnikiem do stałego obiektu

.

Taki wskaźnik wskazuje na obiekty, ale nie

pozwala na ich modyfikację.

background image

Stałe wskaźniki:

Dotychczas mówiliśmy o wskaźnikach do

obiektów stałych

.

Są to wskaźniki, które

nie mogą zmieniać

pokazywanego obiektu

. Traktują go jako

obiekt stały.

Sam obiekt, na który pokazują nie musi

być rzeczywiście stały.

Ważne jest to, że wskaźnik tak go

traktuje.

Są jeszcze inne wskaźniki z przydomkiem

const

, które nazywamy

wskaźnikami stałymi.

int

Dworzec;

int

*

const

Wsk = & Dworzec;

background image

Stałe wskaźniki, a wskaźniki do

stałych:

Stały wskaźnik

to taki, który zawsze

pokazuje to samo. Nie można nim
poruszać.

Wskaźnik do stałego obiektu

, to taki

wskaźnik, który uznaje pokazywany
obiekt za stały. Nie można go więc
modyfikować.

Te dwa typy wskaźników można ze sobą
łączyć, np.

const float

*

const

Wsk = &a;

background image

Wskaźnik zawsze na coś

pokazuje:

Jeden z najczęściej popełnianych błędów w

programach ze wskaźnikami jest

brak

początkowego ustawienia wskaźnika

.

Przy braku ustawienia następuje

odczyt z

przypadkowego miejsca

w pamięci oraz

zapis do

przypadkowego miejsca

.

void

fun ()

{
float

a;

float

* x, * m:

// definicja wskaźników bez

inicjalizacji

m = &a;

// ustawienie wskaźnika

m

*x = 20.5;

// wskaźnik

x

nie jest ustawiony!

//

w

tym

momencie

możemy

skasować

// potrzebną daną

}

background image

Rezerwacja obszarów pamięci:

Rezerwowanie

i

zwalnianie

obszarów

pamięci jest wykonywane za pomocą
operatorów

new

i

delete

.

Operator

new

zajmuje się kreacją, a

delete

unicestwianiem obiektów.

Przykłady

:

char

* Wsk;

Wsk =

new

char;

// utworzenie nowego

obiektu t.

char

delete

Wsk;

// zlikwidowanie tego

obiektu

float

* w;

w =

new float

[10];

delete

[ ] w;

int

* Wsk;

Wsk =

new int

( 50 );

background image

Cechy obiektów stworzonych operatorem

new

:

Obiekty takie istnieją od momentu, gdy je

stworzyliśmy operatorem

new

do momentu,

gdy je skasujemy operatorem

delete

. Więc,

programista decyduje o czasie ich życia.

Obiekt tak utworzony nie ma nazwy. Można

nim operować tylko za pomocą wskaźników.

Obiektów tych nie obowiązują zwykłe zasady o

zakresie ważności. Jeśli tylko w danej chwili
jest dostępny choćby jeden wskaźnik, który na
taki obiekt wskazuje, to mamy dostęp do tego
obiektu.

Tylko statyczne obiekty są inicjalizowane

wstępnie

zerami.

Natomiast

obiekty

utworzone operatorem

new

po utworzeniu

przechowują wartości przypadkowe.

background image

Dynamiczna alokacja tablicy:

int

* Wsk_Tab;

Wsk_Tab =

new int

[ Rozmiar ];

Rozmiar

jest wyrażeniem typu

int

.

Została stworzona nienazwana tablica

elementów typu

int

.

Wynikiem działania operatora

new

jest

wskaźnik do początku tej tablicy.

Operator

new

daje swobodę.

Tablica definiowana jest dynamicznie,

w trakcie wykonywania programu, np.:

background image

cout

<<

Ile elementów ma mieć tablica?:

;

int

Rozmiar;

cin

>>

Rozmiar;

int

* Wsk_Tab =

new int

[ Rozmiar ];

* Wsk_Tab = 50;

// wpisanie do zerowego

elementu

// liczby

50

Wsk_Tab [0] = 50;

// to samo inaczej

* (Wsk_Tab + 4) = 100;

// wpisanie do elementu

o indeksie

4

// wartości 100

Wsk_Tab [4] = 100;

// to samo inaczej

delete

[

]

Wsk_Tab;

//

zlikwidowanie

wykreowanej

// tablicy

background image

Sposoby ustawienia

wskaźników:

Wskaźnik można ustawić tak, aby

pokazywał na jakiś obiekt, wstawiając do
niego adres wybranego obiektu:

Wsk = & Obiekt;

Wskaźnik można również ustawić na to

samo, na co pokazuje już inny wskaźnik.
Jest to zwykła operacja przypisania
wskaźników:

Wsk = Nowy_Wsk;

cdn.

background image

Wskaźnik ustawia się

na początek tablicy

podstawiając do niego jej adres. W zapisie
jest niepotrzebny operator

&

:

Wsk = Tablica

Wskaźnik może także pokazywać na funkcję.

Nazwa funkcji jest także jej adresem, zatem i
tu zbędny jest operator

&

:

Wsk = Funkcja;

Operator

new

zwraca adres nowoutworzonego

obiektu. Taki adres wpisujemy do wskaźnika.
Od tej pory wskaźnik pokazuje na ten nowy
obiekt:

float

* Wsk;

Wsk =

new float

;

Jeśli wskaźnik

ma pokazywać na ciąg znaków

,

można go ustawić w taki sposób:

Wsk = Programowanie komputerów ;

background image

Tablice wskaźników:

Elementami tablic mogą być wskaźniki

, czyli

adresy różnych miejsc w pamięci, np.:

float

* Wsk_Flo [10];

lub

float

* (Wsk_Flo [10]);

char

* Wsk_Lan [ 3];

char

* Wsk_Lan [3] = { Matematyka,

Fizyka,

Progr. Komputerów};

char

* Wsk = { abcde };

background image

Przykład 1:

Obliczyć wartości dwóch

następujących całek:

3

2

2

3 dx

x

dx

x

1

0

2

sin

wykorzystując metodę

Simpsona

.

background image

Przybliżony wzór na obliczenie całki
ma następującą postać:

b

a

dx

x

f

I

)

(

3

/

))

(

...

)

(

)

(

(

2

))

(

...

)

(

)

(

(

4

)

(

)

(

2

4

2

1

3

1

0

m

m

m

x

f

x

f

x

f

x

f

x

f

x

f

x

f

x

f

h

I

gdzi
e:

m

a

b

h

- długość
podprzedziału

m

-

jest parzystą liczbą

podprzedziałów

.

background image

f(x) = 3*x*x

0

5

10

15

20

25

30

-2

-1

,5

-1

-0

,5

0

0

,5

1

1

,5

2

2

,5

3

x

y

background image

#include <conio.h>
#include <iostream.h>

void main

()

{

int

a = 1;

int

*

Adr;

int

&

r_a = a;

Adr =

&

a;

clrscr();
cout

<<

*

Adr

<<

endl

;

cout

<<

&

r_a

<<

endl

;

cout

<<

&

a

<<

endl

;

cout

<<

Adr

<<

endl

;

cout

<<

a

<<

endl

;

cout

<<

r_a

<<

endl

;

r_a = 2;
Adr =

&

r_a;

cout

<<

Adr

<<

endl

;

cout

<<

*

Adr

<<

endl

;

}

Wskaźnik a referencja

1

0x8fa0fff4

0x8fa0fff4

0x8fa0fff4

1

1

0x8fa0fff4

2


Document Outline


Wyszukiwarka

Podobne podstrony:
c++ wykłady, Wyc 5 add wskaznki
c++ wykłady, Wyc 2
c++ wykłady, Wyc 3
c++ wykłady, Wyc 6 struktury przec klasy
c++ wykłady, Wyc 1
c++ wykłady, Wyc 4
c++ wykłady, Wyc 5 add wskaznki
c++ wykłady, Wyc 2
Napęd Elektryczny wykład
wykład5
Psychologia wykład 1 Stres i radzenie sobie z nim zjazd B
Wykład 04
geriatria p pokarmowy wyklad materialy
ostre stany w alergologii wyklad 2003
WYKŁAD VII
Wykład 1, WPŁYW ŻYWIENIA NA ZDROWIE W RÓŻNYCH ETAPACH ŻYCIA CZŁOWIEKA
Zaburzenia nerwicowe wyklad
Szkol Wykład do Or

więcej podobnych podstron