Prościej już być nie może, niż na GameCreatorze! ;-)
Witaj znowu :-) W poprzedniej lekcji powiedziałem Ci, jak rozpocząć twój program i jak go zakończyć. Jednak czym byłby Twój program bez świata zewnętrznego? [Albo może czym byłby świat zewnętrzny bez Twojego programu? ;-D] W lekcji, którą właśnie czytasz, dodamy w programie możliwość komunikacji ze światem zewnętrznym. Wreszcie napiszesz program, który będzie robił coś widocznego ;-) Uruchom swoje środowisko programistyczne i otwórz projekt z poprzedniej lekcji, bo będziemy go rozbudowywać.
Każdy program [nawet najprostszy] może korzystać z prostego mechanizmu "rozmowy" ze światem zewnętrznym. Ten najprostszy mechanizm to standardowe wejście/wyjście. Jest to najbardziej prymitywny mechanizm, jednak bardzo uniwersalny i do większości celów wystarczający. Standardowe wejście służy do przyjmowania danych od użytkownika, a standardowe wyjście do pokazywania mu wyników [jest jeszcze kilka innych takich "kanałów", jednak narazie nie będą nam potrzebne].
Standardowe wejście jest zwykle powiązane z klawiaturą, a standardowe wyjście z ekranem tekstowym, które razem nazywane są konsolą. Dawniej [zanim wymyślono monitory] standardowe wyjście prowadziło do drukarki lub dalekopisu ;-P Obecnie systemy okienkowe "symulują" konsolę w postaci okienka tekstowego [np. słynne "okienko MS-DOS" ;-P], z którym wiążą standardowe wejście/wyjście.
Tu drobna uwaga. Windows tworzy dla programu okno konsoli, jednak po skończeniu programu od razu zamyka to okienko ;-P więc możesz nie zdążyć zobaczyć wyników programu. Z kolei Linux w trybie graficznym nie tworzy okna tekstowego [zostawia decyzję użytkownikowi], więc to, co wypisuje się na standardowe wyjście, może być niewidoczne. Żeby zaradzić tym problemom, najlepiej jest odpalać programy w już otwartym oknie konsoli.
Standardowe wejście/wyjście można też przekierowywać do pliku na dysku. Ponieważ w systemach unixowych wszystko jest plikiem, można na nich powiązać wejście/wyjście także z drukarką, portem USB, kartą dźwiękową, albo nawet puścić przez sieć do odległego komputera :-) Jak widzisz, w tym prostym mechaniźmie drzemią ogromne możliwości ;-D
Żeby współpraca z tak szeroką gamą różnych urządzeń była możliwa, standardowe wejście/wyjście działa w sposób "strumieniowy". Nazwa wzięła się stąd, że znaki tekstu są wysyłane/odbierane "taśmowo", jeden za drugim, tak jakby płynęły strumieniem ;-) Czasami spotkasz się z nazwą strumienie wejścia/wyjścia, więc przygotuj się na to ;-)
Oczywiście nie każdy program potrzebuje korzystać ze strumieni wejścia/wyjścia. Dlatego nie jest to częścią samego języka C++. Zamiast tego jest częścią jego Biblioteki Standardowej, czyli takiej, którą posiada każdy kompilator C++. Biblioteka standardowa jest automatycznie linkowana z Twoim programem, więc nie musisz tego robić ręcznie. Aby jednak móc skorzystać ze strumieni wejścia/wyjścia, musisz zrobić coś jeszcze. Musisz w swoim programie wstawić tak zwany plik nagłówkowy.
Taki plik zawiera normalny kod źródłowy i zapoznaje kompilator z nazwami użytymi w bibliotece. Dołączając plik nagłówkowy, uczysz Twój kompilator nowych sztuczek ;-) Kompilator czyta sobie ten plik i poznaje nowe słowa, nowe polecenia, których od tej pory pozwoli Ci już używać w twoim programie, bo będzie je znał i nie będzie panikował, że może robisz coś źle ;-) Będzie też pilnował, czy używasz biblioteki we właściwy sposób. Jedna biblioteka może obsługiwać kilka rzeczy naraz, więc plik nagłówkowy określa także, z których możliwości biblioteki korzystasz.
Wszystko, co się wiąże z obsługą strumieni wejścia/wyjścia, znajduje się w nagłówku iostream
[ang. input/output stream
= strumień wejścia/wyjścia
]. Dopisz więc na samym początku Twojego kodu:
#include <iostream>
Jest to tak zwana dyrektywa preprocesora. Każda taka dyrektywa zaczyna się znakiem #
[płotkiem ;-)] i trwa do końca linii. Dyrektywy są przetwarzane jeszcze zanim kompilator dobierze się do tego pliku! [na etapie tzw. "preprocessingu", czyli wstępnego przygotowania kodu źródłowego do kompilacji.] Dawniej robił to osobny program, zwany preprocesorem, teraz jest on zwykle wbudowany w kompilator. W przyszłości poznasz więcej takich dyrektyw dla preprocesora, jednak narazie mamy ciekawsze rzeczy do poznania ;-)
Dyrektywa #include
nakazuje wstawić w tym miejscu [ang. include=wstaw] zawartość nagłówka iostream
. Efekt jest taki, jakby kod źródłowy z tego nagłówka został wpisany w miejscu dyrektywy. Kompilator zapozna się z nim i pozwoli Ci używać nazw w nim zawartych.
Nazwy plików nagłówkowych dla bibliotek podaje się w nawiasach ostrych ["dzióbkach" ;-J]. Kompilator będzie ich wtedy szukał w swoim katalogu z nagłówkami. Jeśli zamiast tego chcesz dołączyć własny plik nagłówkowy, który masz w katalogu ze swoim projektem, jego nazwę podajesz w cudzysłowach:
#include "mojplik.h"
Jak widzisz, twoje własne pliki nagłówkowe powinny mieć rozszerzenie .h
. To samo tyczy się innych bibliotek. Jedynie pliki nagłówkowe Biblioteki Standardowej nie mają rozszerzenia, bo są one szczególną częścią języka C++ i muszą się jakoś wyróżniać ;-)
Dobra, plik nagłówkowy dołączony, więc kompilator już wie, jak pisać po ekranie tekstowym :-) Teraz kolej na Ciebie ;-D
Wiesz już, że gdy wrzucisz coś do strumienia płynącego na standardowe wyjście, to pojawi się to na konsoli. Wiesz także, że Twój kompilator przeczytał sobie nagłówek iostream
i wie, co to są strumienie. Żeby skorzystać ze strumienia wyjściowego musisz jeszcze tylko wiedzieć, jaką nazwę ten strumień posiada ;-) No dobra, nie będę Cię dłużej trzymał w napięciu ;-D Rzuć okiem na poniższą instrukcję:
std::cout << "Siema, wiara!";
Nazwa cout
oznacza właśnie strumień wyjściowy :-) [od ang. console output
, czytaj "si ałt", a nie "śi ałt", bo trza być twardym a nie miętkim ;-D]. To jest właśnie jedna z nazw, która znajdowała się nagłówku iostream
.
Jak widzisz, jest ona poprzedzona przedrostkiem std::
. Jest tak dlatego, że nazwa cout
pochodzi z Biblioteki Standardowej. Wszystkie nazwy w tej bibliotece są umieszczone w tak zwanej przestrzeni nazw o nazwie std
. Twórcy Biblioteki Standardowej zrobili tak po to, żeby nazwy w niej zawarte nie kolidowały z nazwami wymyślanymi przez Ciebie. Dlatego każda nazwa z Biblioteki Standardowej będzie zaczynać się od std::
. Gdy dojdziesz już do lekcji o przestrzeniach nazw, wyjaśnię Ci to dokładniej i powiem też, co można zrobić, żeby nie pisać wszędzie tego std::
;-) A narazie używaj pełnej nazwy strumienia wyjściowego, czyli std::cout
.
Ale wróćmy narazie do tego, o czym jest ta lekcja. Powyższa instrukcja sprawia, że tekst "Siema, wiara!"
poleci, zgodnie z kierunkiem "strzałek" <<
, do strumienia wyjściowego [cout
] i popłynie sobie tym strumieniem prosto na ekran konsoli ;-) Zobacz jak wygląda nasz drugi program w całości:
#include <iostream> int main() { std::cout << "Siema, wiara!"; }
Sprawdź teraz, jak wygląda efekt działania takiego programu. Skompiluj go i uruchom. Jeśli Twoje środowisko programistyczne oferuje podgląd konsoli, skorzystaj z niego. Jeśli tworzy systemowe okienko konsoli, to powinieneś zobaczyć go zaraz po uruchomieniu. Niektóre środowiska będą go tam pokazywać, dopóki go nie zamkniesz [np. Code::Blocks poczeka, aż wciśniesz klawisz Enter]. Jeśli jednak okienko zamyka się od razu, to postaraj się uruchamiać programy w już otwartym oknie konsoli systemowej.
Efekt tego programu powinien wyglądać tak:
Siema, wiara!
Jeśli jest inny, to znaczy że pomyliły Ci się programy ;-D Możesz teraz chwilę sobie "podłubać" w tym kodzie. Na przykład zmień wyświetlany tekst na jakiś inny. Jak już się oswoisz z działaniem tego programu, zastanów się, co należałoby zrobić, żeby wyświetlić coś takiego:
Siema, wiara! Jak leci?
Hehe ;-) Domyślam się, że pierwszą myślą, jaka Ci przyszła do głowy, było dopisanie kolejnej instrukcji takiej jak ta poprzednia, czyli mniej więcej coś takiego:
#include <iostream> int main() { std::cout << "Siema, wiara!"; std::cout << "Jak leci?"; }
Jeśli tak, to na pewno zdziwiło Cię, że efekt takiego programu był trochę inny niż zamierzony:
Siema, wiara!Jak leci?
Dlaczego tak się stało? Czemu teksty pokazały się jeden za drugim? Odpowiedź jest prosta: bo nie kazaliśmy komputerowi przeskoczyć do kolejnej linijki! :-P No dobra, ale jak to zrobić? No cóż.. tego dowiesz się już z następnego odcinka ;-J