adres x

Transkrypt

adres x
Język ANSI C – wskaźniki
Wskaźniki (1)
- Wskaźniki to typ obiektów, przechowujących adresy innych
obiektów np. zmiennych.
- Adres to konkretna lokalizacja pewnego obiektu w pamięci.
- Jeżeli pewien obiekt typu wskaźnikowego (np. zmienna)
przechowuje adres innego obiektu, to mówimy, że wskazuje na ten
obiekt.
Wskazniki i dynamiczna alokacja
( link do materiału na temat wskaźników)
Język ANSI C – wskaźniki
int main() {
int x=5 ,y=23;
int *px;// definicja zmiennej wskaźnikowej wskazującej na
//obiekty typu int
px=&x; }
px
y
12FF88
12FF80
(1245056)
x
23
12FF84
(1245060)
5
12FF88
(1245064)
zawartości
adresy hex
adresy dec
Adresy te mogą się zmieniać przy kolejnych uruchomieniach programu,
jednak w komórce px będzie zawsze adres zmiennej x.
Język ANSI C – wskaźniki
Przykład. Program obliczający adresy zmiennych i zawartość zmiennej
wskaźnikowej.
#include <stdio.h>
int main(int argc, char *argv[]) {
int x,y;
int *px;
printf("\n Adres zmiennej x
w hex
= %p
i w
dec =%d\n", &x,&x);
printf("\n Adres zmiennej y
w hex
= %p
i w
dec =%d\n", &y,&y);
printf("\n Adres wskaznika px
w hex
= %p
i w
dec =%d\n",&px,&px);
=%x
i w
dec =%d\n", px,px);
px=&x;
printf("\n Zawartosc komorki px w hex
system("PAUSE");
return 0;
}
Język ANSI C – wskaźniki
Przykładowy wynik działania programu:
Adres zmiennej x
w hex
= 0012FF88
i w
dec =1245064
Adres zmiennej y
w hex
= 0012FF84
i w
dec =1245060
=0012FF80
i w
dec =1245056
=12ff88
i w
dec =1245064
Adres wskaznika px w hex
Zawartosc komorki px w hex
Press any key to continue . . .
Język ANSI C – wskaźniki
Definicja prostej zmiennej wskaźnikowej
Definicja zmiennej wskaźnikowej składa się z nazwy typu
wskazywanych obiektów, gwiazdki oraz nazwy zmiennej
typ_wskazywanych_obiektów * nazwa_zmiennej ;
typ_wskazywanych_obiektów zwany jest zwykle typem wskaźnika.
Przykład. Definicja zmiennej wskazującej na obiekty typu
double.
double * pd;
Język ANSI C – wskaźniki
Operatory wskaźnikowe
W języku C istnieją dwa operatory wskaźnikowe:
- operator adresowy &
- operator adresowania pośredniego * ( dereferencji)
Jednoargumentowy operator & przyłożony do operandu zwraca
adres operandu w pamięci ( dokładniej - wyrażenie &operand
reprezentuje adres operandu).
Jednoargumentowy operator * przyłożony do operandu
wskaźnikowego, zwraca wartość znajdującą się pod adresem
zawartym w obiekcie (zmiennej) występującym po operatorze.
Język ANSI C – wskaźniki
Przykład. Proste działania przy użyciu wskaźników.
int *px, *py;// definicja zmiennych wskaźnikowych px i py
int i=5, j,k=10;
px=&i;// przypisanie adresu zmiennej i wskaźnikowi px;
j=*px;// podstawienie wartości i do j
przy użyciu wskaźnika
*px= i+k; // podstawienie sumy i+k do i
py=px;// przypisanie wartości wskaźnika px wskaźnikowi py,
// oba wskaźniki zawierają adres zmiennej i
*py=20; // podstawienie do i wartości 20
printf(”\n i=%d”, *py); // drukowanie i przy użyciu
//wskaźnika py
*py=*py+5;//zwiększenie i o 5
printf(”\n i=%d”, *py); // drukowanie zmiennej i przy użyciu py
Język ANSI C – wskaźniki
Przykład. Wczytywanie i drukowanie zmiennej przy użyciu wskaźnika
#include <stdio.h>
int main()
{
double *pd;
double x;
pd=&x;
printf("\n Podaj x:");
scanf("%lf", pd);
printf("\n x=%f",*pd);
system("PAUSE");
return 0;
}
Język ANSI C – wskaźniki
Wyrażenie *px ma różny sens w zależności od tego czy
występuje po lewej czy też po prawej stronie instrukcji
podstawienia.
Dla następujących definicji i instrukcji
int x=5,y, *px;
px=&x;
w instrukcji
y=*px;
wyrażenie *px reprezentuje zawartość komórki wskazywanej
przez px, czyli komórki x (jest to 5).
Natomiast w instrukcji
*px=15;
wyrażenie *px reprezentuje adres pamięci ( zmienną), pod który
można wpisać jakąś wartość.
Język ANSI C – wskaźniki
L-wartości ( ang. lvalue) i R-wqrtości
W języku ANSI C zmienna jest nazwanym obszarem pamięci;
L-wartość jest wyrażeniem reprezentującym pewien obszar pamięci.
Przykładem L-wartości jest identyfikator o odpowiednim typie i klasie pamięci.
Niektóre operatory jako wynik swojego zastosowania dają L-wartość,
np. jeżeli W jest wyrażeniem wskaźnikowym, to *W jest L-wartością
odnosząca się do obiektu wskazywanego przez W. Określenie L-wartość
wywodzi się od instrukcji przypisania
W1=W2;
w której lewy argument musi L-wartością ( reprezentować pewną lokację w
pamięci).
Stosując poszczególne operatory należy zważać czy zastosowanie danego
operatora daje w wyniku L-wartość.
Język ANSI C – wskaźniki
Przykład. (L-wartość)
int x=0;
int *wski;
x=x+1;
L-wartość (lokacja pamięci)
wski = &x; /* wskaźnik wski wskazuje na x */
*wski = *wski +1;
L-wartość
Język ANSI C – wskaźniki
Arytmetyka na wskaźnikach
W językach C i C++ stosując wskaźniki można posługiwać się tzw.
ograniczoną arytmetyką na wskaźnikach. Oznacza to, że można stosować
niektóre operacje arytmetyczne, by obliczyć odpowiedni wskaźnik.
Należy jednak w każdym przypadku zważać na to, co może oznaczać wynik
danego działania. Dla wskaźników można stosować następujące operacje
wskaźnikowe:
Język ANSI C – wskaźniki
Działania arytmetyczne na wskaźnikach
Na wskaźnikach wskazujących na ten sam typ można dokonywać
następujących operacji:
-inkrementacji (++) ( zwiększania)
-dekrementacji (--)
( zmniejszania)
-dodawania do wskaźnika liczby całkowitej
-odejmowania od wskaźnika liczby całkowitej
-odejmowania wskaźników od siebie
-porównywania dwóch wskaźników.
Język ANSI C – wskaźniki
Inkrementacja wskaźnika
Jeżeli wskaźnik wsk do pewnego typu wskazuje na pewną komórkę pamięci to
wyrażenie wsk++ wskazuje na komórkę o adresie wsk+sizeof(typ).
Przykład. Inkrementacja wskaźników do int .
int *wsk,x;
wsk
wsk=&x;
wsk++;
x
wsk++
Język ANSI C – wskaźniki
Dekrementacja wskaźnika
Jeżeli wskaźnik wsk do pewnego typu wskazuje na pewną komórkę pamięci to
wyrażenie wsk-- wskazuje na komórkę o adresie wsk-sizeof(typ).
Przykład. Dekrementacja wskaźnika do int
int *wsk,x;
wsk--
wsk
wsk=&x;
wsk--;
x
Język ANSI C – wskaźniki
Dodawanie do wskaźnika liczby całkowitej
Jeżeli wskaźnik wsk do pewnego typu wskazuje na pewną komórkę pamięci to
wyrażenie wsk+liczba wskazuje na komórkę o adresie
wsk+liczba*sizeof(typ).
Odejmowanie od wskaźnika liczby całkowitej
Jeżeli wskaźnik wsk do pewnego typu wskazuje na pewną komórkę pamięci to
wyrażenie wsk-liczba wskazuje na komórkę o adresie
wsk-liczba*sizeof(typ).
Język ANSI C – wskaźniki
Odejmowanie wskaźników
Jeżeli dane są dwa wskaźniki wsk1 i wsk2,do tego samego typu Type, to
po wykonaniu instrukcji
diff= wsk2 - wsk1;
to diff ma wartość dodatnią, jeżeli wsk2 wskazuje na wyższy adres,
i ma wartość równą liczbie elementów typu Type, które można umieścić
między adresami komórek pamięci wskazywanych przez wsk1 i wsk2.
Jeśli wsk2 wskazuje na adres niższy, diff ma wartość ujemną, a interpretacja
jest podobna.
Język ANSI C – wskaźniki
Porównywanie wskaźników
Jeśli wskaźniki wsk1 i wsk2 wskazują na ten sam typ, to
wyrażenie
wsk2>wsk1
ma wartość logiczną prawda, jeżeli wsk2 wskazuje na adres wyższy i wartość
fałsz, gdy na niższy.
Język ANSI C – wskaźniki
Przykład. L-wartości i R-wartości
#include <stdio.h>
#include<stdlib.h>
int main(int argc, char* argv[])
{
int j,*wski,i=5;
wski=&i;
*wski=j;
// *wski jest L-value (L-wartoscią)
//++ * wski=j; // L-value required ( wymagana
//L-wartosc), wyrażenie nie jest
//L-wartością
* ++wski=j; // *++wski jest L-value
Język ANSI C – wskaźniki
Przykład. L-wartości i R-wartości (c.d)
//
(*wski) ++=j;
// L-value required
// wymagana L-wartość
*(wski ++)=j;
system("pause");
return 0;
}
// L-value (L-wartość)
Język ANSI C – wskaźniki
Wskaźniki i tablice
Nazwa tablicy w C jest stałym wskaźnikiem do pierwszego elementu
tablicy. Np. jeżeli stworzymy definicje
int a[5];
int *pa;
i zastosujemy instrukcję
pa=a;
to wskaźnik pa będzie wskazywał na a[0], czyli pierwszy element tablicy
a.
Stosując wskaźniki można wykonać te same operacje na tablicach, co
przy użyciu indeksowania.
Język ANSI C – wskaźniki
Przykład. Proste działania na tablicach przy użyciu wskaźników
#include <stdio.h>
int main() {
int a[5]; int *pa,i;
pa=a;
// przypisanie wskaźnikowi pa adresu a[0]
*pa=10; //zapis wartości 10 do a[0]
pa++; //zwiększenie wskaźnika, wskazuje on teraz na a[1]
*pa=20; // zapis wartości 2 do a[1];
pa=pa+1; // wskaźnik wskazuje na element a[2]
for (i=2; i<5; i++){
printf("\n Podaj a[%d]=",i);
scanf("%d",pa);
pa++;
}
pa=a; // ustawienie wskaźnika na początek tablicy
// alternatywnie pa= pa-5
for (i=0;i<5;i++)
printf("\n a[%d]=%d", i,*pa++);
printf("\n");
system("PAUSE");}
Język ANSI C – wskaźniki
Przyklad. Program wczytujący tablicę dwuwymiarową przy zastosowaniu
wskaźników.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{ int tab[3][3];
int *p;
p=&tab[0][0];
int i,j;
for (i=0;i<3;i++)
for (j=0;j<3;j++)
{
printf("\n Podaj element [%d}[%d}=",i,j);
scanf("%d",p+j+i*3);
}
for (i=0;i<3;i++)
{ for (j=0;j<3;j++)
printf("
system("PAUSE");
return 0; }
%d",*(p+j+i*3));
printf("\n");
}

Podobne dokumenty