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"); }