PI W4 T1

background image

Podstawy

Informatyki

wykład dla studentów
studiów magisterskich

dr inż. Grzegorz Bliźniuk

Instytut Systemów Informatycznych
Wydział Cybernetyki WAT
Warszawa

WYKŁAD 4

background image

2

Grzegorz Bliźniuk, Podstawy Informatyki, wykład 4

Wykład 4: Wskaźnikowe typy

danych

podstawy typów wskaźnikowych

operatory wskaźnikowe

wskaźniki a typy tablicowe i napisy

wskaźnikowe parametry funkcji

czas wykładu: 2 godziny lekcyjne

background image

3

Grzegorz Bliźniuk, Podstawy Informatyki, wykład 4

Podstawy typów wskaźnikowych

Wskaźnik jest specjalnym typem
danych

Zmienna typu wskaźnikowego
przechowuje wskazanie do
(adres) innego obiektu (zmiennej)
w pamięci operacyjnej

Wskazania poprzez typy
wskaźnikowe można traktować
tak, jak nazwane adresy w
pamięci operacyjnej

W związku z tym wskaźniki mają
określoną specjalną arytmetykę
wskaźników, dzięki którym można
w stosunkowo łatwy sposób
operować na adresach w pamięci
operacyjnej

p = =

wskazanie

q = =

wartość

background image

4

Grzegorz Bliźniuk, Podstawy Informatyki, wykład 4

Podstawy typów wskaźnikowych

Deklaracja zmiennej
wskaźnikowej w języku C:

typ

*

zmienna_wskaźnikowa;

znak

gwiazdki

oznacza

wskaźnik

- jest on

bardzo

ważny!!!

zmienna_wskaźniko

wa

= = wskazanie na

zmienną

wskazywany

obiekt

= = bliżej

nieokreślona

zmienna

typu „typ”

background image

5

Grzegorz Bliźniuk, Podstawy Informatyki, wykład 4

Podstawy typów wskaźnikowych

Deklaracja wskaźnika na
zmienną całkowitoliczbową

int

*

p

;

p

= = wskazanie na

zmienną

wskazywany

obiekt

= = bliżej

nieokreślona

zmienna

typu int

background image

6

Grzegorz Bliźniuk, Podstawy Informatyki, wykład 4

Podstawy typów wskaźnikowych

Deklaracja wskaźnika na
zmienną całkowitoliczbową

int

*

p, q

;

wskaźnik

na zmienną

całkowitoliczbową

zmienna

całkowitoliczbowa

Ustawienie wskazania z p na q:

p = & q

;

znak

& (ampersand)

oznacza ustawienie wskazania

adresowego dla wskaźnika

p

= =

wskazanie

q

= =

wartość_nieznana

background image

7

Grzegorz Bliźniuk, Podstawy Informatyki, wykład 4

Podstawy typów wskaźnikowych

Ustawienie wskazania na
zmienną całkowitoliczbową

int

*

p, q

;

p=&q; /*adres w PAO*/

Podstawienie wartości liczby:

q=150; lub:

*

p=150;

p

= =

wskazanie

q

= =

150

ustawienie wartości

przez zmienną

wskazywaną

ustawienie wartości

przez zmienną

wskaźnikową

- ODWOŁANIE NIEJAWNE

do zmiennej

q

background image

8

Grzegorz Bliźniuk, Podstawy Informatyki, wykład 4

Podstawy typów wskaźnikowych

Przykład programu ze wskaźnikami:

#include <stdio.h>

main( )

{
int *p, q;

p=&q; /*ustawienie wskazania z p na q*/
*p=150; /*niejawne przypisanie wartości do q*/

printf(„Wartość q wynosi: %d\n”, q);

/*czy można

inaczej?*/

return 0;
}

background image

9

Grzegorz Bliźniuk, Podstawy Informatyki, wykład 4

Operatory wskaźnikowe

Poznaliśmy już dwa podstawowe operatory dla typów
wskaźnikowych. Są to:

operator zwracający wartość przechowywaną pod
konkretnym wskazaniem -

oznaczany gwiazdką -

*

operator zwracający adres zmiennej wskazywanej -

oznaczany „ampersandem” -

&

