KURS C/C++
WYKAAD 5
Typ wyliczeniowy enum
Istnieje inna często wygodniejsz niż deklaracja const metoda nazywania stałych całkowitych
Deklaracja:
enum {WRITE, READ, DELETE);
definiuje trzy stałe całkowite WRITE, READ, DELETE, które nazywamy stałymi wyliczanymi i
przypisuje im kolejno wartości całkowite 0,1,2.
Deklaracja ta jest równoważna zapisowi:
const WRITE = 0;
const READ = 1;
const DELETE = 2;
Wyliczenie może mieć nazwę.
enum RIGHT {WRITE, READ, DELETE);
Nazwa wyliczenia staje się odrębnym typem.
enum nazwa_typu { lista wyliczeniowa }
Przykład:
enum miesiace {styczeń, luty, marzec, kwiecień, maj, czerwiec};
enum miesiace {styczen =1, luty, marzec, kwiecien=6, maj, czerwiec=luty+marzec};
enum miesiace {styczen =1, luty, marzec, kwiecien, maj, czerwiec};
W ten sposób zdefiniowaliśmy nowy typ o nazwie miesiace. Definiujemy zmienną tego typu:
miesiace mm;
Sposób użycia tych zmiennych jest następujący:
mm = styczen;
if (mm = = luty) {.....}
Kompilator ostrzega przy przypisaniach np.:
mm = 2; powinno być mm = miesiace (2);
mm = 3; mm = miesiace (3);
mm = miesiace (23); // nie ma błędu, pakiet Borland 3.1
Kompilator sygnalizuje błąd przy przypisaniu:
styczeń = 1;
ponieważ zmienne wyliczeniowe sa traktowane jak constans.
// enum {BLACK, BLUE, GREEN, CYAN, RED, MAGENTA);
enum {black, blue, green, cyan, red, magenta); czyli black = 0, blue = 1, itd
textcolor (green);
cprintf (3 Zmiana koloru na zielony3 );
printf (3 \n3 );
Operacje we/wy
Język C/C++ nie posiada zdefiniowanych instrukcji realizujących operacje we/wy. Do tego
celu służą funkcje znajdujące się w standardowych bibliotekach.
standardowe strumienie predefiniowane wejścia/wyjścia
stdin - strumień wejściowy (konsola)
stduot - strumień wyjściowy (konsola)
stderr - strumień komunikatów błędów (konsola)
stdaux - strumień pomocniczy (konsola)
stdprn - strumień drukarki
np.:
fputs (3 Nazwa firmy3 , stdprn);
Funkcja printf();
Funkcje printf() i scanf(), służą do realizacji tzw. formatowanego we/wy.
Składnia funkcji jest następująca:
int printf (const char *format [,argument,...]);
Parametr format wskazuje tzw. łańcuch formatujący. Pewne sekwencje tego łancucha są specjalnie
traktowane przez funkcje printf().
int a=1; float b=2.45; char c=żÿdżÿ;
printf("Wartość zmiennej a = %d zmiennej b = %4.2f \
zmiennej c = %c zmiennej d = %s \n",a,b,c,3 C++3 );
char text[]=żÿC++żÿ;
printf("Wartość zmiennej a = %.2d zmiennej b = %4.2f \
zmiennej c = %c zmiennej d = %s \n",a,b,c,text);
Aby wydrukować znak % trzeba napisać: %%
Ogólny format sekwencji formatującej przedstawia się następująco:
%[flagi][szerokość][.precyzja][h|l|L]znak-typu.
flagi:
flagi znaczenie default
- dosunięcie argumentu do lewego krańca jego pola znak tylko dla ujemnej
+ liczba zawsze ze znakiem +/-
# dla formatu x,X, poprzedzenie liczby 0x, 0X bez znaków wiodących
dla formatu o, poprzedzenie liczby 0
dla formatu e,E,f wstawia zawsze znak kropki
szerokość:
n - wyświetlanych jest przynajmniej n znaków. Jeśli wartość zajmuje mniej niż n znaków
szerokość pola jest uzupełniana dodakowymi spacjami z lewej lub prawj strony w zależności od
ustawionej flagi.
float y=10.96
printf ("y=%5.2f ",y); y=10.96
printf ("y=%10.2f ",y); y= 10.96_
printf ("y=%#.0f ",y); y=11.
int i = 12;
printf ("y=%#x",y); y=0xc.
int y=23;
printf ("y=%6d",y); y = 23_
printf ("y=%-6d",y); y =23 _
printf ("y=%+6d",y); y = +23 _
znak_typu:
znak typu argument wejściowy argument wejściowy
d ,i całkowity liczba dziesiętna ze znakiem
o całkowity liczba ósemkowa bez znaku
x,X całkowity liczba szesnastkowa bez znaku
u całkowity liczba dziesiętna bez znaku
c znak pojedynczy znak
s wskaznik Å‚aÅ„cucha ciÄ…g znaki Å‚aÅ„cucha, aż do wystapienia żÿ\0żÿ lub tyle ile
określono w precyzji
f zmiennoprzecinkowy [-]m.ddd gdzie liczbę cyfr d określa precyzja
(domyślnie 6).
e, E zmiennoprzecinkowy [-]m.dde+-xx. Przed kropką dokładnie jedna cyfra, liczba
cyfr po kropce zależna od precyzji(domyślnie 6).
g, G zmiennoprzecinkowy liczba będzie wyświetlana w postaci e lub f w zależności
od zadanej precyzji. Nie wypisuje zbędnej kropki
dziesiętnej i nie znaczących zer.
y=0.000002;
printf ("y=%f y=%g y=%e",y);
wyświetla: y=0.000002 y=2e-06 y=2.000000e-06
y=2000000;
wyświetla: y=2000000.000000 y=2e+06 y=2.000000e+06
modyfikatory:
modyfikator znaczenie
h argument traktowany jak typu short int dla znaków typu d,i,o,u,x,X
l argument traktowany jak long int dla znaków typu d,i,o,u,x,X
dla znaków e, E, g, G jako typu double
L argument traktowany jak long double dla znaków typu e,E,f,g,G
precyzja:
.0 - dla e, E, f nie jest drukowany znak kropka dziesiętna liczba zero nie zostanie wydrukowana
.n
znak typu znaczenie
d,i,o,u,x,X n cyfr znaczących zostanie wydrukowanych, jeśli jest ich mniej
uzupełnienie zerami z lewej strony., jeśli więcej nie będzie obcięta.
e,E, f n cyfr znaczÄ…cych zostanie wydrukowanych po przecinku
dziesiętnym. Ostatnia cyfra jest zaokraglana.
s co najmniej n znaków zostanie wydrukowanych
long double y=2.1e45;
printf ("y=%Le3 ,y); y = 2.100000e+45
printf ("y=%.2Le3 ,y); y = 2.10e+45
printf ("y=%Lf3 ,y);
long int y=50000;
printf ("y=%ld3 ,y); y = 50000
printf ("y=%d",y); y=902
printf ("y=%.6d",y); y=000902
char nazwa[]="Microsoft";
printf ("%.5s", nazwa); Micro
Przyjmowane precyzje domyślne:
1 - dla znaków typu d, i ,o, u, x, X
6 - dla znaków typu e, E, f
- wszystkie cyfry znaczące dla znaków typu G,g
- Å‚aÅ„cuchy sÄ… drukowane do pierwszego znaku żÿ\0żÿ., znaków c nie dotyczy.
Jeśli wartość zajmuje mniej niż n znaków szerokość pola jest uzupełniana dodatkowymi spacjami
z lewej lub prawj strony w zależności od ustawionej flagi.
Funkcja scanf()
Funkcja scanf() służy do realizacji formatowanego wejścia. Składnia tej funkcji jest
następująca:
int scanf (const char* format [,address, ...]);
Parametr format wskazuje tzw. łańcuch formatujący. łańcuch ten zawiera sekwencje
określające typy wprowadzanych danych.
Funkcja wczytuje znaki ze standardowego wejścia, interpretuje je zgodnie ze specyfikacjami
zawartymi w formacie i zapamiętuje wyniki w miejscach określonych przez pozostale argumenty.
Argumenty muszą być adresami, określają adres obszaru pamięci gdzie dane mają być
umieszczone.
int i,j;
scanf("%d%d", &i, &j);
Ogólny format sekwencji formatującej przedstawia się następująco:
%[*][szerokość][h|l|L] znak-typu.
* oznacza, że dane pole zostanie odczytane ale nie zostanie zapamiętane we
wskazanym miejscu
szerokość określa maksymalną liczbę znaków danego pola
znak-typu tak jak opisane w funkcji printf(), dodatkowo można używać dużych liter:
D, O, I, U
scanf ("%d,%d,%d", &d, &m, &r); - wprowadzane dane oddzielane muszą być przecinkami.
float f;
scanf ("%5f", &f); wprowadzamy 1234567 printf ("f=%f", f); f=12345.0
char tab[20];
scanf ("%7s", tab); wprowadzamy Wolszczan printf ("s=%s", tab); s=Wolszcz
Funkcja gets(), puts()
char *gets (char *s); // #include
Funkcja odczytuje znaki ze standardowego strumienia wejściowego (stdin) i umieszcza je w łańcuchu s;
char znaki[20];
gets (znaki);
Czytanie jest przerywane po napotkaniu znaku końca wiersza, ktry zostaje zamieniony na
znak końca łańcucha(NULL).
int puts (const char *s);
char znaki[20]=3 Przykład wyprowadzania łańcucha na ekran3 ;
puts (znaki);
Ekran: Przykład wyprowadzania łańcucha na ekran
Strumienie predefiniowane C++
Wprowadzanie i wyprowadzanie informacji można potraktować jako strumień bajtów
płynący od zródła do ujścia. Jeśli chcemy zmiennej x nadać wartość wczytaną z klawiatury, wtedy
strumień bajtów płynie od urządzenia zewnętrznego - klawiatura do tego miejsca w pamięci
przeznaczonego dla zmiennej x.
Dla operacji we/wy kompilator predefiniuje kilka strumieni (predefiniuje czyli zakłada
stumień, otwiera strumień i po zakończeniu programu zamyka strumień) : cout, cin, cerr.
Aby skorzystać z tych strumieni w programie trzeba umieścić dyrektywę:
#include podobnie jak dla C .
Ze strumieniem wyjściowym cout został stowarzyszony operator <<
<< insert operator (put to wstaw do strumienia cout)
Ze strumieniem wyjściowym cin został stowarzyszony operator >>
>> extract operator (get from pobierz ze strumienia cin )
Przykład
#include
void main(){
int x = 123;
cout<}
Można wysyłać różne typy zmiennych i stałych przy pomocy jednej instrukcji np.
int x=123;
cout<<"Wartość x = "<< x <<'.'
W przykładzie tym, za pomocą jednej instrukcji przesłano na ekran napis Wartość x =,
wartość zmiennej i pojedynczy znak kropki. Na ekranie pojawi się napis: Wartość x = 123.
Poszczególne typy oddzielone są operatorami <<.
W C++ ze strumieniem cout współpracuje zestaw manipulatorów dec, oct, hex. Zmieniają
one bieżący format dla całkowitego argumentu.
Przykład
#include
main(){
int x=123;
cout< < <}
Przykład pokazuje jak można wyświetlić wartość całkowitą w trzech systemach liczbowych:
dec, oct, hex. Wynik działania programu to :123 173 7b.
Ze strumieniem wejściowym cin został stowarzyszony operator >>, odpowiadający za wczytanie
informacji ze strumienia wejściowego (którego początek jest na klawiaturze), czyli program
Przykład .
void main(){
int x;
cout<<"wprowadz wartość x :\n";
cin>>x; // >> pobieranie ze strumienia płynącego z klawiatury
cout<<"wartość x = "<}
powoduje wczytanie ze strumienia wejściowego (klawiatury) wartości do zmiennej x.
Jak widać operacje we/wy dla standardowych typów realizowane są bardzo prosto. Nie
musimy pamiętać o formacie wprowadzania i wyprowadzania wyników, a strumienie cout i cin
interpretują je prawidłowo. Trochę trudniej przedstawiają się te operacje dla typów zdefiniowanych
przez użytkownika, ale o tym opowiemy dużo pózniej.
Mamy również możliwość specyfikacji szerokości pola, precyzji i sposobu wypełniania
pola. Do tego celu służą funkcje składowe klasy o nazwie ios. Są nimi:
int width (int) - określa minimalny rozmiar pola, dotyczy tylko jednej następnej operacji
we/wy
int width () - zwraca bieżący rozmiar pola
int precission (int) - dokładność wypisywania liczb zmiennoprzecinkowych.
Przez domniemanie=6. Efekt trwały.
int precission() - zwraca bieżąca wartość precyzji
int fill (int) - znak wypełniający obszar. Efekt trwały
int fill () - podaje bieżący parametr.
Przykłady wykorzystania funkcji i manipulatorów formatujących
int liczba;
cout.width (9); - musi być wywołana przed operacją na strumieniu
cout.fill (żÿ*żÿ);
cout<char string[12];
cin.width(11);
cin>>string - nie ma wpływy na liczby, a jedynie na stringi. Zapobiega przekraczaniu zakresu
char napis[7];
cin.width (sizeof(napis));
cin>>napis; //1 miejsce jest przeznaczane na żÿ\0żÿ
Odpowiednikiem tych funkcji są manipulatory które można wstawić do strumienia:
setw (długość) <=> cout.width (dlugosc)
setfill (znak) <=> cout.fill (znak)
setprecision <=> cout.precision (liczba);
setw(9); setfill (żÿ*żÿ); setprecision(2); // muszÄ… być umieszczone w strumieniu
setprecision(n); - działa do odwołania
setfill (żÿ*żÿ); - dziaÅ‚a do odwoÅ‚ania.
setw(n); - dla następnej wyprowadzanej wartośći.
liczba=67.237;
cout<< setw(9) << setfill (żÿ*żÿ) << setprecision(2)<cout< Porównanie bibliotek stdio oraz iostream
Jak widać z powyższej analizy, język C++, wprowadził znaczne uproszczenia w realizacji
mechanizmów we/wy. Ponadto, biblioteka stdio ma wiele wad, które zniwelowały w/w
mechanizmy. Należą do nich między innymi:
1. printf(), scanf() są funkcjami ze zmienną ilością argumentów. Kompilator nie ostrzega więc o przypadku
niedostosowania formatu do listy argumentów np.:
printf(3 %i %f %d3 , a, b);
2. nie są kontrolowane przypadki złego typu argumentów (patrz wyżej)
3. dla funkcji scanf, jeśli liczba argumentów jest mniejsza niż w formacie - efekt jest nie zdefiniowany, w przeciwnym
przypadku, dane są pobierane choć nie zdefiniowane.
Mieszanie bibliotek
Pomiędzy predefiniowanymi strumieniami stdio.... cout..... nie ma żadnej łączności. W związku z
tym, gdy mieszamy operacje we/wy realizowane mechanizmami C i C++, możemy spodziewać się
nieprzewidzianych efektów z ich realizacją.
cout<<żÿtekst1żÿ;
printf(żÿtekst2żÿ);
cout<<żÿtekst3żÿ;
printf(żÿtekst4żÿ);
Powyższy zapis nie musi wcale prowadzić do oczekiwanego rezultatu: tekst1tekst2tekst3tekst4.
Może być np.
tekst1tekst3tekst2tekst4 lub odwrotnie.
Strumień cout jest buforowany a stdout nie. Inna jest więc zasada wypisywania. Język C++
przewidział mechanizm synchronizujący oba te strumienie.
Jest nim funkcja ios::sync_with_stdio(); Powinna być użyta na początku programu. Użycie tej
funkcji powoduje jednak utratę szybkości, ponieważ strumienie przestają byc buforowane.
Wyszukiwarka
Podobne podstrony:
Wykład 05 Opadanie i fluidyzacja
Techniki negocjacji i mediacji w administracji wykłady 05 11 2013
wykład 05
Analiza Finansowa Wykład 05 02 12 09
wyklad 05 03 2011
Wykład 05 Pręt i Układ Prętów
Wykład 05 Narzędzia i maszyny do umieszczania sadzonek w glebie
wyklad 05
Konstrukcje metalowe Sem[1][1] VI Wyklad 05
logika wyklad 05
Wyklad 05 dyrektywa o informacji srodek b
Wyklad 05 14 15 GW
wyklad 7 05
więcej podobnych podstron