Prościej już być nie może, niż na GameCreatorze! ;-)
Stałe dosłowne to takie wartości stałe, które są podawane "dosłownie", bezpośrednio w kodzie źródłowym. Przy kompilacji są wplatane na stałe w Twój program, raz na zawsze [dopóki nie zmienisz ich w źródle i nie skompilujesz ponownie ;-J]. Mogą służyć jako wzorcowe wartości wpisywane do obiektów.
Są to takie jakby "gołe" wartości, bo zazwyczaj nie występują "luzem", tylko od razu są wsadzane do jakiegoś obiektu. Kompilator zazwyczaj może wogóle nie umieszczać ich nigdzie w pamięci komputera [nie tworzy z nich osobnych obiektów], tylko od razu wpisuje je w treść instrukcji maszynowych, generuje bezpośrednio w rejestrach procesora lub w pamięci przydzielonej pod jakiś obiekt.
Jedynym wyjątkiem od tej reguły są stałe tekstowe, ale o tym opowiem Ci innym razem, bo narazie nie jest to dla nas ważne ;-J
Każda stała dosłowna ma ponadto swój typ [jak większość rzeczy w języku C++ ;-)]. W tej lekcji pokażę Ci jak wpisywać w kodzie źródłowym stałe dosłowne różnego typu. Jako przykład będziemy je wysyłać do strumienia wyjściowego i patrzeć, co nam wyjdzie ;-) Zaczniemy od liczb całkowitych.
Służą do umieszczania w kodzie źródłowym wartości całkowitych. Załóżmy, że chcesz wypisać na standardowe wyjście liczbę 77
. W tym celu możesz posłużyć się takim kawałkiem kodu:
std::cout << 77; //Wypisze liczbę 77
Jak widzisz, sprawa jest prosta ;-) Ta liczba to właśnie jest wartość stała podana dosłownie. Gdy wysyłasz ją do strumienia, to rozpoznaje on jej typ i rozumie, że powinien wypisać dwie siódemki. Sam zajmie się zamianą wartości liczbowej na odpowiadający jej tekst.
Taka wartość jest typu int
, a jeżeli zakres tego typu nie wystarcza, wtedy używany jest typ long int
. Jeśli jednak potrzebujesz wymusić typ long int
, wystarczy że dodasz na końcu liczby literę "L" [jak "long" ;-)]. Obojętne, czy napiszesz małą czy wielką, jednak osobiście doradzam Ci stosować wielką, bo mała za bardzo przypomina jedynkę ;-P Przykład:
std::cout << 77L; //Wartość 77 będzie typu long int
Podobnie jeśli chcesz, by liczba była traktowana jako bez znaku, dodajesz na końcu literę "U" [jak "unsigned"], małą lub wielką. Możesz dowolnie mieszać ze sobą te dwie literki na końcu, by uzyskać wymagany typ. Przykład:
std::cout << 77uL; //Wartość 77 będzie typu unsigned long int
Normalnie cyfry w takiej liczbie są traktowane jako cyfry dziesiętne. Jeśli jednak zaczniesz liczbę od cyfry 0
, pozostałe cyfry będą traktowane jako cyfry w systemie ósemkowym [oktalnym], w którym używane jest tylko osiem cyfr, od 0
do 7
. Przykład:
std::cout << 033; //Wartość 33 ósemkowo to 3*8 + 3, czyli 27 dziesiętnie
Jeśli zaś zaczniesz liczbę od sekwencji 0x
, oznacza to liczbę w zapisie szesnastkowym [heksadecymalnym] i w jej skład mogą wtedy wchodzić cyfry od 0
do 9
oraz litery od A
do F
[małe lub duże], mające wartości od 10 do 15 ;-J Przykład:
std::cout << 0x33; //Wartość 33 szesnastkowo to 3*16 + 3, czyli 51 dziesiętnie
Wartości zmiennoprzecinkowe również możesz podawać dosłownie w kodzie źródłowym. Przykład:
std::cout << 3.14159; //Słynna liczba Pi, zwana Ludolfiną ;-) (przybliżenie)
Tym razem strumień też rozpozna, że posyłasz mu liczbę typu zmiennoprzecinkowego, więc odpowiednio ją sformatuje w formie tekstu. Zauważ przy tym, że strumień wyświetla tylko kilka cyfr znaczących, a jak mu się nie mieści, to zaokrągla. Można to zachowanie zmienić, opowiem o tym w lekcji o manipulatorach strumienia.
Wartości dosłowne zmiennoprzecinkowe są rozpoznawane po tym, że zawierają kropkę dziesiętną. Dlatego można użyć skróconego zapisu: gdy np. część całkowita wynosi 0
, nie trzeba tego zera pisać. Kompilator domyśli się tego, gdy zobaczy kropkę dziesiętną ;-)
std::cout << .7; //To samo co 0.7, czyli za mało na trzech ;-D
Podobnie można zrobić, gdy część ułamkowa jest zerowa. Przykład:
std::cout << 2.; //To samo, co 2.0
W notacji wykładniczej liczba jest zapisywana jako mantysa i wykładnik. Przykładowo liczba 0.012
może być też zapisana jako ułamek 1.2
[mantysa] pomnożona przez dychę podniesioną do potęgi -2 ;-) [wtedy to -2 jest wykładnikiem], co daje nam 1.2*10-2. Mądrej głowie dość po słowie ;-) więc wystarczy napisać samą mantysę i wykładnik, rozdzielając je literą "e" [jak exponent
, czyli z ang. wykładnik
]. Przydaje się to, gdy liczba jest bardzo mała, lub bardzo duża i w zwykłej notacji byłaby za długa. Przykład:
std::cout << 6.6260693e-34; //Stała Plancka, fizycy kwantowi ją kochają ;-)
Normalnie stałe dosłowne zmiennoprzecinkowe są typu double
. Jeśli chcesz wymusić typ float
, wystarczy że dodasz na końcu literę "F" [małą lub wielką]. Przykład:
std::cout << 1.23f; //Będzie typu float
Podobnie jeśli dodasz literę L
, stała dosłowna będzie miała typ long double
. Przykład:
std::cout << 1.23L; //Będzie typu long double
Stałe dosłowne typu logicznego mamy w języku C++ tylko dwie, oznaczane słowami kluczowymi true
i false
. Pierwsza oznacza wartość "prawda", a druga oznacza wartość "fałsz". Jak nietrudno zgadnąć, takie stałe są typu logicznego, czyli bool
;-) Przykład:
std::cout << true;
Służą do umieszczania znaków w kodzie programu, w postaci dosłownej [np. żeby wypisać je na konsoli]. Takie znaki umieszcza się w apostrofach. Wartością takiej stałej jest kod liczbowy znaku podanego w apostrofach. Przykład wypisania na konsoli znaku %
:
std::cout << '%'; Wypisze procent % na konsoli
Taka stała znakowa jest typu char
. Jeśli poprzedzisz ją literą L
[dużą lub małą], jej typem będzie wtedy wchar_t
. Przykład:
std::cout << L'%'; //Stała znakowa będzie typu wchar_t
Z ich pomocą można umieszczać w kodzie programu całe sekwencje znaków w postaci dosłownej, jeden za drugim :-) Taką sekwencję znaków umieszcza się w cudzysłowach. Przykład, który zobaczysz poniżej, pewnie wyda ci się znajomy:
std::cout << "Ala ma kota";
I nic dziwnego! Już przecież używaliśmy takich stałych tekstowych, nie wiedząc jednak, że to są one ;-) Teraz już będziesz to wiedzieć, i dowiesz się też na ich temat zupełnie nowych rzeczy :-) Na przykład że taka stała tekstowa musi się mieścić w jednej linijce kodu źródłowego. Co zrobić, jeśli chcesz wypisać dłuższy tekst? No więc, możesz zakombinować tak:
std::cout << "To jest bardzo długi tekst, który ciągnie się przez kilka" " linijek. To bardzo przydatna sztuczka i warto z niej" " korzystać ;-)";
Jeśli kompilator napotka kilka stałych tekstowych nie oddzielonych żadnym widocznym znakiem, to poskleja je sobie w jedną długą stałą tekstową :-)
No dobra, a jakiego typu są stałe tekstowe? Hmm.. Są one tablicami znaków typu char
[czym są tablice wyjaśnię Ci dokładniej w lekcji o tablicach, bo to temat na dłuższą opowieść ;-J]. Jeśli przed stałą tekstową dopiszesz literę L
, to poszczególne jej znaki będa miały typ wchar_t
.
Po krótkiej zabawie pewne zrodziło się w twojej głowie pytanie: Jak wypisać na konsoli sam apostrof lub sam cudzysłów? Kompilator traktuje go jako część składni, a nie jako znak. Czy to oznacza, że samego apostrofu nie da się wypisać? :-P
Oczywiście że się da! ;-) Cóż to byłby za język, gdyby się nie dało? :-P Trzeba tylko odpowiednio to kompilatorowi zasygnalizować. Do tego celu służy tak zwany backslash code. Nazwa wzięła się stąd, że używa znaku backslash. Spójrz:
std::cout << '\''; Wypisze pojedynczy apostrof '
Kompilator widzi najpierw otwierający apostrof, więc już wie, że wpisujesz stałą znakową. Następnie widzi znak backslash, który mówi mu: "Uważaj! Następny znak potraktuj specjalnie!", więc ostrożnie przygląda się temu następnemu znakowi. Widzi apostrof, jednak wie, że miał traktować go w specjalny sposób, a nie jako koniec stałej znakowej :-) Uzna go więc za treść stałej znakowej, a dopiero następny apostrof uzna za jej zakończenie. Taki trick nazywa się czasem cytowaniem znaku, bo informujesz kompilator, że znak jest podany dosłownie, a nie jako część składni. Działa zarówno dla stałych znakowych, jak i tekstowych. Odkąd backslash zyskał specjalne znaczenie, on sam także musi być cytowany. Wygląda to wtedy tak:
std::cout << '\\'; //Wypisze pojedynczy backslash \ na konsoli
Warto to wiedzieć, jeśli zechcesz napisać stałą tekstową oznaczającą ścieżkę do pliku w systemie Windows. Przykład:
std::cout << "C:\\katalog\\plik.txt"; //Ścieżka C:\katalog\plik.txt
W poprzedniej lekcji obiecałem, że pokażę Ci jak przerzucać tekst do następnej linijki. Teraz dotrzymam tej obietnicy ;-) Backslash code pozwala bowiem wypisywać znaki, których nie da się wpisać z klawiatury [czyli np. niedrukowalne znaki sterujące ASCII]. Wystarczy że po backslashu podasz kod znaku w postaci liczby ósemkowej:
std::cout << "ABC\12DEF"; //12 ósemkowo to kod znaku nowej linii
Można też używać kodów w postaci liczb szesnastkowych, dorzucając literę "x" [małą lub wielką] po backslashu:
std::cout << "ABC\x44"; //44 ósemkowo to kod litery D
Kody znaków czasami się nie sprawdzają, bo mogą się "zlewać" z dalszym tekstem [np. jeśli po kodzie znaku jest litera, która może być potraktowana jako cyfra szesnastkowa]. Wtedy można posłużyć się taką oto sztuczką:
std::cout << "ABC\xA" "DEF";
Cyfra szesnastkowa A
to kod znaku nowej linii. Gdyby tuż po tym kodzie był znak D
, mógłby zostać uznany za kolejną cyfrę szesnastkową. Dlatego rozdzieliłem to na dwa kawałki, które już nie są mylące ;-) a kompilator i tak je sobie sklei.
Niektóre znaki specjalne, takie jak znak nowej linii, tabulacji itp., są stosowane szczególnie często. Pamiętanie ich cyfrowych kodów byłoby uciążliwe, a długie sekwencje cyferek są mało czytelne. Dlatego niektóre znaki kontrolne dostały specjalne, skrócone kody literowe. Oto one:
\n - nowa linia [ang.New Line] czyli wysunięcie linii [ang.Line Feed] \r - powrót na początek linii [ang.Carriage Return] \t - tabulacja pozioma [ang.Tabulation] \v - tabulacja pionowa [ang.Vertical Tabulation] \f - wysunięcie strony [ang.Form Feed] \b - skasowanie znaku [ang.Backspace] \a - sygnał [ang.Alert]
Możesz więc łatwo wypisać tekst w dwóch linikach w taki sposób:
std::cout << "Linia 1\nLinia 2";
A w ramach zadania domowego ;-) sprawdź, co wyświetli poniższy kod:
std::cout << "Ala ma kota\b\bnia";
I to już koniec tej przydługiej lekcji ;-J W następnym odcinku nauczymy komputer liczyć ;-)