Poznajmy jeszcze pozostałe cztery operatory dla
zmiennych wskaźnikowych

background image

10

Grzegorz Bliźniuk, Podstawy Informatyki, wykład 4

Arytmetyczne operatory

wskaźnikowe

Arytmetyka wskaźników jest inna niż arytmetyka na
liczbach, ponieważ:

inkrementacja wartości wskaźnika „p” oznacza
przejście do adresu:

„p + liczba bajtów dla wskazywanego przez p”

dekrementacja wartości wskaźnika „p” oznacza
przejście do adresu:

„p - liczba bajtów dla wskazywanego przez p”

Dla wskaźnika do typu

char

będzie to przechodzenie

co 1 bajt

,

Dla wskaźnika do typu

int

będzie to przechodzenie

co 2 bajty

,

Dla wskaźnika do typu

float

- przechodzenie

co 4 bajty

??? Jak to wygląda dla wskaźników do pozostałych typów

background image

11

Grzegorz Bliźniuk, Podstawy Informatyki, wykład 4

Arytmetyczne operatory

wskaźnikowe

Przykład:

int *p, q;

p=&q; /*załóżmy, że p wskazuje na adres: 100*/

*p=200; /*wartość wskazywana przez p == 200*/

p++; /*p wskazuje na adres 102 - dlaczego?*/

p++; /* na jaki adres wskazuje p ?*/

p = p + 12; /*p wskazuje na adres 128 - dlaczego?*/

/* na jaką wartość wskazuje p?*/

Do poćwiczenia:

Wykonaj analogiczne do powyższych działania dla
wskaźników do typów char, float, long, double.

background image

12

Grzegorz Bliźniuk, Podstawy Informatyki, wykład 4

Arytmetyka wskaźników a

arytmetyka liczb

Wykorzystując wskaźniki na liczby trzeba koniecznie rozróżniać
arytmetykę wskaźników od zwykłej arytmetyki liczb:

int *p, q;

p=&q;
q= 150;

*p++; /*zwiększenie adresu o 2 bajty - dlaczego?*/
*p- -; /*zmniejszenie adresu o 2 bajty - wskazanie na q*/

(*p)++; /*inkrementacja wartości wskazywanej przez p
jaka jest teraz wartość zmiennej q?*/
(*p)++; /*a teraz q == 152 !!!! */

operatory

wskaźnikowe

operatory

arytmetyczne

background image

13

Grzegorz Bliźniuk, Podstawy Informatyki, wykład 4

Arytmetyka wskaźników a

arytmetyka liczb

Przykład 1. Wypisywanie wartości wskaźników (adresów w PAO):

#include <stdio.h>
main( )
{
char *cp, c;
int *ip, i;
float *fp, f;
double *dp, d;

cp=&c; /*ustawienie wskaźników*/
ip=&i;
fp=&f;
dp=&d;

/*wypisanie bieżących wartości wskaźników*/
printf(„Wartości wskaźników: %p, %p, %p, %p \n”, cp, ip, fp, dp);

return 0;
}

%p

operator konwersji

dla wypisywania wskaźników

background image

14

Grzegorz Bliźniuk, Podstawy Informatyki, wykład 4

Arytmetyka wskaźników a

arytmetyka liczb

Przykład 2. Pokazanie różnicy pomiędzy arytmetyką liczb i wskaźników:

#include <stdio.h>
main( )
{
int *ip, i;
ip=&i; /*ustawienie wskaźnika*/
i=200; /*ustawienie liczby*/
/*wypisanie bieżących wartości*/
printf(„Wskaźnik: %p, liczba: %d \n”, ip, i);

/*zwiększenie wartości liczby*/

(*ip)++;

/*wypisanie bieżących wartości*/
printf(„Wskaźnik: %p, liczba: %d \n”, ip, i);

/*zwiększenie wskaźnika*/
*ip++;
/*wypisanie bieżących wartości*/
printf(„Wskaźnik: %p, liczba: %d \n”, ip, i);

return 0;
}

background image

15

Grzegorz Bliźniuk, Podstawy Informatyki, wykład 4

Wskaźniki a typy tablicowe

Język C w sposób wyjątkowy utożsamia wskaźniki i tablice

