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

Podobne dokumenty