От «оно компилируется» к «я могу это прочитать»
На предыдущей странице вы взяли исходный файл и превратили его в работающую программу с помощью компилятора. Теперь мы притормозим и посмотрим, что на самом деле было в этом файле. Каждая программа на C++ построена из одного и того же набора структурных элементов, и как только вы научитесь их называть, незнакомый файл .cpp перестанет выглядеть как шум.
Вот полная, готовая к запуску программа. Прочитайте её один раз, а затем мы разберём её строку за строкой.
Пять значимых строк, и каждая из них выполняет конкретную работу. Пройдёмся по ним.
Строка #include
#include <iostream>
Эта строка подключает заголовок <iostream>, чтобы вы могли пользоваться средствами ввода-вывода, такими как cout. #include - это директива препроцессора: она выполняется до настоящей компиляции и, по сути, вставляет содержимое этого заголовка в ваш файл.
Две вещи делают строки #include особенными:
- Они начинаются с
#, что помечает их как директивы препроцессора. - Они не заканчиваются точкой с запятой. Это и есть распространённое исключение из привычки «каждая строка заканчивается на
;», которую вы вот-вот выработаете.
Если вы используете cout, но забываете #include <iostream>, компилятор не будет знать, что такое cout, и вы получите ошибку вроде 'cout' was not declared in this scope. Решение почти всегда - недостающее включение.
Функция main
int main() {
// ...
return 0;
}
main - это функция, с которой начинается ваша программа. Когда вы запускаете скомпилированную программу, выполнение начинается с первой строки внутри main и останавливается, когда main возвращает значение. В каждой программе на C++ ровно одна main - ни больше, ни меньше.
Составные части:
int-mainвозвращает целое число операционной системе. По соглашению0означает «завершилось успешно».main()- имя, за которым следуют скобки для параметров (здесь пустые).{ ... }- фигурные скобки заключают тело: операторы, которые выполняются.return 0;- завершаетmainи сообщает об успехе. Если вы его опустите, C++ ведёт себя так, будтоmainвернула0за вас, но если написать его, ваше намерение становится очевидным.
Операторы и точка с запятой
Оператор - это одна полная инструкция. В C++ каждый оператор заканчивается точкой с запятой:
C++ полностью игнорирует переводы строк и лишние пробелы. Компилятору всё равно, размещаете ли вы операторы в одной строке или в десяти - именно ; сообщает ему, где заканчивается каждый оператор. Все три варианта для компилятора одинаковы:
int a = 1; int b = 2;
int a = 1;
int b = 2;
int
a
= 1;
Эта свобода сопровождается самой частой ловушкой для новичков: забытой точкой с запятой. Посмотрите, что происходит здесь.
int x = 5 // <-- нет точки с запятой
int y = 10;
Вы получите ошибку вроде expected ';' before 'int'. Обратите внимание на подвох: компилятор осознаёт, что что-то не так, только когда доходит до следующей строки, поэтому указанный номер строки часто указывает на строку ниже фактической ошибки. Когда ошибка упоминает пропущенную ;, проверяйте строку выше той, что в сообщении.
Фигурные скобки определяют блоки
Там, где одни языки используют отступы для группировки кода, C++ использует фигурные скобки { }. Всё между парой соответствующих скобок - это один блок. Тела функций, циклы и операторы if используют их:
Две строки внутри скобок условного оператора if выполняются только когда условие истинно. Последний cout находится вне скобок, поэтому он выполняется всегда.
Поскольку структуру определяют фигурные скобки, а не отступы, C++ не заставляет вас делать отступы. Но делать их всё равно стоит: отступы - это то, как люди читают структуру, которую определяют скобки. Распространённая ошибка - непарная скобка: каждой { нужна закрывающая }. Если вы забудете одну, компилятор обычно сообщает об ошибке ближе к концу файла (expected '}' at end of input), далеко от места, где вы на самом деле ошиблись. Подсчёт скобок или использование редактора, который сопоставляет их за вас, избавляет от множества недоразумений.
Вывод с помощью cout и <<
Вы уже видели cout несколько раз. Это стандартный поток вывода, и вы отправляете в него значения с помощью оператора << (читайте его как «помести это в вывод»):
Вы можете объединять << в цепочку, чтобы вывести несколько вещей подряд. endl завершает строку (а также сбрасывает буфер); управляющая последовательность "\n" - более лёгкий способ вывести перевод строки. Для простых программ подойдёт любой вариант.
Насчёт того using namespace std; в начале: имена из стандартной библиотеки находятся в пространстве имён std, поэтому полное имя - std::cout. Если написать using namespace std; один раз, можно опускать префикс std:: и писать просто cout. Это удобно в коротких примерах, но в крупных проектах многие команды предпочитают явный std::cout, чтобы избежать конфликтов имён, так что не удивляйтесь, встречая оба варианта.
Теперь вы можете прочитать скелет любой программы
Включения в начале, функция main как точка входа, операторы, заканчивающиеся точками с запятой, скобки, группирующие код в блоки, и cout << для вывода - этот скелет есть почти в каждом файле C++, который вы когда-либо откроете. Остальная часть языка - это детали, надстроенные поверх этих немногих форм. Когда программа выглядит пугающе, сначала найдите main, затем читайте операторы по порядку; структура вас направит.
Далее: комментарии
Сейчас каждая строка в ваших программах - это код, который читает компилятор. Дальше мы добавим строки, которые он намеренно игнорирует - комментарии - чтобы вы могли оставлять заметки себе и другим читателям. Вы увидите однострочную форму // и блочную форму /* ... */, а также узнаете, когда какая из них уместна.
Часто задаваемые вопросы
Почему каждый оператор в C++ требует точку с запятой?
C++ игнорирует переводы строк и пробелы, поэтому ему нужна явная отметка о том, где заканчивается один оператор и начинается следующий. Эта отметка - точка с запятой ;. Пропущенная точка с запятой - самая частая ошибка компиляции у новичков, и указанный номер строки часто соответствует строке после той, где вы её забыли.
Что делает int main() в C++?
main - это функция, с которой программа начинает выполняться: выполнение стартует с её первой строки и завершается, когда она возвращает значение. В каждой программе на C++ должна быть ровно одна main. int означает, что она возвращает целочисленный код состояния операционной системе, где 0 по соглашению означает успех.
Обязательно ли писать std:: перед cout?
Можно либо писать std::cout (полное имя), либо один раз добавить using namespace std; в начале и потом писать просто cout. Полная форма безопаснее в крупных файлах; using namespace std; - распространённое сокращение в небольших примерах и учебных материалах.