Tak faktycznie, to w wyniku deklaracji zmiennej tablicowej,
środowisko języka C tworzy wskaźnik na początek tej tablicy.
Miejsca na pozostałe elementy tablicy są zajmowane w
zależności od rozmiaru tablicy.

Tablica zajmuje spójny obszar pamięci operacyjnej

Tak więc do tablic możemy odnosić się w sposób tradycyjny,
tzn. przy pomocy nazwy zmiennej z indeksem tablicy: tab[i]
lub stosując arytmetykę wskaźników

Takie traktowanie tablic jest szczególnie przydatne dla tzw.
tablic otwartych i łańcuchów znaków - bez wstępnego
określenia ich długości. Środowisko języka C jest w stanie na
bieżąco reagować na aktualne potrzeby programisty w tym
zakresie

Takich cech nie ma większość innych języków
programowania

background image

16

Grzegorz Bliźniuk, Podstawy Informatyki, wykład 4

Wskaźniki a typy tablicowe

W poniższym programie przedstawiono klasyczną i
wskaźnikową referencję do elementów tablicy tab:

#include <stdio.h>

main( )

{
int a[5] = {10, 20, 30, 40, 50};
int *p;

p = a; /*przypisanie początku tablicy - DLA WSKAŹNIKÓW
DO TABLIC NIE UŻYWAMY AMPERSANDA!!!*/

/*zwykłe indeksowanie elementów tablicy*/
printf(„%d %d %d %d %d”, a[0], a[1], a[2], a[3], a[4]);

/*dostęp do elementów tablicy poprzez wskaźnik*/
printf(„%d %d %d %d %d”, *p, *(p+1), *(p+2), *(p+3),

*(p+4));

return 0;
}

tutaj działa

arytmetyka

wskaźników

background image

17

Grzegorz Bliźniuk, Podstawy Informatyki, wykład 4

Wskaźniki a typy tablicowe

A zatem, kiedy do wskaźnika p podstawiamy wskazanie na
tablicę tab nie używamy znaku & (ampersand). Wynika to
z tego, że zmienna tablicowa jest niejawnie realizowana
przez środowisko języka C jako wskaźnik do początku
tablicy. Wtedy stosujemy podstawienie:

p=tab;

Stosowanie arytmetyki wskaźników przy tablicach jest
możliwe, ale niezbyt wygodne. Lepiej jest wykorzystywać
zwykłe indeksowanie tablic - efekt jest ten sam w obu
przypadkach

Należy zwrócić uwagę na różnicę pomiędzy poniższymi
wyrażeniami:

*p++;

/*zwiększa wskazanie p do następnego elementu*/

*(p+1)

/*daje wskazanie do następnego bez zwiększania p*/

background image

18

Grzegorz Bliźniuk, Podstawy Informatyki, wykład 4

Wskaźniki a napisy

Z poprzedniego wykładu wiemy, że napis jest tablicą znaków.
Nie ma więc wielkich nowości przy wykorzystywaniu
wskaźników z tablicami znaków.

Przykład: wypisanie napisu przy pomocy pętli for :

char nap[ ] = „Łańcuch znaków”;

char *nap_wsk;

int i;

/*wypisuj aż do znaku null w łańcuchu*/
for(i=0;nap[i];i++) {
printf(„%c”, nap[i]);
}

/*??? jak to zrobić wykorzystując nap_wsk ???*/

Jaki to rodzaj

pętli - skonfrontuj

z treścią wykładu 1

background image

19

Grzegorz Bliźniuk, Podstawy Informatyki, wykład 4

Wskaźniki a napisy

Wskaźniki ze stałymi napisowymi:

char *p=„Stały napis wskazywany przez p”;

printf(p);

Czy pamiętasz, że do wczytywania napisów służy

gets(

)

? Jak wykorzystywać to polecenie?

Przestudiuj polecenia z biblioteki

<ctype.h>

.

Szczególnie:

toupper( )

i

tolower( )

.

background image

20

Grzegorz Bliźniuk, Podstawy Informatyki, wykład 4

Wskaźniki a napisy

Postaraj się zrealizować implementację rozwiązań dla
czterech poniższych zadań, wykorzystując wskaźniki do
napisów:

