L-wartość
Transkrypt
L-wartość
Katedra Elektrotechniki Teoretycznej i Informatyki sem. III-wykład 3 Dr inż. M. Czyżak 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 – funkcje 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 – funkcje 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 C++ – wejście /wyjście Konsolowe operacje wejścia wyjścia w C++ Do realizacji konsolowych operacji wejścia/wyjścia w C++ stosuje się predefiniowane obiekty strumieni - cout klasy ostream i cin klasy istream oraz operatory << i >>. Nazwy obiektów są skrótami od Console-Output i Console-Output. Operator << jest tzw. operatorem wstawiania do strumienia (ang. insertor), a operator << jest operatorem pobierania ze strumienia wejściowego (ang, ekstractor). Sposób ich użycia podano poniżej w programie: Język C++ – wejście /wyjście Konsolowe operacje wejścia wyjścia w C++ #include <iostream> // włączenie biblioteki using namespace std;// deklaracja użycia standardowej // przestrzeni nazw int main(){ int x;double y; cout<<" Podaj x:"; cin>>x; cout<<endl<<" Podaj y:"; cin>>y; cout<<'\n'<<"x="<<x; cout<<'\n'<<"y="<<y<<endl; system("pause"); return 0; } Język C++ – wejście /wyjście Konsolowe operacje wejścia/ wyjścia w C++ Operator << pozwala na wyprowadzanie na ekran wartości różnych typów (np. char, int, double, tablic znakowych, wskaźników). Nie jest konieczne stosowanie deskryptorów formatu dla wyprowadzania w sposób standardowy. Operator ten jest tzw. operatorem przeciążonym, co oznacza, że ten sam symbol operatora pozwala na realizacją różnych operacji w zależności od typu argumentu. Operatorem przeciążonym jest też operator >>. Język C++ – wejście /wyjście Konsolowe operacje wejścia/ wyjścia w C++ Postać wydruku zależy od tzw. stanu formatowania, który jest ustawiony domyślnie w pewien sposób, a który można zmieniać stosując sygnalizatory i manipulatory ( sygnalizatory nie będą tu rozważane, opisano je np. w W. Porębski, Język C++. Standard ISO w praktyce, PWN, W-wa,2008, str, 197-202). Prostsze w użyciu są manipulatory np. manipulator hex, użyty jak niżej, powoduje, że liczby całkowite są wyprowadzane w postaci szesnastkowej. int x=255; cout<< hex <<x; manipulator Język C++ – wejście /wyjście Konsolowe operacje wejścia/ wyjścia w C++ Podstawowe manipulatory to: - dec wydruk w postaci dziesiętnej -hex wydruk w postaci szesnastkowej -oct wydruk w postaci ósemkowej -endl wstaw znak nowej linii i opróżnij strumień -flush -ws opróżnij strumień pomiń spacje -setbase(int b) konwersja na system liczbowy o podstawie b (b=8,10,16) -setfill(int z) ustal znak dopełniający na znak z -setprecision (int p) ustal liczbę miejsc po kropce dziesiętnej -setw( int w) ustaw szerokość pola wydruku na w