Bogdan Kreczmer ZPCiR IIAiR PWr pokój 307 budynek C3 bogdan.kreczmer@pwr.wroc.pl Copyright c 2005 2008 Bogdan Kreczmer Niniejszy dokument zawiera materiały do wykładu na temat programowania obiektowego. Jest on udostępiony pod warunkiem wykorzystania wyłacznie do własnych prywatnych potrzeb i może on być kopiowany wyłacznie w całości, razem z niniejsza strona tytułowa.
Operacje wyjścia - porównanie C i C++ 1 Język C #include <stdio.h> printf( Hello World!!!\n ); return 0; Język C++ #include <iostream> using namespace std; cout << Hello World!!! << endl; Funkcja main w języku C++ domyślnie zwraca wartość 0. Operacje wyjścia sa realizowane na obiekcie cout z wykorzystaniem przeciażenia operatora lewostronnego przesunięcia bitowego <<.
Operacje wyjścia - porównanie C i C++ 2 Język C Język C++ printf( Napis ); printf( Napis\n ); cout << Napis ; cout << Napis\n ; cout << Napis << endl; char wnap = Napis ; char wnap = Napis ; printf( %s, wnap); cout << wnap; printf( %c, a ); char Znak = a ; printf( %c, Znak); printf( \n ); cout << a ; char Znak = a ; cout << Znak; cout << \n ; cout << \n ;
Operacje wyjścia - porównanie C i C++ 3 Język C Język C++ printf( %i,13); cout << 13; printf( %x,13); cout << hex << 13; printf( %f, 13.0); cout << 13.0; double Zm = 13.0; double Zm = 13.0; printf( %f, Zm); cout << Zm; printf( %9f, 7.0); cout << setw(9) << 7.0; printf( %9.3f, 7.0); cout << setw(9) << precision(3) << 7.0; printf( Napis%f%c,7.0, z ); cout << Napis << 7.0 << z ;
Operacje wejścia - porównanie C i C++ 4 Język C Język C++ int ZmInt; int ZmInt; scanf( %i, &ZmInt); cin >> ZmInt; float ZmFloat; float ZmFloat; scanf( %f, &ZmFloat); cin >> ZmFloat; double ZmDouble; double ZmDouble; scanf( %lf, &ZmDouble); cin >> ZmDouble; int ZmInt; int ZmInt; float ZmFloat; float ZmFloat; scanf( %i%f, &ZmInt, &ZmFloat); cin >> ZmInt >> ZmFloat;
Operacje wejścia - porównanie C i C++ 5 Język C Język C++ char Znak; int Znak; scanf( %c, &Znak); cin >> Znak; char Tab[10000]; char Tab[10000]; scanf( %s, Tab); cin >> Tab; Tak można, ale mimo to nie należy robić!!! (niebezpieczeństwo niekontrolowanego przepełnienia) char Tab[10]; char Tab[10]; scanf( %10s, Tab); cin >> setw(sizeof(tab)) >> Tab; char Znak, Tab[10]; char Znak, Tab[10]; scanf( %c%10s, &Znak, Tab); cin >> Znak >> setw(sizeof(tab)) >> Tab;
Operacje wejścia - porównanie C i C++ 6 Język C Wczytywanie bez pomijania znaków białych Język C++ int KodZnaku; char Znak; scanf( %c, &Znak); cin >> noskipws >> Znak; Wymuszenie pomijania znaków białych char Znak; char Znak; scanf( %c, &Znak); cin >> skipws >> Znak; Odrzucenie znaku int KodZnaku; char Znak; KodZanku = getchar( ); cin >> Znak; // Zakładamy, że strumień jest ungetc(kodznaku, stdin); cin.unget( ); // we właściwym stanie.
Operacje wejścia - porównanie C i C++ 7 Język C Język C++ fprintf(stderr, Komunikat o błędzie... ); cerr << Komunikat o błędzie... ; Predefiniowane strumienie wejścia/wyjścia FILE stdin istream cin FILE stdout ostream cout FILE stderr ostream cerr ostream clog Deklaracje plików nagłówkowych dla operacji wejścia/wyjścia #include <stdio.h> #include <iostream> #include <iomanip> using namespace std;
8 Operacje wyjścia - definiowanie przeciażeń... enum Element a, b, e ; void Wyswietl( Element x) char Nazwa = abe ; ostrm << Nazwa[x]; Element x = a; cout << Wartosc zmiennej x: ; Wyswietl( x ); cout << endl; Tworzenie specjalizowanej funkcji do wyświetlania wartości zmiennej danego typu jest podejściem właściwym dla języka C (gdyż nie ma tam innej możliwości). Oczywista wada takiego podejścia jest brak elastyczności.
Operacje wyjścia - operator << 9 cout << Napis ; cout.operator << ( Napis ); cout << Napis << endl; (cout.operator << ( Napis ) ).operator << (endl); Operacje wejścia/wyjścia sa zdefiniowane w oparciu o standardowe mechanizmy dostępne na poziomie języka C++. W tym sensie biblioteka standardowa nie wykorzystuje żadnych dodatkowych mechanizmów, które byłyby spoza definicji jęzka, tak jak to ma miejsce np. w Pascalu.
Operacje wyjścia - definiowanie przeciażeń 10 enum Element a, b, e ; ostream & operator << ( ostream & ostrm, Element x ) ostrm << abe [x]; return ostrm; Element z = a; cout << Wartosc zmiennej z: << z << endl; Przy definiowaniu przeciażenia musza być spełnione dwa warunki: 1. Pierwszy parametr musi być klasy ostream i musi on być przekazywany przez referencję. 2. Przeciażenie operatora musi zwracać referencję do pierwszego parametru klasy ostream.
Operacje wyjścia - definiowanie przeciażeń 11 enum Element a, b, e ; ostream & operator << ( ostream & ostrm, Element x ) return ostrm << abe [x]; Element z = a; cout << Wartosc zmiennej z: << z << endl; Dzięki temu, że przeciażęnie operatora << zwraca zawsze referencję do obiektu ostream, możliwy jest znacznie bardziej zwarty zapis.
Operacje wyjścia - definiowanie przeciażeń 12 enum Stan Uspienie, Czuwanie, Aktywny ; ostream & operator << ( ostream & ostrm, Stan x ) char Nazwa[ ] = Uspienie, Czuwanie, Aktywny ; return ostrm << Nazwa[x]; Stan z = Czuwanie; cout << Aktualny stan: << z << endl; Tłumaczenie wartości stanu na nazwę można łatwo zrealizować wykorzystujac tablicę napisów.
Operacje wyjścia - definiowanie przeciażeń 13 struct LiczbaZespolona float re, im; ; ostream & operator << ( ostream & ostrm, LiczbaZespolona lz ) return ostrm << lz.re << showpos << lz.im << noshowpos << i ; LiczbaZespolona LZesp; LZesp.re = 2; LZesp.im = 5; cout << Liczba zespolona: << LZesp << endl;
Operacje wyjścia - definiowanie przeciażeń 13 struct LiczbaZespolona float re, im; ; ostream & operator << ( ostream & ostrm, LiczbaZespolona lz ) return ostrm << lz.re << showpos << lz.im << noshowpos << i ; LiczbaZespolona LZesp; LZesp.re = 2; LZesp.im = 5; cout << Liczba zespolona: << LZesp << endl; Wyświetlona wartość: 2+5i Dla części urojonej wymuszone zostaje uwidocznienie znaku liczby.
Operacje wyjścia - definiowanie przeciażeń 14 struct LiczbaZespolona float re, im; ; ostream & operator << ( ostream & ostrm, const LiczbaZespolona& lz ) return ostrm << lz.re << showpos << lz.im << noshowpos << i ; LiczbaZespolona LZesp; LZesp.re = 2; LZesp.im = 5; cout << Liczba zespolona: << LZesp << endl; Przekazywanie parametru wywołania przez referencję jest bardziej właściwe dla tego przypadku.
15 Operacje wejścia - definiowanie przeciażeń struct LiczbaZespolona float re, im; ; istream & operator >> ( istream & istrm, LiczbaZespolona& lz ) return (istrm >> lz.re >> lz.im).ignore( ); LiczbaZespolona LZesp; cin >> LZesp; Przekazywanie parametru wywołania przez referencję jest dla tego przypadku konieczne. Implementacja wczytania liczby urojonej jest bardzo uproszczona (brak reakcji na błędy). Realizacja czytania: wczytane zostaja dwie kolejne liczby, następnie zostaje pominięty pierwszy znak znajdujacy się za druga liczba.
Pytania i ćwiczenia 16 1. Czy operacja: cout << Napis ; spowoduje pojawienie się tekstu napis na ekranie monitora? Zakładamy, że ekran monitora jest wyjściem standardowym dla danej aplikacji. 2. Czy zbiór operacji: cout << \n ; cout << \n ; cout << endl; jest zbiorem operacji równoważnych pod względem wyniku działania? 3. Jeżeli powyżej przedstawione operacje sa równoważne, to czy sa one wykonywane przez tę sama metodę? Jeżeli zaś nie, to jakie sa najistotniejsze różnice?