Wczytaj z klawiatury napis o niezdefiniowanej
długości, wczytywanego z klawiatury i wypisz go na
ekranie w kolejności od końca do początku
wczytanego napisu

Wczytaj z klawiatury napis o niezdefiniowanej
długości i wypisz na ekranie zamieniając wszystkie
jego znaki na duże litery

Wczytaj z klawiatury dwa napisy o daj odpowiedź,
czy są one identyczne

Skopiuj napis1 do zmiennej napis2 przechodząc po
pojedynczych znakach i nie zapominając o dodaniu
na koniec napisu wynikowego znaku null, czyli: ‘\0’.

background image

21

Grzegorz Bliźniuk, Podstawy Informatyki, wykład 4

Tablice wskaźników

Możemy w razie potrzeby wykorzystywać tablice wskaźników do
zmiennych tego samego typu, np.:

int *tab_wsk[20]; /*tablica 20-stu wskaźników do int*/

Ustawianie wskazań do różnych zmiennych całkowitoliczbowych:

tab_wsk[2]=&zmienna_int1;

tab_wsk[5]=&inna_zmienna;

Ustawianie wskazań do różnych wartości całkowitoliczbowych:

*tab_wsk[1]=100;

*tab_wsk[3]=300;

Zrealizuj program wypisujący w pętli wartości z tablicy wskaźników

do liczb całkowitych wskazującej na różne zmienne i wartości.

background image

22

Grzegorz Bliźniuk, Podstawy Informatyki, wykład 4

Wskaźnikowe parametry funkcji

Zmienne wskaźnikowe mogą być parametrami funkcji i
procedur

Wszystkie funkcje operujące na napisach korzystają właśnie
ze wskaźników do napisów - dlaczego tak jest?

Na wykładzie o tablicach znaków przedstawiono
wykorzystanie funkcji scanf( ) z biblioteki <stdio.h>.
Wczytanie na przykład jakiejś liczby całkowitej liczba
wygląda następująco:

scanf(„%d”, &liczba); /*dlaczego znak & (ampersand)?
*/

Użycie polecenia gets( ):

char *p;

gets(p); /*dlaczego bez znaku & (ampersand)? */

background image

23

Grzegorz Bliźniuk, Podstawy Informatyki, wykład 4

Wskaźnikowe parametry funkcji

Przykład: przejście pętlą do końca
łańcucha znaków z
wykorzystaniem arytmetyki
wskaźników:

char *p;

int i;

while(*p) {
/*jakieś czynności w pętli*/
*p++;
}

powtarzanie pętli

do napotkania znaku null

przejście do następnego

znaku

background image

24

Grzegorz Bliźniuk, Podstawy Informatyki, wykład 4

Wskaźnikowe parametry funkcji

Zadanie:

Zaproponuj implementację funkcji wykorzystującej
jako parametr wejściowy wskaźnik do napisu:

char *p

i zwracającej liczbę spacji w napisie wskazywanym

przez ten parametr.

background image

25

Grzegorz Bliźniuk, Podstawy Informatyki, wykład 4

Podsumowanie

Omówiliśmy podstawowe zagadnienia dotyczące
typów wskaźnikowych

Wskaźniki w języku C są inaczej zaimplementowane
niż wskaźniki w innych językach programowania

Wskaźniki są bardzo silnym i bardzo wydajnym
narzędziem dla wprawnego programisty

Są one również bardzo wymagające i „kapryśne” -
należy je stosować z pełną tego świadomością

Na następnym wykładzie poznamy zasady obsługi
plików

Dziękuję za uwagę


Document Outline


Wyszukiwarka

Podobne podstrony:
PI T1 1 2 PL 1 ARR
W4 Proces wytwórczy oprogramowania
W4 2010
Statystyka SUM w4
w4 3
W4 2
W4 1
w4 skrócony
w4 orbitale molekularne hybrydyzacja
in w4
w4 Zazębienie ewolwentowe
TM w4
IB w4 Aud pełny
Chemia wyklad I i II (konfiguracja wiÄ…zania Pauling hybrydyzacja wiazania pi i sigma)
W4 Mitochondr

więcej podobnych podstron