Od "to się kompiluje" do "rozumiem to"
Na poprzedniej stronie plik źródłowy zamienił się w działający program dzięki kompilatorowi. Teraz zwolnimy i przyjrzymy się temu, co właściwie było w tym pliku. Każdy program w C++ składa się z tych samych kilku elementów strukturalnych, a gdy potrafisz je nazwać, nieznany plik .cpp przestaje wyglądać jak szum.
Oto kompletny program do uruchomienia. Przeczytaj go raz, a potem rozbierzemy go linia po linii.
Pięć znaczących linii i każda wykonuje konkretne zadanie. Przejdźmy przez nie.
Linia #include
#include <iostream>
Ta linia dołącza nagłówek <iostream>, aby udostępnić funkcje wejścia i wyjścia, takie jak cout. #include to dyrektywa preprocesora: działa przed właściwą kompilacją i w praktyce wkleja zawartość nagłówka do twojego pliku.
Dwie rzeczy wyróżniają linie #include:
- Zaczynają się od
#, co oznacza je jako dyrektywy preprocesora. - Nie kończą się średnikiem. To jedyny częsty wyjątek od nawyku "każda linia kończy się
;", który zaraz sobie wyrobisz.
Jeśli użyjesz cout, ale zapomnisz o #include <iostream>, kompilator nie będzie wiedział, czym jest cout, i dostaniesz błąd w rodzaju 'cout' was not declared in this scope. Rozwiązaniem prawie zawsze jest brakujący include.
Funkcja main
int main() {
// ...
return 0;
}
main to miejsce, w którym zaczyna się twój program. Gdy uruchamiasz skompilowany program, wykonanie rusza od pierwszej linii wewnątrz main i kończy się, gdy main zwraca wartość. Każdy program w C++ ma dokładnie jedną funkcję main, ani więcej, ani mniej.
Elementy:
int:mainprzekazuje systemowi operacyjnemu liczbę całkowitą. Zwyczajowo0oznacza "zakończono pomyślnie".main(): nazwa, a po niej nawiasy na parametry (tu puste).{ ... }: klamry otaczają ciało, czyli instrukcje, które się wykonują.return 0;: kończymaini zgłasza sukces. Jeśli go pominiesz, C++ potraktujemaintak, jakby zwróciła0za ciebie, ale jawny zapis czyni intencję oczywistą.
Instrukcje i średnik
Instrukcja to jedno kompletne polecenie. W C++ każda instrukcja kończy się średnikiem:
C++ całkowicie ignoruje podziały linii i dodatkowe spacje. Kompilatorowi jest wszystko jedno, czy instrukcje stoją w jednej linii, czy w dziesięciu: to ; mówi mu, gdzie kończy się każda instrukcja. Dla kompilatora te trzy zapisy są identyczne:
int a = 1; int b = 2;
int a = 1;
int b = 2;
int
a
= 1;
Ta swoboda wiąże się z najczęstszą pułapką początkujących: zapomnianym średnikiem. Zobacz, co się tu dzieje.
int x = 5 // <-- brak średnika
int y = 10;
Dostaniesz błąd w rodzaju expected ';' before 'int'. Zwróć uwagę na haczyk: kompilator orientuje się, że coś jest nie tak, dopiero gdy dochodzi do następnej linii, więc zgłoszony numer linii często wskazuje jedną linię poniżej prawdziwej pomyłki. Gdy błąd mówi o brakującym ;, sprawdź linię nad tą z komunikatu.
Klamry wyznaczają bloki
Tam, gdzie niektóre języki grupują kod wcięciami, C++ używa klamer { }. Wszystko między parą pasujących klamer to jeden blok. Używają ich ciała funkcji, pętle i instrukcje if:
Dwie linie w klamrach if wykonują się tylko wtedy, gdy warunek jest prawdziwy. Ostatnie cout jest poza klamrami, więc wykonuje się zawsze.
Ponieważ strukturę wyznaczają klamry, a nie wcięcia, C++ nie zmusza cię do wcinania kodu. Mimo to rób to: wcięcia to sposób, w jaki ludzie odczytują strukturę wyznaczoną przez klamry. Częsty błąd to niesparowana klamra: każde { potrzebuje zamykającego }. Jeśli o jednym zapomnisz, kompilator zwykle zgłasza błąd przy końcu pliku (expected '}' at end of input), daleko od miejsca, w którym faktycznie nastąpiła pomyłka. Liczenie klamer albo zdanie się na edytor, który je paruje, oszczędza mnóstwo zamieszania.
Wypisywanie przez cout i <<
cout pojawiło się już kilka razy. To standardowy strumień wyjścia, a wartości wysyłasz do niego operatorem << (czytaj go jako "włóż to do wyjścia"):
Możesz łączyć << w łańcuch, aby wypisać kilka rzeczy po kolei. endl kończy linię (i dodatkowo opróżnia bufor); sekwencja ucieczki "\n" to lżejszy sposób na wypisanie nowej linii. W prostych programach oba są w porządku.
A co z tym using namespace std; na górze? Nazwy z biblioteki standardowej żyją w przestrzeni nazw std, więc pełna nazwa to std::cout. Jednorazowe using namespace std; pozwala pominąć przedrostek std:: i pisać po prostu cout. To wygodne w krótkich przykładach, ale w większych projektach wiele zespołów woli jawne std::cout, aby uniknąć konfliktów nazw, więc nie zdziw się, widząc oba zapisy.
Potrafisz już czytać szkielet każdego programu
Dyrektywy include na górze, funkcja main jako punkt wejścia, instrukcje zakończone średnikami, klamry grupujące kod w bloki i cout << do wypisywania: ten szkielet znajduje się niemal w każdym pliku C++, jaki kiedykolwiek otworzysz. Reszta języka to szczegóły nałożone na te kilka kształtów. Gdy program wygląda groźnie, znajdź najpierw main, a potem czytaj instrukcje po kolei; struktura cię poprowadzi.
Dalej: komentarze
Na razie każda linia twoich programów to kod, który czyta kompilator. Następnie dodamy linie, które kompilator celowo ignoruje, czyli komentarze, aby zostawiać notatki sobie i innym czytelnikom. Zobaczysz jednoliniową formę // i blokową /* ... */, a także to, kiedy wybrać którą.
Najczęściej zadawane pytania
Dlaczego każda instrukcja w C++ potrzebuje średnika?
C++ ignoruje podziały linii i białe znaki, więc potrzebuje jawnego znacznika, gdzie kończy się jedna instrukcja, a zaczyna następna. Tym znacznikiem jest średnik ;. Brakujący średnik to najczęstszy błąd kompilacji u początkujących, a zgłoszony numer linii często wskazuje linię po tej, w której go zabrakło.
Co robi int main() w C++?
main to funkcja, od której program zaczyna działanie: wykonanie rusza od jej pierwszej linii i kończy się, gdy funkcja zwraca wartość. Każdy program w C++ potrzebuje dokładnie jednej funkcji main. int oznacza, że przekazuje ona systemowi operacyjnemu całkowity kod statusu, gdzie 0 zwyczajowo oznacza sukces.
Czy muszę pisać std:: przed cout?
Albo piszesz std::cout (pełna nazwa), albo dodajesz raz na górze using namespace std; i potem piszesz po prostu cout. Pełna nazwa jest bezpieczniejsza w większych plikach; using namespace std; to popularny skrót w małych przykładach i tutorialach.